Commit a9b31786 authored by Brett Walker's avatar Brett Walker

Make GPG signature verification work with non-primary email (#36959)

parent 4457ae82
...@@ -817,6 +817,17 @@ class User < ActiveRecord::Base ...@@ -817,6 +817,17 @@ class User < ActiveRecord::Base
all_emails all_emails
end end
def all_verified_emails
verified_emails = []
verified_emails << email if confirmed? && !temp_oauth_email?
verified_emails.concat(emails.select {|e| e.confirmed?}.map(&:email))
verified_emails
end
def verified_email?(email)
all_verified_emails.include?(email)
end
def hook_attrs def hook_attrs
{ {
name: name, name: name,
...@@ -1041,10 +1052,6 @@ class User < ActiveRecord::Base ...@@ -1041,10 +1052,6 @@ class User < ActiveRecord::Base
ensure_rss_token! ensure_rss_token!
end end
def verified_email?(email)
self.email == email
end
def sync_attribute?(attribute) def sync_attribute?(attribute)
return true if ldap_user? && attribute == :email return true if ldap_user? && attribute == :email
......
...@@ -26,7 +26,7 @@ to be uploaded to GitLab. For a signature to be verified three conditions need ...@@ -26,7 +26,7 @@ to be uploaded to GitLab. For a signature to be verified three conditions need
to be met: to be met:
1. The public key needs to be added your GitLab account 1. The public key needs to be added your GitLab account
1. One of the emails in the GPG key matches your **primary** email 1. One of the emails in the GPG key matches a **verified** email address you use in GitLab
1. The committer's email matches the verified email from the gpg key 1. The committer's email matches the verified email from the gpg key
## Generating a GPG key ## Generating a GPG key
...@@ -94,7 +94,7 @@ started: ...@@ -94,7 +94,7 @@ started:
``` ```
1. Enter you real name, the email address to be associated with this key (should 1. Enter you real name, the email address to be associated with this key (should
match the primary email address you use in GitLab) and an optional comment match a verified email address you use in GitLab) and an optional comment
(press <kbd>Enter</kbd> to skip): (press <kbd>Enter</kbd> to skip):
``` ```
......
...@@ -2,5 +2,7 @@ FactoryGirl.define do ...@@ -2,5 +2,7 @@ FactoryGirl.define do
factory :email do factory :email do
user user
email { generate(:email_alias) } email { generate(:email_alias) }
trait(:confirmed) { confirmed_at Time.now }
end end
end end
...@@ -88,12 +88,21 @@ describe GpgKey do ...@@ -88,12 +88,21 @@ describe GpgKey do
describe '#emails_with_verified_status' do describe '#emails_with_verified_status' do
it 'email is verified if the user has the matching email' do it 'email is verified if the user has the matching email' do
user = create :user, email: 'bette.cartwright@example.com' user = create :user, email: 'bette.cartwright@example.com'
gpg_key = create :gpg_key, key: GpgHelpers::User2.public_key, user: user gpg_key = create :gpg_key, key: GpgHelpers::User2.public_key, user: user
email_unconfirmed = create :email, user: user
user.reload
expect(gpg_key.emails_with_verified_status).to eq(
'bette.cartwright@example.com' => true,
'bette.cartwright@example.net' => false
)
email_confirmed = create :email, :confirmed, user: user, email: 'bette.cartwright@example.net'
user.reload
expect(gpg_key.emails_with_verified_status).to eq( expect(gpg_key.emails_with_verified_status).to eq(
'bette.cartwright@example.com' => true, 'bette.cartwright@example.com' => true,
'bette.cartwright@example.net' => false 'bette.cartwright@example.net' => true
) )
end end
end end
......
...@@ -1093,6 +1093,48 @@ describe User do ...@@ -1093,6 +1093,48 @@ describe User do
end end
end end
describe '#all_emails' do
let(:user) { create(:user) }
it 'returns all emails' do
email_confirmed = create :email, user: user, confirmed_at: Time.now
email_unconfirmed = create :email, user: user
user.reload
expect(user.all_emails).to eq([user.email, email_unconfirmed.email, email_confirmed.email])
end
end
describe '#all_verified_emails' do
let(:user) { create(:user) }
it 'returns only confirmed emails' do
email_confirmed = create :email, user: user, confirmed_at: Time.now
email_unconfirmed = create :email, user: user
user.reload
expect(user.all_verified_emails).to eq([user.email, email_confirmed.email])
end
end
describe '#verified_email?' do
let(:user) { create(:user) }
it 'returns true when the email is verified/confirmed' do
email_confirmed = create :email, user: user, confirmed_at: Time.now
email_unconfirmed = create :email, user: user
user.reload
expect(user.verified_email?(user.email)).to be_truthy
expect(user.verified_email?(email_confirmed.email)).to be_truthy
end
it 'returns false when the email is not verified/confirmed' do
email_unconfirmed = create :email, user: user
user.reload
expect(user.verified_email?(email_unconfirmed.email)).to be_falsy
end
end
describe '#requires_ldap_check?' do describe '#requires_ldap_check?' do
let(:user) { described_class.new } let(:user) { described_class.new }
...@@ -2073,20 +2115,6 @@ describe User do ...@@ -2073,20 +2115,6 @@ describe User do
end end
end end
describe '#verified_email?' do
it 'returns true when the email is the primary email' do
user = build :user, email: 'email@example.com'
expect(user.verified_email?('email@example.com')).to be true
end
it 'returns false when the email is not the primary email' do
user = build :user, email: 'email@example.com'
expect(user.verified_email?('other_email@example.com')).to be false
end
end
describe '#sync_attribute?' do describe '#sync_attribute?' do
let(:user) { described_class.new } let(:user) { described_class.new }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment