attr_digest 1.1.0 → 1.2.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/CHANGELOG.md +4 -2
- data/README.md +4 -4
- data/lib/attr_digest/attr_digest.rb +0 -1
- data/lib/attr_digest/version.rb +1 -4
- metadata +20 -15
- data/spec/factories/models.rb +0 -46
- data/spec/lib/attr_digest_spec.rb +0 -209
- data/spec/spec_helper.rb +0 -34
- data/spec/support/models.rb +0 -47
- data/spec/support/schema.rb +0 -17
- data/spec/tmp/test.sqlite3 +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 63cdafa1a0c9fb93a2faf186e6cfc34a9cbb3a82
|
4
|
+
data.tar.gz: 92768dd263b1ef29f66b6634a79373164ed43534
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9135190b059ebddd9bae632614f5c787675d0cb627679b081e25f387d99bbed91217606e280ad1a9863898fb249ce831085dd2fcc1d03487a6a9b7d0332c7f7
|
7
|
+
data.tar.gz: ce9daa1a773fc71b8c2a9741aa91cece52490e15ee7be7bf5edc5e026c48d44e452f6a127b8007fb6acf8dc686b9a9ba21ce7abb00566d1ee39b3c4cdb9d3ee3
|
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
-
#Change Log
|
1
|
+
# Change Log
|
2
|
+
|
3
|
+
##v1.2.0
|
4
|
+
- Updated ActiveSupport and ActiveRecord between 4.2.6 and v5.0.0.
|
2
5
|
|
3
6
|
##v1.1.0
|
4
7
|
- Updated Argon2 dependency to v1.1.0.
|
5
|
-
- Updated README.md to reflect dependency changes and compatibility.
|
6
8
|
|
7
9
|
##v1.0.0
|
8
10
|
- Initial release.
|
data/README.md
CHANGED
@@ -19,7 +19,7 @@ This Gem uses the [Ruby Argon2 Gem](https://github.com/technion/ruby-argon2) whi
|
|
19
19
|
To install add the following line to your `Gemfile`:
|
20
20
|
|
21
21
|
``` ruby
|
22
|
-
gem 'attr_digest',
|
22
|
+
gem 'attr_digest',
|
23
23
|
```
|
24
24
|
|
25
25
|
And run `bundle install`.
|
@@ -27,8 +27,8 @@ And run `bundle install`.
|
|
27
27
|
## Dependencies
|
28
28
|
|
29
29
|
Runtime:
|
30
|
-
- activerecord (
|
31
|
-
- activesupport (
|
30
|
+
- activerecord (>= 4.2.6, ~> 5.0.0)
|
31
|
+
- activesupport (>= 4.2.6, ~> 5.0.0)
|
32
32
|
- argon2 (~> 1.1.0)
|
33
33
|
|
34
34
|
Development/Test:
|
@@ -40,7 +40,7 @@ Development/Test:
|
|
40
40
|
|
41
41
|
## Compatibility
|
42
42
|
|
43
|
-
Tested with Ruby 2.
|
43
|
+
Tested with Ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin15] against ActiveRecord 5.0.0 on Mac OS X El Capitan 10.11.5 (15F34).
|
44
44
|
|
45
45
|
Argon2 requires Ruby 2.2 minimum and an OS platform that supports Ruby FFI Bindings, so unfortunately Windows is out.
|
46
46
|
|
data/lib/attr_digest/version.rb
CHANGED
@@ -1,14 +1,11 @@
|
|
1
1
|
module AttrDigest
|
2
2
|
module VERSION
|
3
3
|
MAJOR = 1
|
4
|
-
MINOR =
|
4
|
+
MINOR = 2
|
5
5
|
TINY = 0
|
6
6
|
PRE = nil
|
7
|
-
|
8
7
|
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
|
9
|
-
|
10
8
|
SUMMARY = "AttrDigest v#{STRING}"
|
11
|
-
|
12
9
|
DESCRIPTION = "Provides functionality to store a hash digest of an attribute using Argon2"
|
13
10
|
end
|
14
11
|
end
|
metadata
CHANGED
@@ -1,43 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: attr_digest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jurgen Jocubeit
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-07-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.2.6
|
17
20
|
- - "~>"
|
18
21
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
22
|
+
version: 5.0.0
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 4.2.6
|
24
30
|
- - "~>"
|
25
31
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
32
|
+
version: 5.0.0
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: activerecord
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
30
36
|
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 4.2.6
|
31
40
|
- - "~>"
|
32
41
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
42
|
+
version: 5.0.0
|
34
43
|
type: :runtime
|
35
44
|
prerelease: false
|
36
45
|
version_requirements: !ruby/object:Gem::Requirement
|
37
46
|
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: 4.2.6
|
38
50
|
- - "~>"
|
39
51
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
52
|
+
version: 5.0.0
|
41
53
|
- !ruby/object:Gem::Dependency
|
42
54
|
name: argon2
|
43
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -135,12 +147,6 @@ files:
|
|
135
147
|
- lib/attr_digest.rb
|
136
148
|
- lib/attr_digest/attr_digest.rb
|
137
149
|
- lib/attr_digest/version.rb
|
138
|
-
- spec/factories/models.rb
|
139
|
-
- spec/lib/attr_digest_spec.rb
|
140
|
-
- spec/spec_helper.rb
|
141
|
-
- spec/support/models.rb
|
142
|
-
- spec/support/schema.rb
|
143
|
-
- spec/tmp/test.sqlite3
|
144
150
|
homepage: https://github.com/brightcommerce/attr_digest
|
145
151
|
licenses:
|
146
152
|
- MIT
|
@@ -162,9 +168,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
162
168
|
version: '0'
|
163
169
|
requirements: []
|
164
170
|
rubyforge_project:
|
165
|
-
rubygems_version: 2.
|
171
|
+
rubygems_version: 2.5.1
|
166
172
|
signing_key:
|
167
173
|
specification_version: 4
|
168
|
-
summary: AttrDigest v1.
|
174
|
+
summary: AttrDigest v1.2.0
|
169
175
|
test_files: []
|
170
|
-
has_rdoc:
|
data/spec/factories/models.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
FactoryGirl.define do
|
2
|
-
|
3
|
-
factory :model_with_attr_digest do
|
4
|
-
username 'username'
|
5
|
-
password 'password'
|
6
|
-
password_confirmation 'password'
|
7
|
-
security_question 'question'
|
8
|
-
security_answer 'answer'
|
9
|
-
security_answer_confirmation 'answer'
|
10
|
-
end
|
11
|
-
|
12
|
-
factory :model_with_attr_digest_and_validations_option do
|
13
|
-
username 'username_no_validation'
|
14
|
-
password 'password'
|
15
|
-
password_confirmation 'password'
|
16
|
-
security_question 'question'
|
17
|
-
security_answer 'answer'
|
18
|
-
end
|
19
|
-
|
20
|
-
factory :model_with_attr_digest_and_protected_option do
|
21
|
-
username 'username_protect'
|
22
|
-
password 'password'
|
23
|
-
password_confirmation 'password'
|
24
|
-
security_question 'question'
|
25
|
-
security_answer 'answer'
|
26
|
-
security_answer_confirmation 'answer'
|
27
|
-
end
|
28
|
-
|
29
|
-
factory :model_with_attr_digest_and_case_sensitive_option do
|
30
|
-
username 'username_protect'
|
31
|
-
password 'password'
|
32
|
-
password_confirmation 'password'
|
33
|
-
security_question 'question'
|
34
|
-
security_answer 'answer'
|
35
|
-
security_answer_confirmation 'answer'
|
36
|
-
end
|
37
|
-
|
38
|
-
factory :model_with_attr_digest_and_confirmation_option do
|
39
|
-
username 'username_protect'
|
40
|
-
password 'password'
|
41
|
-
password_confirmation 'password'
|
42
|
-
security_question 'question'
|
43
|
-
security_answer 'answer'
|
44
|
-
end
|
45
|
-
|
46
|
-
end
|
@@ -1,209 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe ModelWithAttrDigest do
|
4
|
-
it 'responds to :security_answer' do
|
5
|
-
respond_to(:security_answer)
|
6
|
-
end
|
7
|
-
|
8
|
-
it 'responds to :security_answer=' do
|
9
|
-
respond_to(:security_answer=)
|
10
|
-
end
|
11
|
-
|
12
|
-
it 'responds to :security_answer_confirmation' do
|
13
|
-
respond_to(:security_answer_confirmation)
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'responds to :security_answer_confirmation=' do
|
17
|
-
respond_to(:security_answer_confirmation=)
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'responds to :authenticate_security_answer' do
|
21
|
-
respond_to(:authenticate_security_answer)
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'confirms :security_answer' do
|
25
|
-
subject.security_answer = 'hello there'
|
26
|
-
subject.security_answer_confirmation = 'there hello'
|
27
|
-
subject.valid?
|
28
|
-
expect(subject.errors[:security_answer_confirmation]).to include("doesn't match Security answer")
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'does not confirm :security_answer if not given' do
|
32
|
-
subject.security_answer = nil
|
33
|
-
subject.security_answer_confirmation = 'there hello'
|
34
|
-
subject.valid?
|
35
|
-
expect(subject.errors[:security_answer_confirmation]).to be_blank
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'requires :security_answer on create' do
|
39
|
-
expect(subject).to be_new_record
|
40
|
-
subject.security_answer = nil
|
41
|
-
subject.valid?
|
42
|
-
expect(subject.errors[:security_answer]).to include("can't be blank")
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'requires :security_answer_confirmation if :security_answer given' do
|
46
|
-
subject.security_answer = 'hello there'
|
47
|
-
subject.valid?
|
48
|
-
expect(subject.errors[:security_answer_confirmation]).to include("can't be blank")
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'does not require :security_answer_confirmation if :security_answer is not given' do
|
52
|
-
subject.security_answer = ''
|
53
|
-
subject.valid?
|
54
|
-
expect(subject.errors[:security_answer_confirmation]).to be_blank
|
55
|
-
end
|
56
|
-
|
57
|
-
it 'requires :security_answer_digest on create' do
|
58
|
-
subject = FactoryGirl.build(:model_with_attr_digest)
|
59
|
-
expect(subject).to be_new_record
|
60
|
-
# change the security_answer_digest to verify the test
|
61
|
-
subject.security_answer_digest = ''
|
62
|
-
expect(lambda do
|
63
|
-
begin
|
64
|
-
subject.save!
|
65
|
-
rescue Exception => exception
|
66
|
-
expect(exception.message).to include("security_answer_digest missing on new record")
|
67
|
-
raise
|
68
|
-
end
|
69
|
-
end).to raise_error(RuntimeError)
|
70
|
-
end
|
71
|
-
|
72
|
-
it 'does not require :security_answer_digest on update' do
|
73
|
-
subject = FactoryGirl.build(:model_with_attr_digest)
|
74
|
-
expect(subject).to be_new_record
|
75
|
-
subject.save!
|
76
|
-
# change the security_answer_digest to verify the test
|
77
|
-
subject.security_answer_digest = ''
|
78
|
-
subject.save!
|
79
|
-
subject.reload
|
80
|
-
expect(subject.security_answer_digest).to be_blank
|
81
|
-
end
|
82
|
-
|
83
|
-
it 'allows to call :security_answer_digest directly if :protect_setter_for_digest is not given as option' do
|
84
|
-
lambda do
|
85
|
-
subject.security_answer_digest = 'hello'
|
86
|
-
expect(subject.security_answer_digest).to eq('hello')
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
describe "#security_answer=" do
|
91
|
-
it 'sets the :security_answer and saves the digest' do
|
92
|
-
model = FactoryGirl.create(:model_with_attr_digest, security_answer: 'old answer', security_answer_confirmation: 'old answer')
|
93
|
-
expect(model.security_answer_digest).to_not be_blank
|
94
|
-
old_security_answer_digest = model.security_answer_digest
|
95
|
-
model.security_answer = 'new answer'
|
96
|
-
model.security_answer_confirmation = 'new answer'
|
97
|
-
expect(model.instance_variable_get(:@security_answer)).to eq('new answer')
|
98
|
-
model.save!
|
99
|
-
expect(model.security_answer_digest).to_not be_blank
|
100
|
-
expect(model.security_answer_digest).to_not eq(old_security_answer_digest)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
describe '#authenticate_security_answer' do
|
105
|
-
it 'returns true if :security_answer given matches the one stored' do
|
106
|
-
model = FactoryGirl.create(:model_with_attr_digest, security_answer: 'some answer', security_answer_confirmation: 'some answer')
|
107
|
-
expect(model.authenticate_security_answer('some answer')).to be(true)
|
108
|
-
end
|
109
|
-
|
110
|
-
it 'returns false if :security_answer given does not match the one stored' do
|
111
|
-
model = FactoryGirl.create(:model_with_attr_digest, security_answer: 'some answer', security_answer_confirmation: 'some answer')
|
112
|
-
expect(model.authenticate_security_answer('some other answer')).to be(false)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
end
|
117
|
-
|
118
|
-
describe ModelWithAttrDigestAndValidationsOption do
|
119
|
-
it 'responds to :security_answer' do
|
120
|
-
respond_to(:security_answer)
|
121
|
-
end
|
122
|
-
|
123
|
-
it 'responds to :security_answer=' do
|
124
|
-
respond_to(:security_answer=)
|
125
|
-
end
|
126
|
-
|
127
|
-
it 'responds to :security_answer_confirmation' do
|
128
|
-
respond_to(:security_answer_confirmation)
|
129
|
-
end
|
130
|
-
|
131
|
-
it 'responds to :security_answer_confirmation=' do
|
132
|
-
respond_to(:security_answer_confirmation=)
|
133
|
-
end
|
134
|
-
|
135
|
-
it 'responds to :authenticate_security_answer' do
|
136
|
-
respond_to(:authenticate_security_answer)
|
137
|
-
end
|
138
|
-
|
139
|
-
it 'does not require :security_answer on create' do
|
140
|
-
expect(subject).to be_new_record
|
141
|
-
subject.security_answer = nil
|
142
|
-
subject.valid?
|
143
|
-
expect(subject.errors[:security_answer]).to be_blank
|
144
|
-
end
|
145
|
-
|
146
|
-
it 'does not require :security_answer_confirmation if :security_answer given' do
|
147
|
-
subject.security_answer = 'hello there'
|
148
|
-
subject.valid?
|
149
|
-
expect(subject.errors[:security_answer_confirmation]).to be_blank
|
150
|
-
end
|
151
|
-
|
152
|
-
it 'does not require :security_answer_confirmation if :security_answer is not given' do
|
153
|
-
subject.security_answer = ''
|
154
|
-
subject.valid?
|
155
|
-
expect(subject.errors[:security_answer_confirmation]).to be_blank
|
156
|
-
end
|
157
|
-
|
158
|
-
it 'does not require :security_answer_digest on create' do
|
159
|
-
subject = FactoryGirl.build(:model_with_attr_digest_and_validations_option)
|
160
|
-
expect(subject).to be_new_record
|
161
|
-
# change the security_answer_digest to verify the test
|
162
|
-
subject.security_answer_digest = ''
|
163
|
-
subject.save!
|
164
|
-
end
|
165
|
-
|
166
|
-
it 'does not require :security_answer_digest on update' do
|
167
|
-
subject = FactoryGirl.build(:model_with_attr_digest_and_validations_option)
|
168
|
-
expect(subject).to be_new_record
|
169
|
-
subject.save!
|
170
|
-
# change the :security_answer_digest to verify the test
|
171
|
-
subject.send(:security_answer_digest=, '')
|
172
|
-
subject.save!
|
173
|
-
subject.reload
|
174
|
-
expect(subject.security_answer_digest).to be_blank
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
describe ModelWithAttrDigestAndProtectedOption do
|
179
|
-
it 'does not allow to call to protected setter for :security_answer_digest' do
|
180
|
-
model = FactoryGirl.create(:model_with_attr_digest_and_protected_option, security_answer: 'Answer', security_answer_confirmation: 'Answer')
|
181
|
-
expect(lambda do
|
182
|
-
model.security_answer_digest = 'hello'
|
183
|
-
end).to raise_error(NoMethodError)
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
describe ModelWithAttrDigestAndCaseSensitiveOption do
|
188
|
-
it 'authenticates even if :security_answer is of different case' do
|
189
|
-
model = FactoryGirl.create(:model_with_attr_digest_and_case_sensitive_option, security_answer: 'Answer', security_answer_confirmation: 'Answer')
|
190
|
-
expect(model.authenticate_security_answer('answer')).to eq(true)
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
describe ModelWithAttrDigestAndConfirmationOption do
|
195
|
-
it 'does not respond to :security_answer_confirmation' do
|
196
|
-
respond_to(:security_answer_confirmation) == false
|
197
|
-
end
|
198
|
-
|
199
|
-
it 'does not respond to :security_answer_confirmation=' do
|
200
|
-
respond_to(:security_answer_confirmation=) == false
|
201
|
-
end
|
202
|
-
|
203
|
-
it 'allows to create and save without any confirmation on :security_answer' do
|
204
|
-
model = FactoryGirl.create(:model_with_attr_digest_and_confirmation_option, security_answer: 'Answer')
|
205
|
-
model.save!
|
206
|
-
expect(model.authenticate_security_answer('another answer')).to be(false)
|
207
|
-
expect(model.authenticate_security_answer('Answer')).to be(true)
|
208
|
-
end
|
209
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
begin
|
2
|
-
require 'simplecov'
|
3
|
-
SimpleCov.start
|
4
|
-
if ENV['CI']=='true'
|
5
|
-
require 'codecov'
|
6
|
-
SimpleCov.formatter = SimpleCov::Formatter::Codecov
|
7
|
-
end
|
8
|
-
rescue LoadError
|
9
|
-
end
|
10
|
-
|
11
|
-
require 'active_record'
|
12
|
-
|
13
|
-
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: File.dirname(__FILE__) + "/tmp/test.sqlite3")
|
14
|
-
|
15
|
-
puts "Using ActiveRecord #{ActiveRecord::VERSION::STRING}"
|
16
|
-
|
17
|
-
load File.dirname(__FILE__) + '/support/schema.rb'
|
18
|
-
|
19
|
-
require File.dirname(__FILE__) + '/../lib/attr_digest.rb'
|
20
|
-
|
21
|
-
require 'support/models'
|
22
|
-
|
23
|
-
require 'factory_girl'
|
24
|
-
FactoryGirl.find_definitions
|
25
|
-
|
26
|
-
require "rspec/expectations"
|
27
|
-
|
28
|
-
RSpec.configure do |config|
|
29
|
-
config.before(:each) do
|
30
|
-
ModelWithAttrDigest.delete_all
|
31
|
-
end
|
32
|
-
|
33
|
-
config.order = 'random'
|
34
|
-
end
|
data/spec/support/models.rb
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
class ModelWithAttrDigest < ActiveRecord::Base
|
2
|
-
attr_digest :password
|
3
|
-
attr_digest :security_answer
|
4
|
-
|
5
|
-
validates :username, presence: true, uniqueness: { case_sensitive: false }
|
6
|
-
validates :security_question, presence: true
|
7
|
-
end
|
8
|
-
|
9
|
-
class ModelWithAttrDigestAndCaseSensitiveOption < ActiveRecord::Base
|
10
|
-
self.table_name = "model_with_attr_digests"
|
11
|
-
|
12
|
-
attr_digest :password
|
13
|
-
attr_digest :security_answer, case_sensitive: false
|
14
|
-
|
15
|
-
validates :username, presence: true, uniqueness: { case_sensitive: false }
|
16
|
-
validates :security_question, presence: true
|
17
|
-
end
|
18
|
-
|
19
|
-
class ModelWithAttrDigestAndProtectedOption < ActiveRecord::Base
|
20
|
-
self.table_name = "model_with_attr_digests"
|
21
|
-
|
22
|
-
attr_digest :password
|
23
|
-
attr_digest :security_answer, protected: true
|
24
|
-
|
25
|
-
validates :username, presence: true, uniqueness: { case_sensitive: false }
|
26
|
-
validates :security_question, presence: true
|
27
|
-
end
|
28
|
-
|
29
|
-
class ModelWithAttrDigestAndValidationsOption < ActiveRecord::Base
|
30
|
-
self.table_name = "model_with_attr_digests"
|
31
|
-
|
32
|
-
attr_digest :password
|
33
|
-
attr_digest :security_answer, validations: false
|
34
|
-
|
35
|
-
validates :username, presence: true, uniqueness: { case_sensitive: false }
|
36
|
-
validates :security_question, presence: true
|
37
|
-
end
|
38
|
-
|
39
|
-
class ModelWithAttrDigestAndConfirmationOption < ActiveRecord::Base
|
40
|
-
self.table_name = "model_with_attr_digests"
|
41
|
-
|
42
|
-
attr_digest :password
|
43
|
-
attr_digest :security_answer, confirmation: false
|
44
|
-
|
45
|
-
validates :username, presence: true, uniqueness: { case_sensitive: false }
|
46
|
-
validates :security_question, presence: true
|
47
|
-
end
|
data/spec/support/schema.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
ActiveRecord::Schema.define do
|
2
|
-
|
3
|
-
self.verbose = false
|
4
|
-
|
5
|
-
create_table :model_with_attr_digests, force: true do |t|
|
6
|
-
t.string :username, null: false
|
7
|
-
t.string :password_digest, null: false
|
8
|
-
t.string :security_question, null: false
|
9
|
-
t.string :security_answer_digest, null: false
|
10
|
-
t.timestamps
|
11
|
-
end
|
12
|
-
|
13
|
-
change_table :model_with_attr_digests do |t|
|
14
|
-
t.index :username, unique: true
|
15
|
-
end
|
16
|
-
|
17
|
-
end
|
data/spec/tmp/test.sqlite3
DELETED
Binary file
|