Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions app/services/user_profiles_encryptor.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
class UserProfilesEncryptor
class MissingPiiError < StandardError
end

attr_reader :personal_key

def initialize(user:, user_session:, password:)
Expand All @@ -11,8 +14,13 @@ def encrypt
if user.active_profile.present?
encrypt_pii_for_profile(user.active_profile)
end

if user.pending_profile.present?
encrypt_pii_for_profile(user.pending_profile)
begin
encrypt_pii_for_profile(user.pending_profile)
rescue MissingPiiError
user.pending_profile.deactivate(:encryption_error)
end
end
end

Expand All @@ -21,7 +29,10 @@ def encrypt
attr_reader :user, :password, :user_session

def encrypt_pii_for_profile(profile)
pii = Pii::Cacher.new(user, user_session).fetch(profile.id)
pii_cache = Pii::Cacher.new(user, user_session)
pii = pii_cache.fetch(profile.id)
raise MissingPiiError unless pii

@personal_key = profile.encrypt_pii(pii, password)
profile.save!
end
Expand Down
30 changes: 20 additions & 10 deletions spec/services/user_profiles_encryptor_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,25 +36,35 @@

context 'when the user has a pending profile' do
let(:profile) { create(:profile, :verify_by_mail_pending, :verified, pii: pii.to_h) }

it 'encrypts the PII for the pending profile with the password' do
encryptor = UserProfilesEncryptor.new(
let(:encryptor) do
UserProfilesEncryptor.new(
user: user,
user_session: user_session,
password: password,
)
encryptor.encrypt
end
let(:personal_key) { PersonalKeyGenerator.new(user).normalize(encryptor.personal_key) }
let(:decrypted_profile_pii) { profile.decrypt_pii(password) }
let(:decrypted_profile_recovery_pii) { profile.recover_pii(personal_key) }

it 'encrypts the PII for the pending profile with the password' do
encryptor.encrypt
profile.reload

personal_key = PersonalKeyGenerator.new(user).normalize(encryptor.personal_key)
expect(decrypted_profile_pii).to eq(pii)
expect(decrypted_profile_recovery_pii).to eq(pii)
expect(user.valid_personal_key?(personal_key)).to eq(true)
end

decrypted_profile_pii = profile.decrypt_pii(password)
decrypted_profile_recovery_pii = profile.recover_pii(personal_key)
context 'but the pending profile has no PII associated with it' do
before { user_session.delete(:encrypted_profiles) }

expect(pii).to eq(decrypted_profile_pii)
expect(pii).to eq(decrypted_profile_recovery_pii)
expect(user.valid_personal_key?(personal_key)).to eq(true)
it 'deactivates the profile with an encryption error' do
encryptor.encrypt
profile.reload

expect(profile.deactivation_reason).to eq('encryption_error')
end
end
end

Expand Down