From 225fd87d0e00f2549a5e100cc0e9be4624c32965 Mon Sep 17 00:00:00 2001 From: Emma Park Date: Thu, 24 Apr 2025 00:36:03 +1000 Subject: [PATCH 1/4] Use author_email to verify UI-signed commits instead of user_id For UI-signed commits, GitLab signs on behalf of a user but is not an actual user entity. Previously, we used `user_id` to verify these commits, which led to incorrect verification results. This commit changes the logic to rely on the newly added `author_email` column for verifying UI-signed commits. It avoids incorrect assumptions based on `user_id`, ensuring more accurate and reliable commit signature validation. Changelog: changed --- app/models/concerns/commit_signature.rb | 11 +++++---- lib/gitlab/signed_commit.rb | 9 +++++++- lib/gitlab/ssh/commit.rb | 4 +++- lib/gitlab/ssh/signature.rb | 5 ---- spec/lib/gitlab/ssh/commit_spec.rb | 23 ++++++++++++------- spec/lib/gitlab/ssh/signature_spec.rb | 14 ----------- .../commit_signatures/gpg_signature_spec.rb | 4 ++-- .../commit_signatures/ssh_signature_spec.rb | 19 ++++++++++----- 8 files changed, 47 insertions(+), 42 deletions(-) diff --git a/app/models/concerns/commit_signature.rb b/app/models/concerns/commit_signature.rb index d65edfedbfc71c..5264e244cbf5f5 100644 --- a/app/models/concerns/commit_signature.rb +++ b/app/models/concerns/commit_signature.rb @@ -57,10 +57,11 @@ def verification_status private def emails_for_verification - if x509? - x509_certificate.all_emails - else - signed_by_user&.verified_emails - end + return x509_certificate.all_emails if x509? + + return author_email if Feature.enabled?( + :check_for_mailmapped_commit_emails, project) && verified_system? + + signed_by_user&.verified_emails end end diff --git a/lib/gitlab/signed_commit.rb b/lib/gitlab/signed_commit.rb index 0d443c1750c1bf..35da86fb079f6a 100644 --- a/lib/gitlab/signed_commit.rb +++ b/lib/gitlab/signed_commit.rb @@ -26,7 +26,7 @@ def signature # This is because of the introduction of mailmap. See https://gitlab.com/gitlab-org/gitlab/-/issues/425042#note_1997022896. if cached_signature.present? && verified_system_user_missing?(cached_signature) && Feature.enabled?( :check_for_mailmapped_commit_emails, @commit.project) - return @signature = update_signature!(cached_signature) + return @signature = update_author_email!(cached_signature) end return @signature = cached_signature if cached_signature.present? @@ -43,6 +43,13 @@ def update_signature!(cached_signature) @signature = cached_signature end + def update_author_email!(cached_signature) + return cached_signature unless author_email.present? + + cached_signature.update!(author_email: author_email) + @signature = cached_signature + end + def signature_text strong_memoize(:signature_text) do @signature_data.itself ? @signature_data[:signature] : nil diff --git a/lib/gitlab/ssh/commit.rb b/lib/gitlab/ssh/commit.rb index 791f6a1f3c7112..4654590d94aa13 100644 --- a/lib/gitlab/ssh/commit.rb +++ b/lib/gitlab/ssh/commit.rb @@ -19,7 +19,9 @@ def attributes key_fingerprint_sha256: signature.key_fingerprint, user_id: signature.user_id, verification_status: signature.verification_status - } + }.tap do |attrs| + attrs[:author_email] = author_email if Feature.enabled?(:check_for_mailmapped_commit_emails, @commit.project) + end end end end diff --git a/lib/gitlab/ssh/signature.rb b/lib/gitlab/ssh/signature.rb index aa06b8945d8ee0..be3949c93c8c81 100644 --- a/lib/gitlab/ssh/signature.rb +++ b/lib/gitlab/ssh/signature.rb @@ -49,11 +49,6 @@ def key_fingerprint end def user_id - if verification_status == :verified_system && Feature.enabled?(:check_for_mailmapped_commit_emails, - @commit.project) - return User.find_by_any_email(author_email)&.id - end - signed_by_key&.user_id end diff --git a/spec/lib/gitlab/ssh/commit_spec.rb b/spec/lib/gitlab/ssh/commit_spec.rb index 79393c7f8bd50c..4ec556695604a8 100644 --- a/spec/lib/gitlab/ssh/commit_spec.rb +++ b/spec/lib/gitlab/ssh/commit_spec.rb @@ -33,7 +33,8 @@ allow(verifier).to receive_messages({ verification_status: verification_status, signed_by_key: signed_by_key, - key_fingerprint: fingerprint + key_fingerprint: fingerprint, + author_email: author_email }) allow(verifier).to receive(:user_id).and_return(user_author.id) @@ -87,16 +88,21 @@ context 'when signature is verified_system' do before do - allow(verifier).to receive(:verification_status).and_return(:verified_system) + allow(verifier).to receive_messages( + verification_status: :verified_system, + user_id: user.id + ) end + let(:user) { create(:user) } let(:signer) { :VERIFIED_SYSTEM } - it 'uses the author email to set the user id' do + it 'returns the correct attributes' do expect(signature).to have_attributes( commit_sha: commit.sha, - user_id: user_author.id, - verification_status: 'verified_system' + user_id: user.id, + verification_status: 'verified_system', + author_email: author_email ) end @@ -120,8 +126,9 @@ end context 'when author_email is present' do - it 'updates stored signature with user_id from signature author_email' do - expect(signature.user).to eq(user_author) + it 'updates stored signature with author_email only' do + expect(signature.author_email).to eq(user_author.email) + expect(signature.user).to be_nil end end @@ -129,7 +136,7 @@ let(:author_email) { nil } it 'does not update the stored signature' do - expect(signature.user).to be_nil + expect(signature).not_to receive(:update!) end end diff --git a/spec/lib/gitlab/ssh/signature_spec.rb b/spec/lib/gitlab/ssh/signature_spec.rb index ad5a0bdca65d3a..82a46dd139bacc 100644 --- a/spec/lib/gitlab/ssh/signature_spec.rb +++ b/spec/lib/gitlab/ssh/signature_spec.rb @@ -322,19 +322,5 @@ it 'returns the user id from signed by key' do expect(signature.user_id).to eq(user.id) end - - context 'for system verified commits' do - let(:signer) { :SIGNER_SYSTEM } - let(:new_user) { create(:user) } - - before do - allow(User).to receive(:find_by_any_email) - .with(author_email).and_return(new_user) - end - - it 'returns the user id from author email' do - expect(signature.user_id).to eq(new_user.id) - end - end end end diff --git a/spec/models/commit_signatures/gpg_signature_spec.rb b/spec/models/commit_signatures/gpg_signature_spec.rb index a338964ca68108..2697bd2db03ca3 100644 --- a/spec/models/commit_signatures/gpg_signature_spec.rb +++ b/spec/models/commit_signatures/gpg_signature_spec.rb @@ -171,8 +171,8 @@ context 'when commit author does not match the gpg_key author' do let(:commit_author) { create(:user) } - it 'returns unverified_author_email' do - expect(signature.verification_status).to eq('unverified_author_email') + it 'returns verified_system' do + expect(signature.verification_status).to eq('verified_system') end end end diff --git a/spec/models/commit_signatures/ssh_signature_spec.rb b/spec/models/commit_signatures/ssh_signature_spec.rb index e6061d1703dab6..a92e3698cb35c0 100644 --- a/spec/models/commit_signatures/ssh_signature_spec.rb +++ b/spec/models/commit_signatures/ssh_signature_spec.rb @@ -16,7 +16,7 @@ let(:signature) do create(:ssh_signature, commit_sha: commit_sha, key: ssh_key, key_fingerprint_sha256: key_fingerprint, user: user, - verification_status: verification_status) + verification_status: verification_status, author_email: commit.author_email) end let(:attributes) do @@ -25,7 +25,8 @@ project: project, key: ssh_key, key_fingerprint_sha256: key_fingerprint, - user: user + user: user, + author_email: commit.author_email } end @@ -120,11 +121,17 @@ expect(signature.verification_status).to eq('verified_system') end - context 'and the author email does not belong to the signed by user' do - let(:user) { create(:user) } + context 'and author email does not match the SSH key owner' do + let(:author) { create(:user) } + let(:commit) { create(:commit, project: project, sha: commit_sha, author: author) } - it 'returns unverified_author_email' do - expect(signature.verification_status).to eq('unverified_author_email') + let(:signature) do + create(:ssh_signature, commit_sha: commit_sha, key: ssh_key, key_fingerprint_sha256: key_fingerprint, + user: user, verification_status: verification_status, author_email: commit.author_email) + end + + it 'returns verified_system' do + expect(signature.verification_status).to eq('verified_system') end context 'when check_for_mailmapped_commit_emails feature flag is disabled' do -- GitLab From f2041aa4b791827743e44564612f66d5c07ac4f4 Mon Sep 17 00:00:00 2001 From: Emma Park Date: Thu, 8 May 2025 18:30:20 +0900 Subject: [PATCH 2/4] Update author_email when it is misisng Since user_id is no longer used for verification for a verified system, we now check if author_email is missing instead. If it is, we update the signature with the author_email. --- app/models/concerns/commit_signature.rb | 3 +-- lib/gitlab/signed_commit.rb | 12 +++++++----- spec/lib/gitlab/ssh/commit_spec.rb | 12 ++++++------ 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/app/models/concerns/commit_signature.rb b/app/models/concerns/commit_signature.rb index 5264e244cbf5f5..095956669af1c0 100644 --- a/app/models/concerns/commit_signature.rb +++ b/app/models/concerns/commit_signature.rb @@ -59,8 +59,7 @@ def verification_status def emails_for_verification return x509_certificate.all_emails if x509? - return author_email if Feature.enabled?( - :check_for_mailmapped_commit_emails, project) && verified_system? + return author_email if verified_system? signed_by_user&.verified_emails end diff --git a/lib/gitlab/signed_commit.rb b/lib/gitlab/signed_commit.rb index 35da86fb079f6a..ffb320dd412b8c 100644 --- a/lib/gitlab/signed_commit.rb +++ b/lib/gitlab/signed_commit.rb @@ -22,9 +22,10 @@ def signature cached_signature = lazy_signature&.itself - # We need to update the cache if there is no user for a verified system commit. - # This is because of the introduction of mailmap. See https://gitlab.com/gitlab-org/gitlab/-/issues/425042#note_1997022896. - if cached_signature.present? && verified_system_user_missing?(cached_signature) && Feature.enabled?( + # We need to update the cache if there is no author_email for a verified system commit. + # For such commits, GitLab signs the commit directly, and since GitLab is not a user, + # user_id can be nil. Therefore, we use author_email for verification instead of user_id. + if cached_signature.present? && verified_system_author_email_missing?(cached_signature) && Feature.enabled?( :check_for_mailmapped_commit_emails, @commit.project) return @signature = update_author_email!(cached_signature) end @@ -34,8 +35,8 @@ def signature @signature = create_cached_signature! end - def verified_system_user_missing?(cached_signature) - cached_signature.verified_system? && cached_signature.user.nil? && author_email.present? + def verified_system_author_email_missing?(cached_signature) + cached_signature.verified_system? && cached_signature.author_email.nil? && author_email.present? end def update_signature!(cached_signature) @@ -45,6 +46,7 @@ def update_signature!(cached_signature) def update_author_email!(cached_signature) return cached_signature unless author_email.present? + return cached_signature if cached_signature.author_email cached_signature.update!(author_email: author_email) @signature = cached_signature diff --git a/spec/lib/gitlab/ssh/commit_spec.rb b/spec/lib/gitlab/ssh/commit_spec.rb index 4ec556695604a8..503b0f4b28f8c5 100644 --- a/spec/lib/gitlab/ssh/commit_spec.rb +++ b/spec/lib/gitlab/ssh/commit_spec.rb @@ -106,15 +106,16 @@ ) end - context 'when a stored signature is present for the commit with user nil' do - let(:signature_with_no_user) do + context 'when a stored signature is present for the commit with author_email nil' do + let(:signature_with_no_author_email) do create(:ssh_signature, commit_sha: commit.sha, verification_status: :verified_system, user_id: nil, project: project, key_fingerprint_sha256: fingerprint, - key_id: signed_by_key.id + key_id: signed_by_key.id, + author_email: nil ) end @@ -122,13 +123,12 @@ allow(CommitSignatures::SshSignature) .to receive(:by_commit_sha) .with([commit.id]) - .and_return([signature_with_no_user]) + .and_return([signature_with_no_author_email]) end context 'when author_email is present' do it 'updates stored signature with author_email only' do expect(signature.author_email).to eq(user_author.email) - expect(signature.user).to be_nil end end @@ -146,7 +146,7 @@ end it 'does not update the stored signature' do - expect(signature.user).to be_nil + expect(signature.author_email).to be_nil end end end -- GitLab From c7b91b44201b7f4ea333ccd6000a0e491149ba30 Mon Sep 17 00:00:00 2001 From: Emma Park Date: Thu, 8 May 2025 23:31:50 +0900 Subject: [PATCH 3/4] Add author_email to GPG signature For GitLab GPG signed commits,if gpg_key_user_email is nil, we updated it with author_email. This mixed two different concepts in one field. With the addition of the author_email column to the GpgSignature table, we can now properly separate these concerns: - Keep gpg_key_user_email strictly for emails associated with GPG keys - Use author_email to store the commit author's email from Gitaly for system-verified commits. This change ensures a cleaner data model and better reflects the nature of system-signed commits. Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/526578 --- lib/gitlab/gpg/commit.rb | 13 ++++--------- lib/gitlab/signed_commit.rb | 1 - spec/lib/gitlab/gpg/commit_spec.rb | 19 ++++++++++--------- .../commit_signatures/gpg_signature_spec.rb | 9 ++++++--- 4 files changed, 20 insertions(+), 22 deletions(-) diff --git a/lib/gitlab/gpg/commit.rb b/lib/gitlab/gpg/commit.rb index c1ffb8bb63830a..3b63f16443e042 100644 --- a/lib/gitlab/gpg/commit.rb +++ b/lib/gitlab/gpg/commit.rb @@ -85,9 +85,11 @@ def attributes(gpg_key) gpg_key: gpg_key, gpg_key_primary_keyid: gpg_key&.keyid || verified_signature&.fingerprint, gpg_key_user_name: user_infos[:name], - gpg_key_user_email: gpg_key_user_email(user_infos, verification_status), + gpg_key_user_email: user_infos[:email], verification_status: verification_status - } + }.tap do |attrs| + attrs[:author_email] = author_email if Feature.enabled?(:check_for_mailmapped_commit_emails, @commit.project) + end end def verification_status(gpg_key) @@ -126,13 +128,6 @@ def find_gpg_key(fingerprint) GpgKey.find_by_primary_keyid(fingerprint) || GpgKeySubkey.find_by_keyid(fingerprint) end end - - def gpg_key_user_email(user_infos, verification_status) - return user_infos[:email] unless Feature.enabled?(:check_for_mailmapped_commit_emails, - @commit.project) && verification_status == :verified_system - - user_infos[:email] || author_email - end end end end diff --git a/lib/gitlab/signed_commit.rb b/lib/gitlab/signed_commit.rb index ffb320dd412b8c..a1cc4d4246b5c5 100644 --- a/lib/gitlab/signed_commit.rb +++ b/lib/gitlab/signed_commit.rb @@ -45,7 +45,6 @@ def update_signature!(cached_signature) end def update_author_email!(cached_signature) - return cached_signature unless author_email.present? return cached_signature if cached_signature.author_email cached_signature.update!(author_email: author_email) diff --git a/spec/lib/gitlab/gpg/commit_spec.rb b/spec/lib/gitlab/gpg/commit_spec.rb index a88f84afaedc10..3ec46a6ef4233d 100644 --- a/spec/lib/gitlab/gpg/commit_spec.rb +++ b/spec/lib/gitlab/gpg/commit_spec.rb @@ -356,8 +356,9 @@ gpg_key: nil, gpg_key_primary_keyid: GpgHelpers::User1.primary_keyid, gpg_key_user_name: nil, - gpg_key_user_email: user_email, - verification_status: 'verified_system' + gpg_key_user_email: nil, + verification_status: 'verified_system', + author_email: user_email ) end @@ -399,17 +400,17 @@ ) end - context 'when signature is system verified and gpg_key_user_email is nil' do + context 'when signature is system verified and author_email is nil' do let(:signer) { :SIGNER_SYSTEM } - it 'update gpg_key_user_email with signature_data author_email' do + it 'update author_email with signature_data author_email' do signature stored_signature = CommitSignatures::GpgSignature.find_by_commit_sha(commit_sha) - stored_signature.update!(gpg_key_user_email: nil) + stored_signature.update!(author_email: nil) expect { described_class.new(commit).update_signature!(stored_signature) }.to( - change { signature.reload.gpg_key_user_email }.from(nil).to(user_email) + change { signature.reload.author_email }.from(nil).to(user_email) ) end @@ -418,14 +419,14 @@ stub_feature_flags(check_for_mailmapped_commit_emails: false) end - it 'does not update gpg_key_user_email with signature_data author_email' do + it 'does not update author_email with signature_data author_email' do signature stored_signature = CommitSignatures::GpgSignature.find_by_commit_sha(commit_sha) - stored_signature.update!(gpg_key_user_email: nil) + stored_signature.update!(author_email: nil) expect { described_class.new(commit).update_signature!(stored_signature) }.to( - not_change { signature.reload.gpg_key_user_email }) + not_change { signature.reload.author_email }) end end end diff --git a/spec/models/commit_signatures/gpg_signature_spec.rb b/spec/models/commit_signatures/gpg_signature_spec.rb index 2697bd2db03ca3..66dd4402aeea96 100644 --- a/spec/models/commit_signatures/gpg_signature_spec.rb +++ b/spec/models/commit_signatures/gpg_signature_spec.rb @@ -169,10 +169,13 @@ end context 'when commit author does not match the gpg_key author' do - let(:commit_author) { create(:user) } + let(:signature) do + create(:gpg_signature, commit_sha: commit_sha, gpg_key: gpg_key, project: project, + verification_status: verification_status, author_email: 'test@test.com') + end - it 'returns verified_system' do - expect(signature.verification_status).to eq('verified_system') + it 'returns unverified_author_email' do + expect(signature.verification_status).to eq('unverified_author_email') end end end -- GitLab From 502620ddb36f542ba84d7b1875f306fa5bb01c8d Mon Sep 17 00:00:00 2001 From: Emma Park Date: Fri, 9 May 2025 23:26:24 +0900 Subject: [PATCH 4/4] Fix UI signed commit verification for mailmapped emails For a UI signed commit, if we directly compare the author email and the commit email, we might incorrectly label the commit as unverified when the user has mapped the author email to one of their verified emails. In this case, we want to mark the commit as verified and show the green label. To fix this, we now check if the commit author email is included in the author's verified emails. --- app/models/commit_signatures/gpg_signature.rb | 7 +- app/models/concerns/commit_signature.rb | 2 +- lib/gitlab/signed_commit.rb | 3 +- spec/lib/gitlab/ssh/commit_spec.rb | 3 +- .../commit_signatures/gpg_signature_spec.rb | 64 +++++++++++-------- .../commit_signatures/ssh_signature_spec.rb | 54 ++++++++++------ 6 files changed, 75 insertions(+), 58 deletions(-) diff --git a/app/models/commit_signatures/gpg_signature.rb b/app/models/commit_signatures/gpg_signature.rb index 7422ccd380531e..45937b68691f28 100644 --- a/app/models/commit_signatures/gpg_signature.rb +++ b/app/models/commit_signatures/gpg_signature.rb @@ -13,12 +13,7 @@ class GpgSignature < ApplicationRecord validates :gpg_key_primary_keyid, presence: true def signed_by_user - return gpg_key.user if gpg_key - - # system signed gpg keys may not have a gpg key in rails. - # instead take the user from the gpg signature. - User.find_by_any_email(gpg_key_user_email) if verified_system? && Feature.enabled?( - :check_for_mailmapped_commit_emails, project) + gpg_key&.user end def type diff --git a/app/models/concerns/commit_signature.rb b/app/models/concerns/commit_signature.rb index 095956669af1c0..cd68310fa98a1d 100644 --- a/app/models/concerns/commit_signature.rb +++ b/app/models/concerns/commit_signature.rb @@ -59,7 +59,7 @@ def verification_status def emails_for_verification return x509_certificate.all_emails if x509? - return author_email if verified_system? + return User.find_by_any_email(author_email, confirmed: true)&.verified_emails if verified_system? signed_by_user&.verified_emails end diff --git a/lib/gitlab/signed_commit.rb b/lib/gitlab/signed_commit.rb index a1cc4d4246b5c5..5dfd9884f5db3e 100644 --- a/lib/gitlab/signed_commit.rb +++ b/lib/gitlab/signed_commit.rb @@ -25,6 +25,7 @@ def signature # We need to update the cache if there is no author_email for a verified system commit. # For such commits, GitLab signs the commit directly, and since GitLab is not a user, # user_id can be nil. Therefore, we use author_email for verification instead of user_id. + # See https://gitlab.com/gitlab-org/gitlab/-/issues/425042#note_1997022896. if cached_signature.present? && verified_system_author_email_missing?(cached_signature) && Feature.enabled?( :check_for_mailmapped_commit_emails, @commit.project) return @signature = update_author_email!(cached_signature) @@ -45,8 +46,6 @@ def update_signature!(cached_signature) end def update_author_email!(cached_signature) - return cached_signature if cached_signature.author_email - cached_signature.update!(author_email: author_email) @signature = cached_signature end diff --git a/spec/lib/gitlab/ssh/commit_spec.rb b/spec/lib/gitlab/ssh/commit_spec.rb index 503b0f4b28f8c5..b3b8d7a74f82d7 100644 --- a/spec/lib/gitlab/ssh/commit_spec.rb +++ b/spec/lib/gitlab/ssh/commit_spec.rb @@ -33,8 +33,7 @@ allow(verifier).to receive_messages({ verification_status: verification_status, signed_by_key: signed_by_key, - key_fingerprint: fingerprint, - author_email: author_email + key_fingerprint: fingerprint }) allow(verifier).to receive(:user_id).and_return(user_author.id) diff --git a/spec/models/commit_signatures/gpg_signature_spec.rb b/spec/models/commit_signatures/gpg_signature_spec.rb index 66dd4402aeea96..6e9115ee03b7d7 100644 --- a/spec/models/commit_signatures/gpg_signature_spec.rb +++ b/spec/models/commit_signatures/gpg_signature_spec.rb @@ -92,28 +92,6 @@ it 'retrieves the gpg_key user' do expect(signature.signed_by_user).to eq(gpg_key.user) end - - context 'when signature is verified system and no key is stored' do - let(:user) { create(:user) } - - before do - signature.update!(gpg_key_id: nil, gpg_key_user_email: user.email, verification_status: :verified_system) - end - - it 'retrieves the user from the gpg signature email' do - expect(signature.signed_by_user).to eq(user) - end - - context 'when feature flag is disabled' do - before do - stub_feature_flags(check_for_mailmapped_commit_emails: false) - end - - it 'returns nil' do - expect(signature.signed_by_user).to be_nil - end - end - end end describe '#verification_status' do @@ -164,20 +142,50 @@ context 'when persisted verification_status is verified_system' do let(:verification_status) { :verified_system } - it 'returns existing verification status' do - expect(signature.verification_status).to eq('verified_system') + let(:author_email) { 'author-email-from-gitaly@email.com' } + let(:commit_email) { 'verified-email@email.com' } + + let(:commit) { create(:commit, project: project, sha: commit_sha, author_email: commit_email) } + + let(:signature) do + create(:gpg_signature, commit_sha: commit_sha, gpg_key: gpg_key, project: project, + verification_status: verification_status, author_email: author_email) end - context 'when commit author does not match the gpg_key author' do - let(:signature) do - create(:gpg_signature, commit_sha: commit_sha, gpg_key: gpg_key, project: project, - verification_status: verification_status, author_email: 'test@test.com') + let(:mock_user) do + instance_double(User, + verified_emails: ['author-email-from-gitaly@email.com', 'verified-email@email.com']) + end + + before do + allow(User).to receive(:find_by_any_email) + .with(author_email, confirmed: true) + .and_return(mock_user) + end + + context 'when commit author email is included in verified emails' do + it 'returns verified_system' do + expect(signature.verification_status).to eq('verified_system') end + end + + context 'when commit author email is not included in verified emails' do + let(:commit_email) { 'unverified-email@email.com' } it 'returns unverified_author_email' do expect(signature.verification_status).to eq('unverified_author_email') end end + + context 'when check_for_mailmapped_commit_emails feature flag is disabled' do + before do + stub_feature_flags(check_for_mailmapped_commit_emails: false) + end + + it 'verification status is unmodified' do + expect(signature.verification_status).to eq('verified_system') + end + end end end end diff --git a/spec/models/commit_signatures/ssh_signature_spec.rb b/spec/models/commit_signatures/ssh_signature_spec.rb index a92e3698cb35c0..07f4efb2c8c73b 100644 --- a/spec/models/commit_signatures/ssh_signature_spec.rb +++ b/spec/models/commit_signatures/ssh_signature_spec.rb @@ -16,7 +16,7 @@ let(:signature) do create(:ssh_signature, commit_sha: commit_sha, key: ssh_key, key_fingerprint_sha256: key_fingerprint, user: user, - verification_status: verification_status, author_email: commit.author_email) + verification_status: verification_status) end let(:attributes) do @@ -25,8 +25,7 @@ project: project, key: ssh_key, key_fingerprint_sha256: key_fingerprint, - user: user, - author_email: commit.author_email + user: user } end @@ -117,31 +116,48 @@ context 'when verification_status is verified_system' do let(:verification_status) { :verified_system } - it 'returns the signature verification status' do - expect(signature.verification_status).to eq('verified_system') + let(:author_email) { 'author-email-from-gitaly@email.com' } + let(:commit_email) { 'verified-email@email.com' } + + let(:commit) { create(:commit, project: project, sha: commit_sha, author_email: commit_email) } + + let(:signature) do + create(:ssh_signature, commit_sha: commit_sha, key: ssh_key, key_fingerprint_sha256: key_fingerprint, + user: user, verification_status: verification_status, author_email: author_email) end - context 'and author email does not match the SSH key owner' do - let(:author) { create(:user) } - let(:commit) { create(:commit, project: project, sha: commit_sha, author: author) } + let(:mock_user) do + instance_double(User, + verified_emails: ['author-email-from-gitaly@email.com', 'verified-email@email.com']) + end - let(:signature) do - create(:ssh_signature, commit_sha: commit_sha, key: ssh_key, key_fingerprint_sha256: key_fingerprint, - user: user, verification_status: verification_status, author_email: commit.author_email) - end + before do + allow(User).to receive(:find_by_any_email) + .with(author_email, confirmed: true) + .and_return(mock_user) + end + context 'when commit author email is included in verified emails' do it 'returns verified_system' do expect(signature.verification_status).to eq('verified_system') end + end - context 'when check_for_mailmapped_commit_emails feature flag is disabled' do - before do - stub_feature_flags(check_for_mailmapped_commit_emails: false) - end + context 'when commit author email is not included in verified emails' do + let(:commit_email) { 'unverified-email@email.com' } - it 'verification status is unmodified' do - expect(signature.verification_status).to eq('verified_system') - end + it 'returns unverified_author_email' do + expect(signature.verification_status).to eq('unverified_author_email') + end + end + + context 'when check_for_mailmapped_commit_emails feature flag is disabled' do + before do + stub_feature_flags(check_for_mailmapped_commit_emails: false) + end + + it 'verification status is unmodified' do + expect(signature.verification_status).to eq('verified_system') end end end -- GitLab