summaryrefslogtreecommitdiff
path: root/app/models/user.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/user.rb')
-rw-r--r--app/models/user.rb87
1 files changed, 60 insertions, 27 deletions
diff --git a/app/models/user.rb b/app/models/user.rb
index ca7fc3b058f..01eba7e0426 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -28,7 +28,7 @@ class User < ActiveRecord::Base
ignore_column :email_provider
ignore_column :authentication_token
- add_authentication_token_field :incoming_email_token
+ add_authentication_token_field :incoming_email_token, token_generator: -> { SecureRandom.hex.to_i(16).to_s(36) }
add_authentication_token_field :feed_token
default_value_for :admin, false
@@ -88,7 +88,7 @@ class User < ActiveRecord::Base
has_one :namespace, -> { where(type: nil) }, dependent: :destroy, foreign_key: :owner_id, inverse_of: :owner, autosave: true # rubocop:disable Cop/ActiveRecordDependent
# Profile
- has_many :keys, -> { where(type: ['Key', nil]) }, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
+ has_many :keys, -> { regular_keys }, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
has_many :deploy_keys, -> { where(type: 'DeployKey') }, dependent: :nullify # rubocop:disable Cop/ActiveRecordDependent
has_many :gpg_keys
@@ -347,18 +347,36 @@ class User < ActiveRecord::Base
# Find a User by their primary email or any associated secondary email
def find_by_any_email(email, confirmed: false)
+ return unless email
+
by_any_email(email, confirmed: confirmed).take
end
- # Returns a relation containing all the users for the given Email address
- def by_any_email(email, confirmed: false)
- users = where(email: email)
- users = users.confirmed if confirmed
+ # Returns a relation containing all the users for the given email addresses
+ #
+ # @param emails [String, Array<String>] email addresses to check
+ # @param confirmed [Boolean] Only return users where the email is confirmed
+ def by_any_email(emails, confirmed: false)
+ emails = Array(emails).map(&:downcase)
+
+ from_users = where(email: emails)
+ from_users = from_users.confirmed if confirmed
+
+ from_emails = joins(:emails).where(emails: { email: emails })
+ from_emails = from_emails.confirmed if confirmed
+
+ items = [from_users, from_emails]
+
+ user_ids = Gitlab::PrivateCommitEmail.user_ids_for_emails(emails)
+ items << where(id: user_ids) if user_ids.present?
+
+ from_union(items)
+ end
- emails = joins(:emails).where(emails: { email: email })
- emails = emails.confirmed if confirmed
+ def find_by_private_commit_email(email)
+ user_id = Gitlab::PrivateCommitEmail.user_id_for_email(email)
- from_union([users, emails])
+ find_by(id: user_id)
end
def filter(filter_name)
@@ -460,12 +478,6 @@ class User < ActiveRecord::Base
by_username(username).take!
end
- def find_by_personal_access_token(token_string)
- return unless token_string
-
- PersonalAccessTokensFinder.new(state: 'active').find_by(token: token_string)&.user # rubocop: disable CodeReuse/Finder
- end
-
# Returns a user for the given SSH key.
def find_by_ssh_key_id(key_id)
Key.find_by(id: key_id)&.user
@@ -639,6 +651,10 @@ class User < ActiveRecord::Base
def 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
super.presence || self.email
end
@@ -651,6 +667,10 @@ class User < ActiveRecord::Base
has_attribute?(:commit_email) && super
end
+ def private_commit_email
+ Gitlab::PrivateCommitEmail.for_user(self)
+ end
+
# see if the new email is already a verified secondary email
def check_for_verified_email
skip_reconfirmation! if emails.confirmed.where(email: self.email).any?
@@ -941,12 +961,17 @@ class User < ActiveRecord::Base
if !Gitlab.config.ldap.enabled
false
elsif ldap_user?
- !last_credential_check_at || (last_credential_check_at + 1.hour) < Time.now
+ !last_credential_check_at || (last_credential_check_at + ldap_sync_time) < Time.now
else
false
end
end
+ def ldap_sync_time
+ # This number resides in this method so it can be redefined in EE.
+ 1.hour
+ end
+
def try_obtain_ldap_lease
# After obtaining this lease LDAP checks will be blocked for 600 seconds
# (10 minutes) for this user.
@@ -1014,6 +1039,7 @@ class User < ActiveRecord::Base
def all_emails
all_emails = []
all_emails << email unless temp_oauth_email?
+ all_emails << private_commit_email
all_emails.concat(emails.map(&:email))
all_emails
end
@@ -1021,13 +1047,29 @@ class User < ActiveRecord::Base
def verified_emails
verified_emails = []
verified_emails << email if primary_email_verified?
+ verified_emails << private_commit_email
verified_emails.concat(emails.confirmed.pluck(:email))
verified_emails
end
+ def any_email?(check_email)
+ downcased = check_email.downcase
+
+ # handle the outdated private commit email case
+ return true if persisted? &&
+ id == Gitlab::PrivateCommitEmail.user_id_for_email(downcased)
+
+ all_emails.include?(check_email.downcase)
+ end
+
def verified_email?(check_email)
downcased = check_email.downcase
- email == downcased ? primary_email_verified? : emails.confirmed.where(email: downcased).exists?
+
+ # handle the outdated private commit email case
+ return true if persisted? &&
+ id == Gitlab::PrivateCommitEmail.user_id_for_email(downcased)
+
+ verified_emails.include?(check_email.downcase)
end
def hook_attrs
@@ -1138,7 +1180,7 @@ class User < ActiveRecord::Base
events = Event.select(:project_id)
.contributions.where(author_id: self)
.where("created_at > ?", Time.now - 1.year)
- .uniq
+ .distinct
.reorder(nil)
Project.where(id: events)
@@ -1464,15 +1506,6 @@ class User < ActiveRecord::Base
end
end
- def generate_token(token_field)
- if token_field == :incoming_email_token
- # Needs to be all lowercase and alphanumeric because it's gonna be used in an email address.
- SecureRandom.hex.to_i(16).to_s(36)
- else
- super
- end
- end
-
def self.unique_internal(scope, username, email_pattern, &block)
scope.first || create_unique_internal(scope, username, email_pattern, &block)
end