has_editable_password 0.0.3 → 0.1.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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YTZhOWU5OTA1YzJkYTU5MmFiYWQyMWYxMWYyMjQyZjczZDA0Y2RhNg==
4
+ YjE0YjFiMmY0YzBhMTk5YWUwMDAxNGJiMGEyZmY5OWJiYzY1NWE5OQ==
5
5
  data.tar.gz: !binary |-
6
- MTc5ZjRjNDMzOTE0OWQ1OTU3NmVlYWRlNGZlY2EyYTU1NjZjM2QxZA==
6
+ MjE2MjYyZjA1NTRlYmUxZjE5MmQ2YTI2ZDUyOWNlZmFiYjUxOTc2Mw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- YTc1NTFiODYxZmUwZmUxYTM3MDMwZWZmNTE2NTJlMDE4MmEzMzk1ZmM0OTg3
10
- MmZlYmRhNzdiNjMyNmUyNmJlMjkwMGUzZTk4YTE1NzZjNGZmNmJmYzQ2MTE5
11
- Y2UyMWQzOTAyZmE5MzBlZGI0ZjMyZDMwZTU5OGVhMWYzZmU1ZTg=
9
+ M2U1MGQ0NDUxMzdjYmRlMWQzNGU4MGRmYmEwZTYzYWQ0NzhhYjdiMzRmMTNl
10
+ OWRlZDZlYWRiY2VjOTRiNDYzYjBmMjZhZTZkZTMxMWQ1NDliMTNkZWUxNWVl
11
+ YmU2NzI2ZWEzOGQ4OThkNmE2OTY0MmJmZjJlMjM4ZTljZmEwYjI=
12
12
  data.tar.gz: !binary |-
13
- MjIxZTNmMjMwNTI2ZTcxMWEyNTFjMGNkM2EyMTgyOWJjNDdmMzA3MmRlY2Zm
14
- NzMwMzk0N2VjNjRkOWJhMjRhOTI1MzllZGU4MGYzNjk2YzI0N2E0ZjEwMjM0
15
- MjY3YTEzMDEyMDVmZjQ4ZTc0MjM1OWUxODNiMTg3ZWQyNWM4ZDc=
13
+ ZDMyZTJhNmQ4YmFkZjY3NWZjMTdmYTFjZjIxMTU2MGY3ZDg3NWU3OGY3NDdl
14
+ MWY5ZDc5MWJiYjYzMTBlMjMxOWE2MTVmMjljODMwZDgzNmY4YmY5YTAyYWJk
15
+ ZjMzNTMxOWI4ZWNkN2ZiYjE1MGZlNTFmZDE3OTM0YmM5NTZkYmY=
@@ -15,11 +15,30 @@ module HasEditablePassword
15
15
  validate :password_change, on: :update, if: :password_digest_changed?
16
16
 
17
17
  def password=(value)
18
- @old_password_digest = self.password_digest unless @old_password_digest or self.password_digest.blank?
18
+ @old_password_digest = password_digest unless @old_password_digest or password_digest.blank?
19
+
20
+ unless password_digest.blank? or password_digest_changed?
21
+ self.previous_password_digest = password_digest if respond_to? :previous_password_digest=
22
+ self.password_digest_updated = Time.now if respond_to? :password_digest_updated=
23
+ end
24
+
19
25
  super(value)
20
26
  end
21
27
  end
22
28
 
29
+ ##
30
+ # Creates a new +password_recovery_token+
31
+ #
32
+ # If a token was already there it is discarded. Also sets
33
+ # +password_recovery_token_creation+ to the current time.
34
+ # Unless specified it calls +save+ to store the token in the database.
35
+ #
36
+ # options[:length] - this is the length of the SecureRandom string generated
37
+ # as the token. Since the token is base64_encoded it will be longer than
38
+ # that. Default is 32.
39
+ # options[:save] - you can use this if you don't want save to be called.
40
+ # generate_recovery_token(save: false)
41
+ #
23
42
  def generate_recovery_token(options = {})
24
43
  token = SecureRandom.urlsafe_base64(options.delete(:length) || 32)
25
44
  self.password_recovery_token = BCrypt::Password.create(token)
@@ -28,10 +47,17 @@ module HasEditablePassword
28
47
  token
29
48
  end
30
49
 
50
+ ##
51
+ # Returns true if the +recovery_token+ matches with the stored one and the
52
+ # token creation time is less than 24 hours ago
53
+ #
31
54
  def valid_recovery_token?
32
55
  recovery_token_match? and !recovery_token_expired?
33
56
  end
34
57
 
58
+ ##
59
+ # Returns true if +current_password+ matches the stored +password_digest+.
60
+ #
35
61
  def current_password_match?
36
62
  if @current_password
37
63
  if @old_password_digest
data/lib/version.rb CHANGED
@@ -1 +1 @@
1
- VERSION = '0.0.3'
1
+ VERSION = '0.1.0'
@@ -33,6 +33,48 @@ describe HasEditablePassword do
33
33
  user.password = 'secret'
34
34
  expect(BCrypt::Password.new(user.password_digest)).to eq 'secret'
35
35
  end
36
+
37
+ context 'previous_password_digest= exists' do
38
+ it 'sets the previous_password_digest field' do
39
+ expect(user).to receive :previous_password_digest=
40
+ user.password = 'new_secret'
41
+ end
42
+ end
43
+
44
+ context 'previous_password_digest= does not exist' do
45
+ before { user.stub(:respond_to?).and_return false }
46
+
47
+ it 'does not set the previous_password_digest field' do
48
+ expect(user).to_not receive :previous_password_digest=
49
+ user.password = 'new_secret'
50
+ end
51
+ end
52
+
53
+ context 'password_digest_updated= exists' do
54
+ it 'sets the password_digest_updated field' do
55
+ expect(user).to receive(:password_digest_updated=)
56
+ user.password = 'new_secret'
57
+ end
58
+ end
59
+
60
+ context 'password_digest_updated= does not exist' do
61
+ before { user.stub(:respond_to?).and_return false }
62
+
63
+ it 'does not set the password_digest_updated field' do
64
+ expect(user).to_not receive(:password_digest_updated=)
65
+ user.password = 'new_secret'
66
+ end
67
+ end
68
+
69
+ it 'only updates the previous_password and password_updated fields once' do
70
+ user.password = 'new_secret'
71
+ user.stub(:password_digest_changed?).and_return true
72
+ user.password = 'banana'
73
+
74
+ # Twice just to improve comprension
75
+ expect(BCrypt::Password.new(user.previous_password_digest)).to_not eq 'new_secret'
76
+ expect(BCrypt::Password.new(user.previous_password_digest)).to eq 'secret'
77
+ end
36
78
  end
37
79
 
38
80
  describe '#generate_recovery_token' do
data/spec/spec_helper.rb CHANGED
@@ -19,6 +19,8 @@ class User
19
19
  attr_accessor :password_digest
20
20
  attr_accessor :password_recovery_token
21
21
  attr_accessor :password_recovery_token_creation
22
+ attr_accessor :previous_password_digest
23
+ attr_accessor :password_digest_updated
22
24
 
23
25
  def initialize(hash = {})
24
26
  hash.each do |k, v|
@@ -26,13 +28,8 @@ class User
26
28
  end
27
29
  end
28
30
 
29
- def attributes
30
- keys = [ 'password', 'password_confirmation' ]
31
- values = keys.map do |k|
32
- send(k)
33
- end
34
-
35
- Hash[keys.zip(values)]
31
+ def password_digest_changed?
32
+ false
36
33
  end
37
34
 
38
35
  def save
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: has_editable_password
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Francesco Boffa