diff options
Diffstat (limited to 'app/models/user.rb')
-rw-r--r-- | app/models/user.rb | 112 |
1 files changed, 42 insertions, 70 deletions
diff --git a/app/models/user.rb b/app/models/user.rb index 80b8c9173d1..cb0f15c04cb 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -26,6 +26,7 @@ class User < ApplicationRecord include UpdateHighestRole include HasUserType include Gitlab::Auth::Otp::Fortinet + include RestrictedSignup DEFAULT_NOTIFICATION_LEVEL = :participating @@ -205,11 +206,14 @@ class User < ApplicationRecord has_one :user_canonical_email has_one :credit_card_validation, class_name: '::Users::CreditCardValidation' has_one :atlassian_identity, class_name: 'Atlassian::Identity' + has_one :banned_user, class_name: '::Users::BannedUser' has_many :reviews, foreign_key: :author_id, inverse_of: :author has_many :in_product_marketing_emails, class_name: '::Users::InProductMarketingEmail' + has_many :timelogs + # # Validations # @@ -220,7 +224,7 @@ class User < ApplicationRecord validates :email, confirmation: true validates :notification_email, presence: true validates :notification_email, devise_email: true, if: ->(user) { user.notification_email != user.email } - validates :public_email, presence: true, uniqueness: true, devise_email: true, allow_blank: true + validates :public_email, uniqueness: true, devise_email: true, allow_blank: true validates :commit_email, devise_email: true, allow_nil: true, if: ->(user) { user.commit_email != user.email } validates :projects_limit, presence: true, @@ -231,11 +235,10 @@ class User < ApplicationRecord validate :namespace_move_dir_allowed, if: :username_changed? validate :unique_email, if: :email_changed? - validate :owns_notification_email, if: :notification_email_changed? - validate :owns_public_email, if: :public_email_changed? - validate :owns_commit_email, if: :commit_email_changed? - validate :signup_domain_valid?, on: :create, if: ->(user) { !user.created_by_id } - validate :check_email_restrictions, on: :create, if: ->(user) { !user.created_by_id } + validate :notification_email_verified, if: :notification_email_changed? + validate :public_email_verified, if: :public_email_changed? + validate :commit_email_verified, if: :commit_email_changed? + validate :signup_email_valid?, on: :create, if: ->(user) { !user.created_by_id } validate :check_username_format, if: :username_changed? validates :theme_id, allow_nil: true, inclusion: { in: Gitlab::Themes.valid_ids, @@ -245,7 +248,6 @@ class User < ApplicationRecord message: _("%{placeholder} is not a valid color scheme") % { placeholder: '%{value}' } } before_validation :sanitize_attrs - before_validation :set_notification_email, if: :new_record? before_validation :set_public_email, if: :public_email_changed? before_validation :set_commit_email, if: :commit_email_changed? before_save :default_private_profile_to_false @@ -270,11 +272,6 @@ class User < ApplicationRecord update_emails_with_primary_email(previous_confirmed_at, previous_email) update_invalid_gpg_signatures - - if previous_email == notification_email - self.notification_email = email - save - end end end @@ -315,6 +312,7 @@ class User < ApplicationRecord delegate :bio, :bio=, :bio_html, to: :user_detail, allow_nil: true delegate :webauthn_xid, :webauthn_xid=, to: :user_detail, allow_nil: true delegate :pronouns, :pronouns=, to: :user_detail, allow_nil: true + delegate :pronunciation, :pronunciation=, to: :user_detail, allow_nil: true accepts_nested_attributes_for :user_preference, update_only: true accepts_nested_attributes_for :user_detail, update_only: true @@ -326,7 +324,6 @@ class User < ApplicationRecord transition deactivated: :blocked transition ldap_blocked: :blocked transition blocked_pending_approval: :blocked - transition banned: :blocked end event :ldap_block do @@ -380,6 +377,14 @@ class User < ApplicationRecord NotificationService.new.user_deactivated(user.name, user.notification_email) end # rubocop: enable CodeReuse/ServiceClass + + after_transition active: :banned do |user| + user.create_banned_user + end + + after_transition banned: :active do |user| + user.banned_user&.destroy + end end # Scopes @@ -917,22 +922,22 @@ class User < ApplicationRecord end end - def owns_notification_email - return if new_record? || temp_oauth_email? + def notification_email_verified + return if read_attribute(:notification_email).blank? || temp_oauth_email? - errors.add(:notification_email, _("is not an email you own")) unless verified_emails.include?(notification_email) + errors.add(:notification_email, _("must be an email you have verified")) unless verified_emails.include?(notification_email) end - def owns_public_email + def public_email_verified return if public_email.blank? - errors.add(:public_email, _("is not an email you own")) unless verified_emails.include?(public_email) + errors.add(:public_email, _("must be an email you have verified")) unless verified_emails.include?(public_email) end - def owns_commit_email + def commit_email_verified return if read_attribute(:commit_email).blank? - errors.add(:commit_email, _("is not an email you own")) unless verified_emails.include?(commit_email) + errors.add(:commit_email, _("must be an email you have verified")) unless verified_emails.include?(commit_email) end # Define commit_email-related attribute methods explicitly instead of relying @@ -959,6 +964,11 @@ class User < ApplicationRecord has_attribute?(:commit_email) && super end + def notification_email + # The notification email is the same as the primary email if undefined + super.presence || self.email + end + def private_commit_email Gitlab::PrivateCommitEmail.for_user(self) end @@ -1005,6 +1015,8 @@ class User < ApplicationRecord # Returns a relation of groups the user has access to, including their parent # and child groups (recursively). def all_expanded_groups + return groups if groups.empty? + Gitlab::ObjectHierarchy.new(groups).all_objects end @@ -1576,10 +1588,11 @@ class User < ApplicationRecord .order('routes.path') end - def namespaces - namespace_ids = groups.pluck(:id) - namespace_ids.push(namespace.id) - Namespace.where(id: namespace_ids) + def namespaces(owned_only: false) + user_groups = owned_only ? owned_groups : groups + personal_namespace = Namespace.where(id: namespace.id) + + Namespace.from_union([user_groups, personal_namespace]) end def oauth_authorized_tokens @@ -2008,8 +2021,8 @@ class User < ApplicationRecord def authorized_groups_without_shared_membership Group.from_union([ - groups, - authorized_projects.joins(:namespace).select('namespaces.*') + groups.select(Namespace.arel_table[Arel.star]), + authorized_projects.joins(:namespace).select(Namespace.arel_table[Arel.star]) ]) end @@ -2058,51 +2071,10 @@ class User < ApplicationRecord end end - def signup_domain_valid? - valid = true - error = nil - - 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_allowlist - unless allowed_domains.blank? - if domain_matches?(allowed_domains, email) - valid = true - else - error = "domain is not authorized for sign-up" - valid = false - end - end - - errors.add(:email, error) unless valid - - valid - end - - def domain_matches?(email_domains, email) - signup_domain = Mail::Address.new(email).domain - email_domains.any? do |domain| - escaped = Regexp.escape(domain).gsub('\*', '.*?') - regexp = Regexp.new "^#{escaped}$", Regexp::IGNORECASE - signup_domain =~ regexp - end - end + def signup_email_valid? + error = validate_admin_signup_restrictions(email) - def check_email_restrictions - return unless Gitlab::CurrentSettings.email_restrictions_enabled? - - restrictions = Gitlab::CurrentSettings.email_restrictions - return if restrictions.blank? - - if Gitlab::UntrustedRegexp.new(restrictions).match?(email) - errors.add(:email, _('is not allowed. Try again with a different email address, or contact your GitLab admin.')) - end + errors.add(:email, error) if error end def check_username_format |