mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Allow passing hash on secure password validations
I was running into a case where I didn't want to just disabled the validations and add my own. In fact, I would very much like to keep the default validation but just de-activate it on some scenario: e.g. Inviting a user without having to set a password for them yet so they can add it themselves later when they receive an email invitation to finish setting up their account. My understanding of the validations flag originally intended was to just disabled them and if you needed something more custom, you could run your own validations instead. This would be an acceptable solution, but it would add more code to my controller. Instead validations can receive a `Hash` wich is then use to apply validations rules to `validate`. This is just a suggestion, I am not sure if there is a need, and I am aware this PR is probably far from perfect. Any feedback welcome. EDIT: implemented changes as per feedback.
This commit is contained in:
parent
894686b8ef
commit
8804128ad4
3 changed files with 28 additions and 3 deletions
|
@ -1,3 +1,13 @@
|
||||||
|
* Support passing `Hash` with keys `:if / :unless / :on` to SecurePassword.
|
||||||
|
This provides more flexibility when you want to trigger or skip validations on
|
||||||
|
specific conditions
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
secure_password validations: {if: :requires_password?}`
|
||||||
|
```
|
||||||
|
|
||||||
|
*Kevin Jacoby*
|
||||||
|
|
||||||
* `has_secure_password` now supports password challenges via a
|
* `has_secure_password` now supports password challenges via a
|
||||||
`password_challenge` accessor and validation.
|
`password_challenge` accessor and validation.
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,11 @@ module ActiveModel
|
||||||
# ActiveModel::Dirty; if dirty tracking methods are not defined, this
|
# ActiveModel::Dirty; if dirty tracking methods are not defined, this
|
||||||
# validation will fail.
|
# validation will fail.
|
||||||
#
|
#
|
||||||
# All of the above validations can be omitted by passing
|
# The password presence validation can be conditionally enforced by
|
||||||
# <tt>validations: false</tt> as an argument. This allows complete
|
# passing an options hash to +:validations+ with the standard +:if+ /
|
||||||
|
# +:unless+ / +:on+ keys. (See ActiveModel::Validations::ClassMethods#validates
|
||||||
|
# for more information.) Alternatively, all of the above validations can
|
||||||
|
# be omitted by passing <tt>validations: false</tt>. This allows complete
|
||||||
# customizability of validation behavior.
|
# customizability of validation behavior.
|
||||||
#
|
#
|
||||||
# To use +has_secure_password+, add bcrypt (~> 3.1.7) to your Gemfile:
|
# To use +has_secure_password+, add bcrypt (~> 3.1.7) to your Gemfile:
|
||||||
|
@ -93,11 +96,13 @@ module ActiveModel
|
||||||
if validations
|
if validations
|
||||||
include ActiveModel::Validations
|
include ActiveModel::Validations
|
||||||
|
|
||||||
|
validation_options = validations.is_a?(Hash) ? validations : {}
|
||||||
|
|
||||||
# This ensures the model has a password by checking whether the password_digest
|
# This ensures the model has a password by checking whether the password_digest
|
||||||
# is present, so that this works with both new and existing records. However,
|
# is present, so that this works with both new and existing records. However,
|
||||||
# when there is an error, the message is added to the password attribute instead
|
# when there is an error, the message is added to the password attribute instead
|
||||||
# so that the error message will make sense to the end-user.
|
# so that the error message will make sense to the end-user.
|
||||||
validate do |record|
|
validate(validation_options) do |record|
|
||||||
record.errors.add(attribute, :blank) unless record.public_send("#{attribute}_digest").present?
|
record.errors.add(attribute, :blank) unless record.public_send("#{attribute}_digest").present?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,16 @@ class SecurePasswordTest < ActiveModel::TestCase
|
||||||
assert_not_respond_to @visitor, :valid?
|
assert_not_respond_to @visitor, :valid?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "support conditional validation" do
|
||||||
|
user = Struct.new(:requires_password, :password_digest) do
|
||||||
|
include ActiveModel::SecurePassword
|
||||||
|
has_secure_password validations: { if: :requires_password }
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_predicate user.new(false), :valid?
|
||||||
|
assert_predicate user.new(true), :invalid?
|
||||||
|
end
|
||||||
|
|
||||||
test "create a new user with validations and valid password/confirmation" do
|
test "create a new user with validations and valid password/confirmation" do
|
||||||
@user.password = "password"
|
@user.password = "password"
|
||||||
@user.password_confirmation = "password"
|
@user.password_confirmation = "password"
|
||||||
|
|
Loading…
Reference in a new issue