diff options
Diffstat (limited to 'app/models/user.rb')
-rw-r--r-- | app/models/user.rb | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/app/models/user.rb b/app/models/user.rb index ef77e207215..be64e057d59 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -28,6 +28,8 @@ class User < ApplicationRecord DEFAULT_NOTIFICATION_LEVEL = :participating + INSTANCE_ACCESS_REQUEST_APPROVERS_TO_BE_NOTIFIED_LIMIT = 10 + add_authentication_token_field :incoming_email_token, token_generator: -> { SecureRandom.hex.to_i(16).to_s(36) } add_authentication_token_field :feed_token add_authentication_token_field :static_object_token @@ -341,6 +343,7 @@ class User < ApplicationRecord # Scopes scope :admins, -> { where(admin: true) } + scope :instance_access_request_approvers_to_be_notified, -> { admins.active.order_recent_sign_in.limit(INSTANCE_ACCESS_REQUEST_APPROVERS_TO_BE_NOTIFIED_LIMIT) } scope :blocked, -> { with_states(:blocked, :ldap_blocked) } scope :blocked_pending_approval, -> { with_states(:blocked_pending_approval) } scope :external, -> { where(external: true) } @@ -350,6 +353,9 @@ class User < ApplicationRecord scope :deactivated, -> { with_state(:deactivated).non_internal } scope :without_projects, -> { joins('LEFT JOIN project_authorizations ON users.id = project_authorizations.user_id').where(project_authorizations: { user_id: nil }) } scope :by_username, -> (usernames) { iwhere(username: Array(usernames).map(&:to_s)) } + scope :by_name, -> (names) { iwhere(name: Array(names)) } + scope :by_user_email, -> (emails) { iwhere(email: Array(emails)) } + scope :by_emails, -> (emails) { joins(:emails).where(emails: { email: Array(emails).map(&:downcase) }) } scope :for_todos, -> (todos) { where(id: todos.select(:user_id)) } scope :with_emails, -> { preload(:emails) } scope :with_dashboard, -> (dashboard) { where(dashboard: dashboard) } @@ -514,17 +520,15 @@ class User < ApplicationRecord # @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 = by_user_email(emails) from_users = from_users.confirmed if confirmed - from_emails = joins(:emails).where(emails: { email: emails }) + from_emails = by_emails(emails) from_emails = from_emails.confirmed.merge(Email.confirmed) if confirmed items = [from_users, from_emails] - user_ids = Gitlab::PrivateCommitEmail.user_ids_for_emails(emails) + user_ids = Gitlab::PrivateCommitEmail.user_ids_for_emails(Array(emails).map(&:downcase)) items << where(id: user_ids) if user_ids.present? from_union(items) @@ -909,10 +913,11 @@ class User < ApplicationRecord # Returns the groups a user has access to, either through a membership or a project authorization def authorized_groups Group.unscoped do - Group.from_union([ - groups, - authorized_projects.joins(:namespace).select('namespaces.*') - ]) + if Feature.enabled?(:shared_group_membership_auth, self) + authorized_groups_with_shared_membership + else + authorized_groups_without_shared_membership + end end end @@ -1807,6 +1812,26 @@ class User < ApplicationRecord private + def authorized_groups_without_shared_membership + Group.from_union([ + groups, + authorized_projects.joins(:namespace).select('namespaces.*') + ]) + end + + def authorized_groups_with_shared_membership + cte = Gitlab::SQL::CTE.new(:direct_groups, authorized_groups_without_shared_membership) + cte_alias = cte.table.alias(Group.table_name) + + Group + .with(cte.to_arel) + .from_union([ + Group.from(cte_alias), + Group.joins(:shared_with_group_links) + .where(group_group_links: { shared_with_group_id: Group.from(cte_alias) }) + ]) + end + def default_private_profile_to_false return unless private_profile_changed? && private_profile.nil? @@ -1843,15 +1868,15 @@ class User < ApplicationRecord valid = true error = nil - if Gitlab::CurrentSettings.domain_blacklist_enabled? - blocked_domains = Gitlab::CurrentSettings.domain_blacklist + if Gitlab::CurrentSettings.domain_denylist_enabled? + blocked_domains = Gitlab::CurrentSettings.domain_denylist if domain_matches?(blocked_domains, email) error = 'is not from an allowed domain.' valid = false end end - allowed_domains = Gitlab::CurrentSettings.domain_whitelist + allowed_domains = Gitlab::CurrentSettings.domain_allowlist unless allowed_domains.blank? if domain_matches?(allowed_domains, email) valid = true |