mirror of
https://github.com/discourse/discourse.git
synced 2025-05-28 13:51:18 +08:00
FEATURE: API to create user's associated account (#15737)
Discourse users and associated accounts are created or updated when a user logins or connects the account using their account preferences. This new API can be used to create associated accounts and users too, if necessary.
This commit is contained in:
@ -159,6 +159,17 @@ class UsersController < ApplicationController
|
||||
end
|
||||
end
|
||||
|
||||
if params[:external_ids]&.is_a?(ActionController::Parameters) && current_user&.admin? && is_api?
|
||||
attributes[:user_associated_accounts] = []
|
||||
|
||||
params[:external_ids].each do |provider_name, provider_uid|
|
||||
authenticator = Discourse.enabled_authenticators.find { |a| a.name == provider_name }
|
||||
raise Discourse::InvalidParameters.new(:external_ids) if !authenticator&.is_managed?
|
||||
|
||||
attributes[:user_associated_accounts] << { provider_name: provider_name, provider_uid: provider_uid }
|
||||
end
|
||||
end
|
||||
|
||||
json_result(user, serializer: UserSerializer, additional_errors: [:user_profile, :user_option]) do |u|
|
||||
updater = UserUpdater.new(current_user, user)
|
||||
updater.update(attributes.permit!)
|
||||
@ -632,6 +643,7 @@ class UsersController < ApplicationController
|
||||
params.require(:username)
|
||||
params.require(:invite_code) if SiteSetting.require_invite_code
|
||||
params.permit(:user_fields)
|
||||
params.permit(:external_ids)
|
||||
|
||||
unless SiteSetting.allow_new_registrations
|
||||
return fail_with("login.new_registrations_disabled")
|
||||
@ -691,6 +703,18 @@ class UsersController < ApplicationController
|
||||
user.custom_fields = fields
|
||||
end
|
||||
|
||||
# Handle associated accounts
|
||||
associations = []
|
||||
if params[:external_ids]&.is_a?(ActionController::Parameters) && current_user&.admin? && is_api?
|
||||
params[:external_ids].each do |provider_name, provider_uid|
|
||||
authenticator = Discourse.enabled_authenticators.find { |a| a.name == provider_name }
|
||||
raise Discourse::InvalidParameters.new(:external_ids) if !authenticator&.is_managed?
|
||||
|
||||
association = UserAssociatedAccount.find_or_initialize_by(provider_name: provider_name, provider_uid: provider_uid)
|
||||
associations << association
|
||||
end
|
||||
end
|
||||
|
||||
authentication = UserAuthenticator.new(user, session)
|
||||
|
||||
if !authentication.has_authenticator? && !SiteSetting.enable_local_logins && !(current_user&.admin? && is_api?)
|
||||
@ -709,11 +733,12 @@ class UsersController < ApplicationController
|
||||
|
||||
# just assign a password if we have an authenticator and no password
|
||||
# this is the case for Twitter
|
||||
user.password = SecureRandom.hex if user.password.blank? && authentication.has_authenticator?
|
||||
user.password = SecureRandom.hex if user.password.blank? && (authentication.has_authenticator? || associations.present?)
|
||||
|
||||
if user.save
|
||||
authentication.finish
|
||||
activation.finish
|
||||
associations.each { |a| a.update!(user: user) }
|
||||
user.update_timezone_if_missing(params[:timezone])
|
||||
|
||||
secure_session[HONEYPOT_KEY] = nil
|
||||
|
Reference in New Issue
Block a user