diff --git a/app/mailers/emails/profile.rb b/app/mailers/emails/profile.rb index 256cbcd73a1e99eac4317f70047ec4c2f3215851..4580e1c83bd3b07d1099d0596410d0fa2545bd86 100644 --- a/app/mailers/emails/profile.rb +++ b/app/mailers/emails/profile.rb @@ -22,5 +22,15 @@ module Emails @target_url = user_url(@user) mail(to: @user.notification_email, subject: subject("SSH key was added to your account")) end + + def new_gpg_key_email(gpg_key_id) + @gpg_key = GpgKey.find_by_id(gpg_key_id) + + return unless @gpg_key + + @current_user = @user = @gpg_key.user + @target_url = user_url(@user) + mail(to: @user.notification_email, subject: subject("GPG key was added to your account")) + end end end diff --git a/app/models/gpg_key.rb b/app/models/gpg_key.rb index 04c7ce2e79f50abc5a57bd8cf8246bfb8f861b04..83a303ae9539904ca9d3b041594c9d9d92c47f45 100644 --- a/app/models/gpg_key.rb +++ b/app/models/gpg_key.rb @@ -1,4 +1,6 @@ class GpgKey < ActiveRecord::Base + include AfterCommitQueue + KEY_PREFIX = '-----BEGIN PGP PUBLIC KEY BLOCK-----'.freeze belongs_to :user @@ -20,6 +22,7 @@ class GpgKey < ActiveRecord::Base before_validation :extract_fingerprint after_create :add_to_keychain + after_create :notify_user after_destroy :remove_from_keychain def key=(value) @@ -62,4 +65,8 @@ class GpgKey < ActiveRecord::Base def remove_from_keychain Gitlab::Gpg::CurrentKeyChain.remove(fingerprint) end + + def notify_user + run_after_commit { NotificationService.new.new_gpg_key(self) } + end end diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 3a98a5f6b64273a01a2cdb1f47243f4a4337071a..b94921d2a08b84542429ebae40160f29e7504d83 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -17,6 +17,16 @@ class NotificationService end end + # Always notify the user about gpg key added + # + # This is a security email so it will be sent even if the user user disabled + # notifications + def new_gpg_key(gpg_key) + if gpg_key.user + mailer.new_gpg_key_email(gpg_key.id).deliver_later + end + end + # Always notify user about email added to profile def new_email(email) if email.user diff --git a/app/views/notify/new_gpg_key_email.html.haml b/app/views/notify/new_gpg_key_email.html.haml new file mode 100644 index 0000000000000000000000000000000000000000..4b9350c4e8820707901c95da3586568215f25fdb --- /dev/null +++ b/app/views/notify/new_gpg_key_email.html.haml @@ -0,0 +1,10 @@ +%p + Hi #{@user.name}! +%p + A new GPG key was added to your account: +%p + Fingerprint: + %code= @gpg_key.fingerprint +%p + If this key was added in error, you can remove it under + = link_to "GPG Keys", profile_gpg_keys_url diff --git a/app/views/notify/new_gpg_key_email.text.erb b/app/views/notify/new_gpg_key_email.text.erb new file mode 100644 index 0000000000000000000000000000000000000000..80b5a1fd7ff8f58bcd774ed65fcbc232ce57fb3f --- /dev/null +++ b/app/views/notify/new_gpg_key_email.text.erb @@ -0,0 +1,7 @@ +Hi <%= @user.name %>! + +A new GPG key was added to your account: + +Fingerprint: <%= @gpg_key.fingerprint %> + +If this key was added in error, you can remove it at <%= profile_gpg_keys_url %> diff --git a/spec/factories/gpg_keys.rb b/spec/factories/gpg_keys.rb index 70c2875b985d9f051e704c09aafe6d14b58354df..1258dce89404d2d9dc62e06e44321373e9d3456a 100644 --- a/spec/factories/gpg_keys.rb +++ b/spec/factories/gpg_keys.rb @@ -3,5 +3,6 @@ require_relative '../support/gpg_helpers' FactoryGirl.define do factory :gpg_key do key GpgHelpers::User1.public_key + user end end diff --git a/spec/mailers/emails/profile_spec.rb b/spec/mailers/emails/profile_spec.rb index 8c1c9bf135fa58412c0dd4c9b816fbc0ba2ecb55..09e5094cf84220081edca6dd7008377ad4ee4a60 100644 --- a/spec/mailers/emails/profile_spec.rb +++ b/spec/mailers/emails/profile_spec.rb @@ -91,6 +91,36 @@ describe Emails::Profile do end end + describe 'user added gpg key' do + let(:gpg_key) { create(:gpg_key) } + + subject { Notify.new_gpg_key_email(gpg_key.id) } + + it_behaves_like 'an email sent from GitLab' + it_behaves_like 'it should not have Gmail Actions links' + it_behaves_like 'a user cannot unsubscribe through footer link' + + it 'is sent to the new user' do + is_expected.to deliver_to gpg_key.user.email + end + + it 'has the correct subject' do + is_expected.to have_subject /^GPG key was added to your account$/i + end + + it 'contains the new gpg key title' do + is_expected.to have_body_text /#{gpg_key.fingerprint}/ + end + + it 'includes a link to gpg keys page' do + is_expected.to have_body_text /#{profile_gpg_keys_path}/ + end + + context 'with GPG key that does not exist' do + it { expect { Notify.new_gpg_key_email('foo') }.not_to raise_error } + end + end + describe 'user added email' do let(:email) { create(:email) } diff --git a/spec/models/gpg_key_spec.rb b/spec/models/gpg_key_spec.rb index 695a2f65c097b71eeac3304406a1580ba7f6da93..4292892da4f144d64ab7b1b4d94639911a947c3d 100644 --- a/spec/models/gpg_key_spec.rb +++ b/spec/models/gpg_key_spec.rb @@ -103,4 +103,18 @@ describe GpgKey do end end end + + describe 'notification' do + include EmailHelpers + + let(:user) { create(:user) } + + it 'sends a notification' do + perform_enqueued_jobs do + create(:gpg_key, user: user) + end + + should_email(user) + end + end end diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb index 4fc5eb0a527ef3e91b74eee0cf0b42ec107ae6c6..0f07a89aad9f0e90de592125be6ced180d9a2306 100644 --- a/spec/services/notification_service_spec.rb +++ b/spec/services/notification_service_spec.rb @@ -93,6 +93,18 @@ describe NotificationService, services: true do end end + describe 'GpgKeys' do + describe '#new_gpg_key' do + let!(:key) { create(:gpg_key) } + + it { expect(notification.new_gpg_key(key)).to be_truthy } + + it 'sends email to key owner' do + expect{ notification.new_gpg_key(key) }.to change{ ActionMailer::Base.deliveries.size }.by(1) + end + end + end + describe 'Email' do describe '#new_email' do let!(:email) { create(:email) }