has_secure_attribute 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +3 -2
- data/lib/active_model/secure_attribute/has_secure_attribute.rb +9 -4
- data/lib/has_secure_attribute/version.rb +1 -1
- data/spec/factories/test_model_with_attributes.rb +8 -0
- data/spec/models/has_secure_attribute_spec.rb +11 -0
- data/spec/models/test_model_with_attribute_disable_confirmation.rb +8 -0
- data/spec/spec_helper.rb +1 -0
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9365979f3bd3c6800d9815e398ac86e02f7f4b41
|
4
|
+
data.tar.gz: 4ccae4ca00ef2afbc27e76b1a972c6018424a1c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7554a58cdbf1569be7aba7b2a0a58304764f153807aa4e561f88245c6bfbd394548dfedee91c0188b2b0f6be3dfaa98a87e7a4cffbdd47cff882394a96b0d6eb
|
7
|
+
data.tar.gz: 9baf44120d62ebc15e3d1b1f30d5fadabcfcfa4e3b285f67b7afe989169ebe649d4abccd7294c176b29cca4177b2146baf17fd6ecdda6451b70c5273c50ec73e
|
data/README.md
CHANGED
@@ -29,14 +29,15 @@ In the above example:
|
|
29
29
|
* Your should have a `users` table that has one column: `security_answer_digest`.
|
30
30
|
* It creates a reader: `security_answer`.
|
31
31
|
* It creates a writer: `security_answer=(value)` which basically saves the security answer given into the database on column `security_answer_digest` but is saves it encrypted.
|
32
|
-
* It adds some validations (if you want to avoid having these validations: `has_secure_security_answer :
|
32
|
+
* It adds some validations (if you want to avoid having these validations: `has_secure_security_answer validations: false`).
|
33
33
|
* It creates a confirmation validation on `security_answer` but only if `security_answer` is given (for confirmation validations see [this](http://http://guides.rubyonrails.org/active_record_validations.html#confirmation)).
|
34
34
|
* It creates a presence validation on `security_answer` but only on create.
|
35
35
|
* It creates a presence validation on `security_answer_confirmation` but only if `security_answer` has been given.
|
36
36
|
* It raises an exception if `security_answer_digest` is empty on create.
|
37
37
|
* It defines the method `authenticate_security_answer(answer_to_authenticate)` which returns `false` if the answer given does not correspond to the saved digest, or returns the object instance itself if it does.
|
38
38
|
|
39
|
-
__Case Insensitive Values__: you can
|
39
|
+
__Case Insensitive Values__: you can do `has_secure_security_answer case_insensitive: false` if you want to handle values that match even if they differ on case. Then, `answer` will match `Answer`, for example.
|
40
|
+
__Do not use confirmation__: you can do `has_secure_security_answer confirm: false` if you do not want to have confirmation attribute for the attribute you are securing.
|
40
41
|
|
41
42
|
Do you want to test it?
|
42
43
|
------------------------
|
@@ -21,12 +21,11 @@ module ActiveModel
|
|
21
21
|
def has_secure_attribute(meth, *args, &block)
|
22
22
|
attribute_sym = meth.to_sym
|
23
23
|
attr_reader attribute_sym # setter is defined later on
|
24
|
-
options = {validations: true, protect_setter_for_digest: false, case_sensitive: true}
|
24
|
+
options = {validations: true, protect_setter_for_digest: false, case_sensitive: true, confirmation: true}
|
25
25
|
options.merge! args[0] unless args.blank?
|
26
26
|
if options[:validations]
|
27
|
-
|
28
|
-
validates attribute_sym,
|
29
|
-
validates "#{attribute_sym}_confirmation".to_sym, presence: true, if: lambda { |m| m.send(attribute_sym).present? }
|
27
|
+
confirm attribute_sym if options[:confirmation]
|
28
|
+
validates attribute_sym, presence: true, on: :create
|
30
29
|
before_create { raise "#{attribute_sym}_digest missing on new record" if send("#{attribute_sym}_digest").blank? }
|
31
30
|
end
|
32
31
|
|
@@ -36,6 +35,11 @@ module ActiveModel
|
|
36
35
|
define_authenticate_method(attribute_sym, options)
|
37
36
|
end
|
38
37
|
|
38
|
+
def confirm(attribute_sym)
|
39
|
+
validates attribute_sym, confirmation: true, if: lambda { |m| m.send(attribute_sym).present? }
|
40
|
+
validates "#{attribute_sym}_confirmation".to_sym, presence: true, if: lambda { |m| m.send(attribute_sym).present? }
|
41
|
+
end
|
42
|
+
|
39
43
|
def define_setter(attribute_sym, options)
|
40
44
|
define_method "#{attribute_sym.to_s}=" do |unencrypted_value|
|
41
45
|
unless unencrypted_value.blank?
|
@@ -60,6 +64,7 @@ module ActiveModel
|
|
60
64
|
end
|
61
65
|
|
62
66
|
protected :has_secure_attribute
|
67
|
+
protected :confirm
|
63
68
|
protected :define_setter
|
64
69
|
protected :protect_setter_for_digest
|
65
70
|
protected :define_authenticate_method
|
@@ -33,4 +33,12 @@ FactoryGirl.define do
|
|
33
33
|
security_answer 'answer'
|
34
34
|
security_answer_confirmation 'answer'
|
35
35
|
end
|
36
|
+
|
37
|
+
factory :test_model_with_attribute_disable_confirmation do
|
38
|
+
username 'username_protect'
|
39
|
+
password 'password'
|
40
|
+
password_confirmation 'password'
|
41
|
+
security_question 'question'
|
42
|
+
security_answer 'answer'
|
43
|
+
end
|
36
44
|
end
|
@@ -171,3 +171,14 @@ describe TestModelWithAttributeWithCaseSensitive do
|
|
171
171
|
t.authenticate_security_answer('answer').should eq t
|
172
172
|
end
|
173
173
|
end
|
174
|
+
|
175
|
+
describe TestModelWithAttributeDisableConfirmation do
|
176
|
+
it { should_not respond_to(:security_answer_confirmation) }
|
177
|
+
it { should_not respond_to(:security_answer_confirmation=) }
|
178
|
+
it 'should allow to create and save without any confirmation on security answer' do
|
179
|
+
t = FactoryGirl.create :test_model_with_attribute_disable_confirmation, security_answer: 'Answer'
|
180
|
+
t.save!
|
181
|
+
t.authenticate_security_answer('another answer').should be_false
|
182
|
+
t.authenticate_security_answer('Answer').should eq t
|
183
|
+
end
|
184
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
class TestModelWithAttributeDisableConfirmation < ActiveRecord::Base
|
2
|
+
self.table_name = "test_model_with_attributes"
|
3
|
+
has_secure_password
|
4
|
+
has_secure_security_answer confirmation: false
|
5
|
+
|
6
|
+
validates :username, presence: true, uniqueness: {case_sensitive: false}
|
7
|
+
validates :security_question, presence: true
|
8
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -8,6 +8,7 @@ require File.expand_path("../models/test_model_with_attribute", __FILE__)
|
|
8
8
|
require File.expand_path("../models/test_model_with_attribute_no_validation", __FILE__)
|
9
9
|
require File.expand_path("../models/test_model_with_attribute_protect_setter_for_digest", __FILE__)
|
10
10
|
require File.expand_path("../models/test_model_with_attribute_with_case_sensitive", __FILE__)
|
11
|
+
require File.expand_path("../models/test_model_with_attribute_disable_confirmation", __FILE__)
|
11
12
|
|
12
13
|
require 'factory_girl'
|
13
14
|
FactoryGirl.find_definitions
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: has_secure_attribute
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Panayotis Matsinopoulos
|
@@ -125,6 +125,7 @@ files:
|
|
125
125
|
- spec/models/has_secure_attribute_spec.rb
|
126
126
|
- spec/models/test_model_with_attribute_no_validation.rb
|
127
127
|
- spec/models/test_model_with_attribute_protect_setter_for_digest.rb
|
128
|
+
- spec/models/test_model_with_attribute_disable_confirmation.rb
|
128
129
|
- spec/models/test_model_with_attribute.rb
|
129
130
|
- spec/models/test_model_with_attribute_with_case_sensitive.rb
|
130
131
|
- spec/db/migrate/db_helper.rb
|