feat: update users on SAML setup and destroy [CW-2958][CW-5612] (#12346)
This commit is contained in:
@@ -17,6 +17,7 @@ class SamlUserBuilder
|
||||
user = User.from_email(auth_attribute('email'))
|
||||
|
||||
if user
|
||||
confirm_user_if_required(user)
|
||||
convert_existing_user_to_saml(user)
|
||||
return user
|
||||
end
|
||||
@@ -24,6 +25,13 @@ class SamlUserBuilder
|
||||
create_user
|
||||
end
|
||||
|
||||
def confirm_user_if_required(user)
|
||||
return if user.confirmed?
|
||||
|
||||
user.skip_confirmation!
|
||||
user.save!
|
||||
end
|
||||
|
||||
def convert_existing_user_to_saml(user)
|
||||
return if user.provider == 'saml'
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
class Saml::UpdateAccountUsersProviderJob < ApplicationJob
|
||||
queue_as :default
|
||||
|
||||
# Updates the authentication provider for users in an account
|
||||
# This job is triggered when SAML settings are created or destroyed
|
||||
def perform(account_id, provider)
|
||||
account = Account.find(account_id)
|
||||
account.users.find_each(batch_size: 1000) do |user|
|
||||
next unless should_update_user_provider?(user, provider)
|
||||
|
||||
# rubocop:disable Rails/SkipsModelValidations
|
||||
user.update_column(:provider, provider)
|
||||
# rubocop:enable Rails/SkipsModelValidations
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Determines if a user's provider should be updated based on their multi-account status
|
||||
# When resetting to 'email', only update users who don't have SAML enabled on other accounts
|
||||
# This prevents breaking SAML authentication for users who belong to multiple accounts
|
||||
def should_update_user_provider?(user, provider)
|
||||
return !user_has_other_saml_accounts?(user) if provider == 'email'
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
# Checks if the user belongs to any other accounts that have SAML configured
|
||||
# Used to preserve SAML authentication when one account disables SAML but others still use it
|
||||
def user_has_other_saml_accounts?(user)
|
||||
user.accounts.joins(:saml_settings).exists?
|
||||
end
|
||||
end
|
||||
@@ -27,6 +27,9 @@ class AccountSamlSettings < ApplicationRecord
|
||||
|
||||
before_validation :set_sp_entity_id, if: :sp_entity_id_needs_generation?
|
||||
|
||||
after_create_commit :update_account_users_provider
|
||||
after_destroy_commit :reset_account_users_provider
|
||||
|
||||
def saml_enabled?
|
||||
sso_url.present? && certificate.present?
|
||||
end
|
||||
@@ -58,6 +61,14 @@ class AccountSamlSettings < ApplicationRecord
|
||||
GlobalConfigService.load('INSTALLATION_NAME', 'Chatwoot')
|
||||
end
|
||||
|
||||
def update_account_users_provider
|
||||
Saml::UpdateAccountUsersProviderJob.perform_later(account_id, 'saml')
|
||||
end
|
||||
|
||||
def reset_account_users_provider
|
||||
Saml::UpdateAccountUsersProviderJob.perform_later(account_id, 'email')
|
||||
end
|
||||
|
||||
def certificate_must_be_valid_x509
|
||||
return if certificate.blank?
|
||||
|
||||
|
||||
Reference in New Issue
Block a user