Skip to content
This repository has been archived by the owner on Jan 27, 2023. It is now read-only.

Uniqueness validations #46

Merged
merged 9 commits into from
Aug 15, 2022
Merged

Uniqueness validations #46

merged 9 commits into from
Aug 15, 2022

Conversation

coderdan
Copy link
Contributor

No description provided.

@coderdan coderdan requested a review from a team as a code owner July 12, 2022 08:18
mpalmer
mpalmer previously approved these changes Jul 13, 2022
Copy link
Contributor

@mpalmer mpalmer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing terribad in here that I noticed, so approving, but it won't be sufficient to support the devise-instantiated uniqueness validations I'm wrestling with at the moment.

README.md Outdated
Comment on lines 287 to 288
Also, note that as of now the `ActiveStash::Validations` module only supports a very simple uniqueness validation
and doesn't yet support conditions or any option other than `:message`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, that's going to be insufficient for the initial use-case I'm after this feature for.

lib/active_stash/validations.rb Outdated Show resolved Hide resolved
Copy link
Contributor

@mpalmer mpalmer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your code looks OK, but when I try to use it with a Devise-using model it isn't being picked up, and the SQL-based validation still runs (and explodes, ofc). I'll have to spend some time figuring out what strange magicks Devise is up to, and get back to you.


Instead, you can include `ActiveStash::Validations` and your uniqueness validation will now work via a query
to the CipherStash index on the validated field.
If there is no index on the field then validations will fail.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean that including ActiveStash::Validations overrides all ActiveRecord uniqueness validations? Say, if I have two fields, one encrypted and the other one unencrypted, with (separate) uniqueness validations on each, will that still work?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure. Will look into that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add a test and check this out.

Copy link
Contributor

@fimac fimac Aug 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mpalmer @coderdan I tested this out, and ActiveStash::Validations overrides all ActiveRecord uniqueness validations.

In this example, first_name doesn't have a stash_index applied, and has a uniqueness validation.

https://github.com/cipherstash/activestash/compare/uniqueness-validations...test-overrides-on-non-encrypted-indexes?expand=1

The error returned is expected no Exception, got #<RuntimeError: No indexes available for 'first_name'> with backtrace:

Screen Shot 2022-08-12 at 11 52 56 am

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll try something like the below pseudo code and see if I can get it working.

module ClassMethods
      def validates_uniqueness_of(*attr_names)
        # if stash index available for attr_name
        validates_with ActiveStash::Validations::UniquenessValidator, _merge_attributes(attr_names)
        # else
        validates_with UniquenessValidator, _merge_attributes(attr_names)
        # end
      end
    end

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This issue has been fixed with this change
edbcba8

@@ -50,6 +50,11 @@ def order(*args)
self
end

def exists?
self.load
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this redundant? I was under the impression that #first called #load itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Supposedly, yes but it wasn't working without this line. I'll double check but something weird with lazy loading.

@mpalmer mpalmer dismissed their stale review July 31, 2022 23:21

So that this PR drops back to "Review Required"

# Used for testing
attr_accessor :skip_validations

validates :email, uniqueness: true, if: Proc.new { |user| user.perform_validations? }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
validates :email, uniqueness: true, if: Proc.new { |user| user.perform_validations? }
validates_uniqueness_of :email, if: Proc.new { |user| user.perform_validations? }

Finally figured out WTF is going on in Devise. Turns out that validates_uniqueness_of is what Devise is calling, and that doesn't end up getting turned into a validates uniqueness: true call, but instead does something totally different. NFI what, yet, but this at least gives us a failing test case to work from.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mpalmer Dan and I paired on this.

We fixed this by adding in this code to override the validates_uniqueness_of method to point to ActiveStash validations.

https://github.com/cipherstash/activestash/pull/46/files#diff-cad201e14383cf85c4b3f8ba1e716e599c5204d388ebf482d2b8926f3ab4fa6dR3-R11

I've pushed this change up, and the existing test is passing, as the ActiveStash validation return string of failed: Email already exists" is being returned now.

@fimac fimac force-pushed the uniqueness-validations branch 5 times, most recently from a8a7d09 to 2dd1c74 Compare August 15, 2022 02:10
@fimac fimac merged commit 757ea57 into main Aug 15, 2022
@fimac fimac deleted the uniqueness-validations branch August 15, 2022 03:44
freshtonic pushed a commit that referenced this pull request Dec 21, 2022
This pull request was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants