Commit c239452b authored by Tiago Botelho's avatar Tiago Botelho

User can keep their commit email private

The private commit email is automatically generated in the format:
id-username@noreply.HOSTNAME

GitLab instance admins are able to change the HOSTNAME portion,
that defaults to Gitlab's hostname, to whatever they prefer.
parent c81d4a65
...@@ -217,7 +217,8 @@ module ApplicationSettingsHelper ...@@ -217,7 +217,8 @@ module ApplicationSettingsHelper
:user_oauth_applications, :user_oauth_applications,
:version_check_enabled, :version_check_enabled,
:web_ide_clientside_preview_enabled, :web_ide_clientside_preview_enabled,
:diff_max_patch_bytes :diff_max_patch_bytes,
:commit_email_hostname
] ]
end end
......
...@@ -22,7 +22,7 @@ module AvatarsHelper ...@@ -22,7 +22,7 @@ module AvatarsHelper
end end
def avatar_icon_for_email(email = nil, size = nil, scale = 2, only_path: true) def avatar_icon_for_email(email = nil, size = nil, scale = 2, only_path: true)
user = User.find_by_any_email(email.try(:downcase)) user = User.find_by_any_email(email)
if user if user
avatar_icon_for_user(user, size, scale, only_path: only_path) avatar_icon_for_user(user, size, scale, only_path: only_path)
else else
......
# frozen_string_literal: true # frozen_string_literal: true
module ProfilesHelper module ProfilesHelper
def commit_email_select_options(user)
private_email = user.private_commit_email
verified_emails = user.verified_emails - [private_email]
[
[s_("Profiles|Use a private email - %{email}").html_safe % { email: private_email }, Gitlab::PrivateCommitEmail::TOKEN],
verified_emails
]
end
def selected_commit_email(user)
user.read_attribute(:commit_email) || user.commit_email
end
def attribute_provider_label(attribute) def attribute_provider_label(attribute)
user_synced_attributes_metadata = current_user.user_synced_attributes_metadata user_synced_attributes_metadata = current_user.user_synced_attributes_metadata
if user_synced_attributes_metadata&.synced?(attribute) if user_synced_attributes_metadata&.synced?(attribute)
......
...@@ -187,6 +187,8 @@ class ApplicationSetting < ActiveRecord::Base ...@@ -187,6 +187,8 @@ class ApplicationSetting < ActiveRecord::Base
validates :user_default_internal_regex, js_regex: true, allow_nil: true validates :user_default_internal_regex, js_regex: true, allow_nil: true
validates :commit_email_hostname, format: { with: /\A[^@]+\z/ }
validates :archive_builds_in_seconds, validates :archive_builds_in_seconds,
allow_nil: true, allow_nil: true,
numericality: { only_integer: true, greater_than_or_equal_to: 1.day.seconds } numericality: { only_integer: true, greater_than_or_equal_to: 1.day.seconds }
...@@ -299,10 +301,15 @@ class ApplicationSetting < ActiveRecord::Base ...@@ -299,10 +301,15 @@ class ApplicationSetting < ActiveRecord::Base
user_default_internal_regex: nil, user_default_internal_regex: nil,
user_show_add_ssh_key_message: true, user_show_add_ssh_key_message: true,
usage_stats_set_by_user_id: nil, usage_stats_set_by_user_id: nil,
diff_max_patch_bytes: Gitlab::Git::Diff::DEFAULT_MAX_PATCH_BYTES diff_max_patch_bytes: Gitlab::Git::Diff::DEFAULT_MAX_PATCH_BYTES,
commit_email_hostname: default_commit_email_hostname
} }
end end
def self.default_commit_email_hostname
"users.noreply.#{Gitlab.config.gitlab.host}"
end
def self.create_from_defaults def self.create_from_defaults
create(defaults) create(defaults)
end end
...@@ -358,6 +365,10 @@ class ApplicationSetting < ActiveRecord::Base ...@@ -358,6 +365,10 @@ class ApplicationSetting < ActiveRecord::Base
Array(read_attribute(:repository_storages)) Array(read_attribute(:repository_storages))
end end
def commit_email_hostname
super.presence || self.class.default_commit_email_hostname
end
def default_project_visibility=(level) def default_project_visibility=(level)
super(Gitlab::VisibilityLevel.level_value(level)) super(Gitlab::VisibilityLevel.level_value(level))
end end
......
...@@ -260,7 +260,7 @@ class Commit ...@@ -260,7 +260,7 @@ class Commit
request_cache(:author) { author_email.downcase } request_cache(:author) { author_email.downcase }
def committer def committer
@committer ||= User.find_by_any_email(committer_email.downcase) @committer ||= User.find_by_any_email(committer_email)
end end
def parents def parents
......
...@@ -347,7 +347,11 @@ class User < ActiveRecord::Base ...@@ -347,7 +347,11 @@ class User < ActiveRecord::Base
# Find a User by their primary email or any associated secondary email # Find a User by their primary email or any associated secondary email
def find_by_any_email(email, confirmed: false) def find_by_any_email(email, confirmed: false)
by_any_email(email, confirmed: confirmed).take return unless email
downcased = email.downcase
find_by_private_commit_email(downcased) || by_any_email(downcased, confirmed: confirmed).take
end end
# Returns a relation containing all the users for the given Email address # Returns a relation containing all the users for the given Email address
...@@ -361,6 +365,12 @@ class User < ActiveRecord::Base ...@@ -361,6 +365,12 @@ class User < ActiveRecord::Base
from_union([users, emails]) from_union([users, emails])
end end
def find_by_private_commit_email(email)
user_id = Gitlab::PrivateCommitEmail.user_id_for_email(email)
find_by(id: user_id)
end
def filter(filter_name) def filter(filter_name)
case filter_name case filter_name
when 'admins' when 'admins'
...@@ -633,6 +643,10 @@ class User < ActiveRecord::Base ...@@ -633,6 +643,10 @@ class User < ActiveRecord::Base
def commit_email def commit_email
return self.email unless has_attribute?(:commit_email) return self.email unless has_attribute?(:commit_email)
if super == Gitlab::PrivateCommitEmail::TOKEN
return private_commit_email
end
# The commit email is the same as the primary email if undefined # The commit email is the same as the primary email if undefined
super.presence || self.email super.presence || self.email
end end
...@@ -645,6 +659,10 @@ class User < ActiveRecord::Base ...@@ -645,6 +659,10 @@ class User < ActiveRecord::Base
has_attribute?(:commit_email) && super has_attribute?(:commit_email) && super
end end
def private_commit_email
Gitlab::PrivateCommitEmail.for_user(self)
end
# see if the new email is already a verified secondary email # see if the new email is already a verified secondary email
def check_for_verified_email def check_for_verified_email
skip_reconfirmation! if emails.confirmed.where(email: self.email).any? skip_reconfirmation! if emails.confirmed.where(email: self.email).any?
...@@ -1020,13 +1038,21 @@ class User < ActiveRecord::Base ...@@ -1020,13 +1038,21 @@ class User < ActiveRecord::Base
def verified_emails def verified_emails
verified_emails = [] verified_emails = []
verified_emails << email if primary_email_verified? verified_emails << email if primary_email_verified?
verified_emails << private_commit_email
verified_emails.concat(emails.confirmed.pluck(:email)) verified_emails.concat(emails.confirmed.pluck(:email))
verified_emails verified_emails
end end
def verified_email?(check_email) def verified_email?(check_email)
downcased = check_email.downcase downcased = check_email.downcase
email == downcased ? primary_email_verified? : emails.confirmed.where(email: downcased).exists?
if email == downcased
primary_email_verified?
else
user_id = Gitlab::PrivateCommitEmail.user_id_for_email(downcased)
user_id == id || emails.confirmed.where(email: downcased).exists?
end
end end
def hook_attrs def hook_attrs
......
...@@ -20,5 +20,11 @@ ...@@ -20,5 +20,11 @@
By default GitLab sends emails in HTML and plain text formats so mail By default GitLab sends emails in HTML and plain text formats so mail
clients can choose what format to use. Disable this option if you only clients can choose what format to use. Disable this option if you only
want to send emails in plain text format. want to send emails in plain text format.
.form-group
= f.label :commit_email_hostname, _('Custom hostname (for private commit emails)'), class: 'label-bold'
= f.text_field :commit_email_hostname, class: 'form-control'
.form-text.text-muted
- commit_email_hostname_docs_link = link_to _('Learn more'), help_page_path('user/admin_area/settings/email', anchor: 'custom-private-commit-email-hostname'), target: '_blank'
= _("This setting will update the hostname that is used to generate private commit emails. %{learn_more}").html_safe % { learn_more: commit_email_hostname_docs_link }
= f.submit 'Save changes', class: "btn btn-success" = f.submit 'Save changes', class: "btn btn-success"
...@@ -91,8 +91,9 @@ ...@@ -91,8 +91,9 @@
= f.select :public_email, options_for_select(@user.all_emails, selected: @user.public_email), = f.select :public_email, options_for_select(@user.all_emails, selected: @user.public_email),
{ help: s_("Profiles|This email will be displayed on your public profile."), include_blank: s_("Profiles|Do not show on profile") }, { help: s_("Profiles|This email will be displayed on your public profile."), include_blank: s_("Profiles|Do not show on profile") },
control_class: 'select2' control_class: 'select2'
= f.select :commit_email, options_for_select(@user.verified_emails, selected: @user.commit_email), - commit_email_docs_link = link_to s_('Profiles|Learn more'), help_page_path('user/profile/index', anchor: 'commit-email', target: '_blank')
{ help: 'This email will be used for web based operations, such as edits and merges.' }, = f.select :commit_email, options_for_select(commit_email_select_options(@user), selected: selected_commit_email(@user)),
{ help: s_("Profiles|This email will be used for web based operations, such as edits and merges. %{learn_more}").html_safe % { learn_more: commit_email_docs_link } },
control_class: 'select2' control_class: 'select2'
= f.select :preferred_language, Gitlab::I18n::AVAILABLE_LANGUAGES.map { |value, label| [label, value] }, = f.select :preferred_language, Gitlab::I18n::AVAILABLE_LANGUAGES.map { |value, label| [label, value] },
{ help: s_("Profiles|This feature is experimental and translations are not complete yet.") }, { help: s_("Profiles|This feature is experimental and translations are not complete yet.") },
......
---
title: Adds option to override commit email with a noreply private email
merge_request: 22560
author:
type: added
# frozen_string_literal: true
class AddPrivateCommitEmailHostnameToApplicationSettings < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def change
add_column(:application_settings, :commit_email_hostname, :string, null: true)
end
end
...@@ -166,6 +166,7 @@ ActiveRecord::Schema.define(version: 20181107054254) do ...@@ -166,6 +166,7 @@ ActiveRecord::Schema.define(version: 20181107054254) do
t.integer "receive_max_input_size" t.integer "receive_max_input_size"
t.integer "diff_max_patch_bytes", default: 102400, null: false t.integer "diff_max_patch_bytes", default: 102400, null: false
t.integer "archive_builds_in_seconds" t.integer "archive_builds_in_seconds"
t.string "commit_email_hostname"
end end
create_table "audit_events", force: :cascade do |t| create_table "audit_events", force: :cascade do |t|
......
...@@ -171,8 +171,8 @@ class Commit ...@@ -171,8 +171,8 @@ class Commit
extend Gitlab::Cache::RequestCache extend Gitlab::Cache::RequestCache
def author def author
User.find_by_any_email(author_email.downcase) User.find_by_any_email(author_email)
end end
request_cache(:author) { author_email.downcase } request_cache(:author) { author_email }
end end
``` ```
...@@ -3,3 +3,20 @@ ...@@ -3,3 +3,20 @@
## Custom logo ## Custom logo
The logo in the header of some emails can be customized, see the [logo customization section](../../../customization/branded_page_and_email_header.md). The logo in the header of some emails can be customized, see the [logo customization section](../../../customization/branded_page_and_email_header.md).
## Custom hostname for private commit emails
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/22560) in GitLab 11.5.
This configuration option sets the email hostname for [private commit emails](../../profile/index.md#private-commit-email),
and it's, by default, set to `users.noreply.YOUR_CONFIGURED_HOSTNAME`.
In order to change this option:
1. Go to **Admin area > Settings** (`/admin/application_settings`).
1. Under the **Email** section, change the **Custom hostname (for private commit emails)** field.
1. Hit **Save** for the changes to take effect.
NOTE: **Note**: Once the hostname gets configured, every private commit email using the previous hostname, will not get
recognized by GitLab. This can directly conflict with certain [Push rules](https://docs.gitlab.com/ee/push_rules/push_rules.html) such as
`Check whether author is a GitLab user` and `Check whether committer is the current authenticated user`.
...@@ -31,6 +31,7 @@ From there, you can: ...@@ -31,6 +31,7 @@ From there, you can:
- Update your personal information - Update your personal information
- Set a [custom status](#current-status) for your profile - Set a [custom status](#current-status) for your profile
- Manage your [commit email](#commit-email) for your profile
- Manage [2FA](account/two_factor_authentication.md) - Manage [2FA](account/two_factor_authentication.md)
- Change your username and [delete your account](account/delete_account.md) - Change your username and [delete your account](account/delete_account.md)
- Manage applications that can - Manage applications that can
...@@ -132,6 +133,45 @@ They may however contain emoji codes such as `I'm on vacation :palm_tree:`. ...@@ -132,6 +133,45 @@ They may however contain emoji codes such as `I'm on vacation :palm_tree:`.
You can also set your current status [using the API](../../api/users.md#user-status). You can also set your current status [using the API](../../api/users.md#user-status).
## Commit email
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/21598) in GitLab 11.4.
A commit email, is the email that will be displayed in every Git-related action done through the
GitLab interface.
You are able to select from the list of your own verified emails which email you want to use as the commit email.
To change it:
1. Open the user menu in the top-right corner of the navigation bar.
1. Hit **Commit email** selection box.
1. Select any of the verified emails.
1. Hit **Update profile settings**.
### Private commit email
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/22560) in GitLab 11.5.
GitLab provides the user with an automatically generated private commit email option,
which allows the user to not make their email information public.
To enable this option:
1. Open the user menu in the top-right corner of the navigation bar.
1. Hit **Commit email** selection box.
1. Select **Use a private email** option.
1. Hit **Update profile settings**.
Once this option is enabled, every Git-related action will be performed using the private commit email.
In order to stay fully annonymous, you can also copy this private commit email
and configure it on your local machine using the following command:
```
git config --global user.email "YOUR_PRIVATE_COMMIT_EMAIL"
```
## Troubleshooting ## Troubleshooting
### Why do I keep getting signed out? ### Why do I keep getting signed out?
......
# frozen_string_literal: true
module Gitlab
module PrivateCommitEmail
TOKEN = "_private".freeze
class << self
def regex
hostname_regexp = Regexp.escape(Gitlab::CurrentSettings.current_application_settings.commit_email_hostname)
/\A(?<id>([0-9]+))\-([^@]+)@#{hostname_regexp}\z/
end
def user_id_for_email(email)
match = email&.match(regex)
return unless match
match[:id].to_i
end
def for_user(user)
hostname = Gitlab::CurrentSettings.current_application_settings.commit_email_hostname
"#{user.id}-#{user.username}@#{hostname}"
end
end
end
end
...@@ -2094,6 +2094,9 @@ msgstr "" ...@@ -2094,6 +2094,9 @@ msgstr ""
msgid "Custom CI config path" msgid "Custom CI config path"
msgstr "" msgstr ""
msgid "Custom hostname (for private commit emails)"
msgstr ""
msgid "Custom notification events" msgid "Custom notification events"
msgstr "" msgstr ""
...@@ -4701,6 +4704,9 @@ msgstr "" ...@@ -4701,6 +4704,9 @@ msgstr ""
msgid "Profiles|Invalid username" msgid "Profiles|Invalid username"
msgstr "" msgstr ""
msgid "Profiles|Learn more"
msgstr ""
msgid "Profiles|Made a private contribution" msgid "Profiles|Made a private contribution"
msgstr "" msgstr ""
...@@ -4743,6 +4749,9 @@ msgstr "" ...@@ -4743,6 +4749,9 @@ msgstr ""
msgid "Profiles|This email will be displayed on your public profile." msgid "Profiles|This email will be displayed on your public profile."
msgstr "" msgstr ""
msgid "Profiles|This email will be used for web based operations, such as edits and merges. %{learn_more}"
msgstr ""
msgid "Profiles|This emoji and message will appear on your profile and throughout the interface." msgid "Profiles|This emoji and message will appear on your profile and throughout the interface."
msgstr "" msgstr ""
...@@ -4767,6 +4776,9 @@ msgstr "" ...@@ -4767,6 +4776,9 @@ msgstr ""
msgid "Profiles|Upload new avatar" msgid "Profiles|Upload new avatar"
msgstr "" msgstr ""
msgid "Profiles|Use a private email - %{email}"
msgstr ""
msgid "Profiles|Username change failed - %{message}" msgid "Profiles|Username change failed - %{message}"
msgstr "" msgstr ""
...@@ -6296,6 +6308,9 @@ msgstr "" ...@@ -6296,6 +6308,9 @@ msgstr ""
msgid "This setting can be overridden in each project." msgid "This setting can be overridden in each project."
msgstr "" msgstr ""
msgid "This setting will update the hostname that is used to generate private commit emails. %{learn_more}"
msgstr ""
msgid "This source diff could not be displayed because it is too large." msgid "This source diff could not be displayed because it is too large."
msgstr "" msgstr ""
......
require 'rails_helper' require 'rails_helper'
describe ProfilesHelper do describe ProfilesHelper do
describe '#commit_email_select_options' do
it 'returns an array with private commit email along with all the verified emails' do
user = create(:user)
private_email = user.private_commit_email
verified_emails = user.verified_emails - [private_email]
emails = [
["Use a private email - #{private_email}", Gitlab::PrivateCommitEmail::TOKEN],
verified_emails
]
expect(helper.commit_email_select_options(user)).to match_array(emails)
end
end
describe '#selected_commit_email' do
let(:user) { create(:user) }
it 'returns main email when commit email attribute is nil' do
expect(helper.selected_commit_email(user)).to eq(user.email)
end
it 'returns DB stored commit_email' do
user.update(commit_email: Gitlab::PrivateCommitEmail::TOKEN)
expect(helper.selected_commit_email(user)).to eq(Gitlab::PrivateCommitEmail::TOKEN)
end
end
describe '#email_provider_label' do describe '#email_provider_label' do
it "returns nil for users without external email" do it "returns nil for users without external email" do
user = create(:user) user = create(:user)
......
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::PrivateCommitEmail do
let(:hostname) { Gitlab::CurrentSettings.current_application_settings.commit_email_hostname }
context '.regex' do
subject { described_class.regex }
it { is_expected.to match("1-foo@#{hostname}") }
it { is_expected.not_to match("1-foo@#{hostname}.foo") }
it { is_expected.not_to match('1-foo@users.noreply.gitlab.com') }
it { is_expected.not_to match('foo-1@users.noreply.gitlab.com') }
it { is_expected.not_to match('foobar@gitlab.com') }
end
context '.user_id_for_email' do
let(:id) { 1 }
it 'parses user id from email' do
email = "#{id}-foo@#{hostname}"
expect(described_class.user_id_for_email(email)).to eq(id)
end
it 'returns nil on invalid commit email' do
email = "#{id}-foo@users.noreply.bar.com"
expect(described_class.user_id_for_email(email)).to be_nil
end
end
context '.for_user' do
it 'returns email in the format id-username@hostname' do
user = create(:user)
expect(described_class.for_user(user)).to eq("#{user.id}-#{user.username}@#{hostname}")
end
end
end
...@@ -25,6 +25,9 @@ describe ApplicationSetting do ...@@ -25,6 +25,9 @@ describe ApplicationSetting do
it { is_expected.to allow_value(https).for(:after_sign_out_path) } it { is_expected.to allow_value(https).for(:after_sign_out_path) }
it { is_expected.not_to allow_value(ftp).for(:after_sign_out_path) } it { is_expected.not_to allow_value(ftp).for(:after_sign_out_path) }
it { is_expected.to allow_value("dev.gitlab.com").for(:commit_email_hostname) }
it { is_expected.not_to allow_value("@dev.gitlab").for(:commit_email_hostname) }
describe 'default_artifacts_expire_in' do describe 'default_artifacts_expire_in' do
it 'sets an error if it cannot parse' do it 'sets an error if it cannot parse' do
setting.update(default_artifacts_expire_in: 'a') setting.update(default_artifacts_expire_in: 'a')
...@@ -107,6 +110,14 @@ describe ApplicationSetting do ...@@ -107,6 +110,14 @@ describe ApplicationSetting do
it { expect(setting.repository_storages).to eq(['default']) } it { expect(setting.repository_storages).to eq(['default']) }
end end
context '#commit_email_hostname' do
it 'returns configured gitlab hostname if commit_email_hostname is not defined' do
setting.update(commit_email_hostname: nil)
expect(setting.commit_email_hostname).to eq("users.noreply.#{Gitlab.config.gitlab.host}")
end
end
context 'auto_devops_domain setting' do context 'auto_devops_domain setting' do
context 'when auto_devops_enabled? is true' do context 'when auto_devops_enabled? is true' do
before do before do
......
...@@ -183,6 +183,12 @@ describe User do ...@@ -183,6 +183,12 @@ describe User do
expect(found_user.commit_email).to eq(user.email) expect(found_user.commit_email).to eq(user.email)
end end
it 'returns the private commit email when commit_email has _private' do
user.update_column(:commit_email, Gitlab::PrivateCommitEmail::TOKEN)
expect(user.commit_email).to eq(user.private_commit_email)
end
it 'can be set to a confirmed email' do it 'can be set to a confirmed email' do
confirmed = create(:email, :confirmed, user: user) confirmed = create(:email, :confirmed, user: user)
user.commit_email = confirmed.email user.commit_email = confirmed.email
...@@ -333,6 +339,40 @@ describe User do ...@@ -333,6 +339,40 @@ describe User do
expect(user).to be_valid expect(user).to be_valid
end end
end end
context 'set_commit_email' do
it 'keeps commit email when private commit email is being used' do
user = create(:user, commit_email: Gitlab::PrivateCommitEmail::TOKEN)
expect(user.read_attribute(:commit_email)).to eq(Gitlab::PrivateCommitEmail::TOKEN)
end
it 'keeps the commit email when nil' do
user = create(:user, commit_email: nil)
expect(user.read_attribute(:commit_email)).to be_nil
end
it 'reverts to nil when email is not verified' do
user = create(:user, commit_email: "foo@bar.com")
expect(user.read_attribute(:commit_email)).to be_nil
end
end
context 'owns_commit_email' do
it 'accepts private commit email' do
user = build(:user, commit_email: Gitlab::PrivateCommitEmail::TOKEN)
expect(user).to be_valid
end
it 'accepts nil commit email' do
user = build(:user, commit_email: nil)
expect(user).to be_valid
end
end
end end
end end
...@@ -1075,6 +1115,14 @@ describe User do ...@@ -1075,6 +1115,14 @@ describe User do
end end
describe '.find_by_any_email' do describe '.find_by_any_email' do
it 'finds user through private commit email' do
user = create(:user)
private_email = user.private_commit_email
expect(described_class.find_by_any_email(private_email)).to eq(user)
expect(described_class.find_by_any_email(private_email, confirmed: true)).to eq(user)
end
it 'finds by primary email' do it 'finds by primary email' do
user = create(:user, email: 'foo@example.com') user = create(:user, email: 'foo@example.com')
...@@ -1082,6 +1130,13 @@ describe User do ...@@ -1082,6 +1130,13 @@ describe User do
expect(described_class.find_by_any_email(user.email, confirmed: true)).to eq user expect(described_class.find_by_any_email(user.email, confirmed: true)).to eq user
end end
it 'finds by uppercased email' do
user = create(:user, email: 'foo@example.com')
expect(described_class.find_by_any_email(user.email.upcase)).to eq user
expect(described_class.find_by_any_email(user.email.upcase, confirmed: true)).to eq user
end
it 'finds by secondary email' do it 'finds by secondary email' do
email = create(:email, email: 'foo@example.com') email = create(:email, email: 'foo@example.com')
user = email.user user = email.user
...@@ -1457,7 +1512,7 @@ describe User do ...@@ -1457,7 +1512,7 @@ describe User do
email_confirmed = create :email, user: user, confirmed_at: Time.now email_confirmed = create :email, user: user, confirmed_at: Time.now
create :email, user: user create :email, user: user
expect(user.verified_emails).to match_array([user.email, email_confirmed.email]) expect(user.verified_emails).to match_array([user.email, user.private_commit_email, email_confirmed.email])
end end
end end
...@@ -1473,6 +1528,10 @@ describe User do ...@@ -1473,6 +1528,10 @@ describe User do
expect(user.verified_email?(email_confirmed.email.titlecase)).to be_truthy expect(user.verified_email?(email_confirmed.email.titlecase)).to be_truthy
end end
it 'returns true when user is found through private commit email' do
expect(user.verified_email?(user.private_commit_email)).to be_truthy
end
it 'returns false when the email is not verified/confirmed' do it 'returns false when the email is not verified/confirmed' do
email_unconfirmed = create :email, user: user email_unconfirmed = create :email, user: user
user.reload user.reload
...@@ -1668,6 +1727,24 @@ describe User do ...@@ -1668,6 +1727,24 @@ describe User do
end end
end end
describe '.find_by_private_commit_email' do
context 'with email' do
set(:user) { create(:user) }
it 'returns user through private commit email' do
expect(described_class.find_by_private_commit_email(user.private_commit_email)).to eq(user)
end
it 'returns nil when email other than private_commit_email is used' do
expect(described_class.find_by_private_commit_email(user.email)).to be_nil
end
end
it 'returns nil when email is nil' do
expect(described_class.find_by_private_commit_email(nil)).to be_nil
end
end
describe '#sort_by_attribute' do describe '#sort_by_attribute' do
before do before do
described_class.delete_all described_class.delete_all
......
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