-
Notifications
You must be signed in to change notification settings - Fork 115
/
user_access_key_overrides.rb
88 lines (77 loc) · 2.73 KB
/
user_access_key_overrides.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# frozen_string_literal: true
# In order to perform scrypt calculation of password in a single
# place for both password and PII encryption, we override
# a few methods to build the encrypted_password via UserAccessKey
#
module UserAccessKeyOverrides
extend ActiveSupport::Concern
attr_reader :personal_key
def valid_password?(password)
result = Encryption::PasswordVerifier.new.verify(
password: password,
digest_pair: password_regional_digest_pair,
user_uuid: uuid,
log_context: 'password-digest',
)
@password = password if result
result
end
def password=(new_password)
@password = new_password
return if @password.blank?
self.encrypted_password_digest, self.encrypted_password_digest_multi_region =
Encryption::PasswordVerifier.new.create_digest_pair(
password: @password,
user_uuid: uuid || generate_uuid,
)
end
def password_regional_digest_pair
Encryption::RegionalCiphertextPair.new(
single_region_ciphertext: encrypted_password_digest,
multi_region_ciphertext: encrypted_password_digest_multi_region,
)
end
def valid_personal_key?(normalized_personal_key)
Encryption::PasswordVerifier.new.verify(
password: normalized_personal_key,
digest_pair: recovery_code_regional_digest_pair,
user_uuid: uuid,
log_context: 'personal-key',
)
end
def personal_key=(new_personal_key)
@personal_key = new_personal_key
return if new_personal_key.blank?
self.encrypted_recovery_code_digest, self.encrypted_recovery_code_digest_multi_region =
Encryption::PasswordVerifier.new.create_digest_pair(
password: new_personal_key,
user_uuid: uuid || generate_uuid,
)
self.encrypted_recovery_code_digest_generated_at = Time.zone.now
end
def recovery_code_regional_digest_pair
Encryption::RegionalCiphertextPair.new(
single_region_ciphertext: encrypted_recovery_code_digest,
multi_region_ciphertext: encrypted_recovery_code_digest_multi_region,
)
end
# This is a callback initiated by Devise after successfully authenticating.
def after_database_authentication
rotate_stale_password_digest
end
def rotate_stale_password_digest
return unless Encryption::PasswordVerifier.new.stale_digest?(
encrypted_password_digest,
)
update!(password: password)
end
# This is a devise method, which we are overriding. This should not be removed
# as Devise depends on this for things like building the key to use when
# storing the user in the session.
def authenticatable_salt
return if encrypted_password_digest.blank?
Encryption::PasswordVerifier::PasswordDigest.parse_from_string(
encrypted_password_digest,
).password_salt
end
end