Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/member.rb')
-rw-r--r--app/models/member.rb67
1 files changed, 64 insertions, 3 deletions
diff --git a/app/models/member.rb b/app/models/member.rb
index 25dae518406..8bec64932b3 100644
--- a/app/models/member.rb
+++ b/app/models/member.rb
@@ -276,9 +276,11 @@ class Member < ApplicationRecord
after_create :send_invite, if: :invite?, unless: :importing?
after_create :create_notification_setting, unless: [:pending?, :importing?]
after_create :post_create_hook, unless: [:pending?, :importing?], if: :hook_prerequisites_met?
+ after_create :update_two_factor_requirement, unless: :invite?
after_update :post_update_hook, unless: [:pending?, :importing?], if: :hook_prerequisites_met?
after_destroy :destroy_notification_setting
after_destroy :post_destroy_hook, unless: :pending?, if: :hook_prerequisites_met?
+ after_destroy :update_two_factor_requirement, unless: :invite?
after_save :log_invitation_token_cleanup
after_commit :send_request, if: :request?, unless: :importing?, on: [:create]
@@ -286,6 +288,14 @@ class Member < ApplicationRecord
refresh_member_authorized_projects
end
+ after_create if: :update_organization_user? do
+ Organizations::OrganizationUser.upsert(
+ { organization_id: source.organization_id, user_id: user_id, access_level: :default },
+ unique_by: [:organization_id, :user_id],
+ on_duplicate: :skip # Do not change access_level, could make :owner :default
+ )
+ end
+
attribute :notification_level, default: -> { NotificationSetting.levels[:global] }
class << self
@@ -486,7 +496,10 @@ class Member < ApplicationRecord
strong_memoize(:highest_group_member) do
next unless user_id && source&.ancestors&.any?
- GroupMember.where(source: source.ancestors, user_id: user_id).order(:access_level).last
+ GroupMember
+ .where(source: source.ancestors, user_id: user_id)
+ .non_request
+ .order(:access_level).last
end
end
@@ -498,6 +511,17 @@ class Member < ApplicationRecord
created_by&.name
end
+ def update_two_factor_requirement
+ return unless source.is_a?(Group)
+ return unless user
+
+ Gitlab::Database::QueryAnalyzers::PreventCrossDatabaseModification.temporary_ignore_tables_in_transaction(
+ %w[users user_details user_preferences], url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/424288'
+ ) do
+ user.update_two_factor_requirement
+ end
+ end
+
private
# TODO: https://gitlab.com/groups/gitlab-org/-/epics/7054
@@ -513,7 +537,7 @@ class Member < ApplicationRecord
end
def send_invite
- # override in subclass
+ run_after_commit_or_now { notification_service.invite_member(self, @raw_invite_token) }
end
def send_request
@@ -522,10 +546,26 @@ class Member < ApplicationRecord
end
def post_create_hook
+ # The creator of a personal project gets added as a `ProjectMember`
+ # with `OWNER` access during creation of a personal project,
+ # but we do not want to trigger notifications to the same person who created the personal project.
+ unless source.is_a?(Project) && source.personal_namespace_holder?(user)
+ event_service.join_source(source, user)
+ run_after_commit_or_now { notification_service.new_member(self) }
+ end
+
system_hook_service.execute_hooks_for(self, :create)
end
def post_update_hook
+ if saved_change_to_access_level?
+ run_after_commit { notification_service.updated_member_access_level(self) }
+ end
+
+ if saved_change_to_expires_at?
+ run_after_commit { notification_service.updated_member_expiration(self) }
+ end
+
system_hook_service.execute_hooks_for(self, :update)
end
@@ -548,6 +588,12 @@ class Member < ApplicationRecord
# rubocop: enable CodeReuse/ServiceClass
def after_accept_invite
+ run_after_commit_or_now do
+ notification_service.accept_invite(self)
+ end
+
+ update_two_factor_requirement
+
post_create_hook
end
@@ -578,7 +624,12 @@ class Member < ApplicationRecord
# rubocop: enable CodeReuse/ServiceClass
def notifiable_options
- {}
+ case source
+ when Group
+ { group: source }
+ when Project
+ { project: source }
+ end
end
def higher_access_level_than_group
@@ -617,12 +668,22 @@ class Member < ApplicationRecord
user&.project_bot?
end
+ def update_organization_user?
+ return false unless Feature.enabled?(:update_organization_users, source.root_ancestor, type: :gitlab_com_derisk)
+
+ !invite? && source.organization.present?
+ end
+
def log_invitation_token_cleanup
return true unless Gitlab.com? && invite? && invite_accepted_at?
error = StandardError.new("Invitation token is present but invite was already accepted!")
Gitlab::ErrorTracking.track_exception(error, attributes.slice(%w["invite_accepted_at created_at source_type source_id user_id id"]))
end
+
+ def event_service
+ EventCreateService.new # rubocop:todo CodeReuse/ServiceClass -- Legacy, convert to value object eventually
+ end
end
Member.prepend_mod_with('Member')