FEATURE: API to update user's discourse connect external id (#19085)
* FEATURE: API to update user's discourse connect external id This adds a special handling of updates to DiscourseConnect external_id in the general user update API endpoint. Admins can create, update or delete a user SingleSignOn record using PUT /u/:username.json { "external_ids": { "discourse_connect": "new-external-id" } }
This commit is contained in:
parent
3ec7b2a769
commit
86bf46a24b
|
@ -168,6 +168,14 @@ class UsersController < ApplicationController
|
|||
attributes[:user_associated_accounts] = []
|
||||
|
||||
params[:external_ids].each do |provider_name, provider_uid|
|
||||
if provider_name == 'discourse_connect'
|
||||
raise Discourse::InvalidParameters.new(:external_ids) unless SiteSetting.enable_discourse_connect
|
||||
|
||||
attributes[:discourse_connect] = { external_id: provider_uid }
|
||||
|
||||
next
|
||||
end
|
||||
|
||||
authenticator = Discourse.enabled_authenticators.find { |a| a.name == provider_name }
|
||||
raise Discourse::InvalidParameters.new(:external_ids) if !authenticator&.is_managed?
|
||||
|
||||
|
|
|
@ -203,6 +203,10 @@ class UserUpdater
|
|||
update_allowed_pm_users(attributes[:allowed_pm_usernames])
|
||||
end
|
||||
|
||||
if attributes.key?(:discourse_connect)
|
||||
update_discourse_connect(attributes[:discourse_connect])
|
||||
end
|
||||
|
||||
if attributes.key?(:user_associated_accounts)
|
||||
updated_associated_accounts(attributes[:user_associated_accounts])
|
||||
end
|
||||
|
@ -354,6 +358,17 @@ class UserUpdater
|
|||
end
|
||||
end
|
||||
|
||||
def update_discourse_connect(discourse_connect)
|
||||
external_id = discourse_connect[:external_id]
|
||||
sso = SingleSignOnRecord.find_or_initialize_by(user_id: user.id)
|
||||
|
||||
if external_id.present?
|
||||
sso.update!(external_id: discourse_connect[:external_id], last_payload: "external_id=#{discourse_connect[:external_id]}")
|
||||
else
|
||||
sso.destroy!
|
||||
end
|
||||
end
|
||||
|
||||
attr_reader :user, :guardian
|
||||
|
||||
def format_url(website)
|
||||
|
|
|
@ -2426,6 +2426,8 @@ RSpec.describe UsersController do
|
|||
|
||||
before do
|
||||
DiscoursePluginRegistry.register_auth_provider(plugin_auth_provider)
|
||||
SiteSetting.discourse_connect_url = 'http://localhost'
|
||||
SiteSetting.enable_discourse_connect = true
|
||||
end
|
||||
|
||||
after do
|
||||
|
@ -2463,6 +2465,75 @@ RSpec.describe UsersController do
|
|||
expect(user.reload.user_associated_account_ids).to be_blank
|
||||
end
|
||||
|
||||
it 'can create SingleSignOnRecord records' do
|
||||
params = {
|
||||
external_ids: { discourse_connect: 'discourse_connect_uid' },
|
||||
}
|
||||
|
||||
expect { put "/u/#{user.username}.json", params: params, headers: { HTTP_API_KEY: api_key.key } }
|
||||
.to change { SingleSignOnRecord.count }.by(1)
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
single_sign_on_record = SingleSignOnRecord.last
|
||||
expect(user.reload.single_sign_on_record).to eq(single_sign_on_record)
|
||||
expect(single_sign_on_record.external_id).to eq('discourse_connect_uid')
|
||||
end
|
||||
|
||||
it 'can update SingleSignOnRecord records' do
|
||||
user = Fabricate(:user)
|
||||
SingleSignOnRecord.create!(user_id: user.id, external_id: 'discourse_connect_uid', last_payload: 'discourse_connect_uid')
|
||||
|
||||
params = {
|
||||
external_ids: { discourse_connect: 'discourse_connect_uid_2' },
|
||||
}
|
||||
|
||||
expect { put "/u/#{user.username}.json", params: params, headers: { HTTP_API_KEY: api_key.key } }
|
||||
.not_to change { SingleSignOnRecord.count }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(user.reload.single_sign_on_record.external_id).to eq('discourse_connect_uid_2')
|
||||
end
|
||||
|
||||
it 'can delete SingleSignOnRecord records' do
|
||||
user = Fabricate(:user)
|
||||
SingleSignOnRecord.create!(user_id: user.id, external_id: 'discourse_connect_uid', last_payload: 'discourse_connect_uid')
|
||||
|
||||
params = {
|
||||
external_ids: { discourse_connect: nil },
|
||||
}
|
||||
|
||||
expect { put "/u/#{user.username}.json", params: params, headers: { HTTP_API_KEY: api_key.key } }
|
||||
.to change { SingleSignOnRecord.count }.by(-1)
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(user.reload.single_sign_on_record).to be_blank
|
||||
end
|
||||
|
||||
it 'can update SingleSignOnRecord and UserAssociatedAccount records in a single call' do
|
||||
user = Fabricate(:user)
|
||||
user.user_associated_accounts.create!(provider_name: 'pluginauth', provider_uid: 'pluginauth_uid')
|
||||
SingleSignOnRecord.create!(user_id: user.id, external_id: 'discourse_connect_uid', last_payload: 'discourse_connect_uid')
|
||||
|
||||
params = {
|
||||
external_ids: {
|
||||
discourse_connect: 'discourse_connect_uid_2',
|
||||
pluginauth: 'pluginauth_uid_2'
|
||||
},
|
||||
}
|
||||
|
||||
expect { put "/u/#{user.username}.json", params: params, headers: { HTTP_API_KEY: api_key.key } }
|
||||
.to change { SingleSignOnRecord.count + UserAssociatedAccount.count }.by(0)
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(user.reload.single_sign_on_record.external_id).to eq('discourse_connect_uid_2')
|
||||
user_associated_account = UserAssociatedAccount.last
|
||||
expect(user.reload.user_associated_account_ids).to contain_exactly(user_associated_account.id)
|
||||
expect(user_associated_account.provider_name).to eq('pluginauth')
|
||||
expect(user_associated_account.provider_uid).to eq('pluginauth_uid_2')
|
||||
expect(user_associated_account.user_id).to eq(user.id)
|
||||
end
|
||||
|
||||
it 'returns error if external ID provider does not exist' do
|
||||
params = {
|
||||
external_ids: { 'pluginauth2' => 'pluginauth_uid' },
|
||||
|
|
Loading…
Reference in New Issue