FEATURE: Allow admins to delete user SSO records in the UI (#10669)
Also displays the user's last payload in the admin UI to help with debugging SSO issues.
This commit is contained in:
parent
6d7b8a71c0
commit
273db57d6e
|
@ -132,6 +132,11 @@ export default Controller.extend(CanCheckEmails, {
|
|||
.catch(() => bootbox.alert(I18n.t("generic_error")));
|
||||
},
|
||||
|
||||
@discourseComputed("model.single_sign_on_record.last_payload")
|
||||
ssoPayload(lastPayload) {
|
||||
return lastPayload.split("&");
|
||||
},
|
||||
|
||||
actions: {
|
||||
impersonate() {
|
||||
return this.model.impersonate();
|
||||
|
@ -321,5 +326,16 @@ export default Controller.extend(CanCheckEmails, {
|
|||
resetPrimaryGroup() {
|
||||
this.set("model.primary_group_id", this.originalPrimaryGroupId);
|
||||
},
|
||||
|
||||
deleteSSORecord() {
|
||||
return bootbox.confirm(
|
||||
I18n.t("admin.user.sso.confirm_delete"),
|
||||
I18n.t("no_value"),
|
||||
I18n.t("yes_value"),
|
||||
() => {
|
||||
return this.model.deleteSSORecord();
|
||||
}
|
||||
);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -567,6 +567,16 @@ const AdminUser = User.extend({
|
|||
_formatError(event) {
|
||||
return `http: ${event.status} - ${event.body}`;
|
||||
},
|
||||
|
||||
deleteSSORecord() {
|
||||
return ajax(`/admin/users/${this.id}/sso_record.json`, {
|
||||
type: "DELETE",
|
||||
})
|
||||
.then(() => {
|
||||
this.set("single_sign_on_record", null);
|
||||
})
|
||||
.catch(popupAjaxError);
|
||||
},
|
||||
});
|
||||
|
||||
AdminUser.reopenClass({
|
||||
|
|
|
@ -652,6 +652,16 @@
|
|||
<div class="display-row">
|
||||
<div class="field">{{i18n "admin.user.sso.external_id"}}</div>
|
||||
<div class="value">{{sso.external_id}}</div>
|
||||
{{#if model.can_delete_sso_record}}
|
||||
<div class="controls">
|
||||
{{d-button
|
||||
class="btn-danger"
|
||||
action=(action "deleteSSORecord")
|
||||
icon="far-trash-alt"
|
||||
label="admin.user.sso.delete_sso_record"
|
||||
}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="display-row">
|
||||
<div class="field">{{i18n "admin.user.sso.external_username"}}</div>
|
||||
|
@ -671,6 +681,16 @@
|
|||
<div class="field">{{i18n "admin.user.sso.external_avatar_url"}}</div>
|
||||
<div class="value">{{sso.external_avatar_url}}</div>
|
||||
</div>
|
||||
{{#if sso.last_payload}}
|
||||
<div class="display-row">
|
||||
<div class="field">{{i18n "admin.user.sso.last_payload"}}</div>
|
||||
<div class="value">
|
||||
{{#each ssoPayload as |line|}}
|
||||
{{line}}<br>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/with}}
|
||||
</section>
|
||||
{{/if}}
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
max-width: 350px;
|
||||
min-width: 50px;
|
||||
margin-left: 12px;
|
||||
word-break: break-word;
|
||||
.select-kit {
|
||||
min-width: 100px;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,8 @@ class Admin::UsersController < Admin::AdminController
|
|||
:merge,
|
||||
:reset_bounce_score,
|
||||
:disable_second_factor,
|
||||
:delete_posts_batch]
|
||||
:delete_posts_batch,
|
||||
:sso_record]
|
||||
|
||||
def index
|
||||
users = ::AdminUserIndexQuery.new(params).find_users
|
||||
|
@ -498,6 +499,12 @@ class Admin::UsersController < Admin::AdminController
|
|||
render json: success_json
|
||||
end
|
||||
|
||||
def sso_record
|
||||
guardian.ensure_can_delete_sso_record!(@user)
|
||||
@user.single_sign_on_record.destroy!
|
||||
render json: success_json
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def perform_post_action
|
||||
|
|
|
@ -31,6 +31,7 @@ class AdminDetailedUserSerializer < AdminUserSerializer
|
|||
:can_view_action_logs,
|
||||
:second_factor_enabled,
|
||||
:can_disable_second_factor,
|
||||
:can_delete_sso_record,
|
||||
:api_key_count
|
||||
|
||||
has_one :approved_by, serializer: BasicUserSerializer, embed: :objects
|
||||
|
@ -126,4 +127,8 @@ class AdminDetailedUserSerializer < AdminUserSerializer
|
|||
def api_key_count
|
||||
object.api_keys.active.count
|
||||
end
|
||||
|
||||
def can_delete_sso_record
|
||||
scope.can_delete_sso_record?(object)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4626,6 +4626,9 @@ en:
|
|||
external_name: "Name"
|
||||
external_email: "Email"
|
||||
external_avatar_url: "Profile Picture URL"
|
||||
last_payload: "Last Payload"
|
||||
delete_sso_record: "Delete SSO Record"
|
||||
confirm_delete: "Are you sure you would like to delete this single sign on (SSO) record?"
|
||||
|
||||
user_fields:
|
||||
title: "User Fields"
|
||||
|
|
|
@ -144,6 +144,7 @@ Discourse::Application.routes.draw do
|
|||
post "merge"
|
||||
post "reset_bounce_score"
|
||||
put "disable_second_factor"
|
||||
delete "sso_record"
|
||||
end
|
||||
get "users/:id.json" => 'users#show', defaults: { format: 'json' }
|
||||
get 'users/:id/:username' => 'users#show', constraints: { username: RouteFormat.username }
|
||||
|
|
|
@ -167,4 +167,7 @@ module UserGuardian
|
|||
(is_me?(user) && user.has_trust_level?(SiteSetting.min_trust_level_to_allow_user_card_background.to_i)) || is_staff?
|
||||
end
|
||||
|
||||
def can_delete_sso_record?(user)
|
||||
SiteSetting.enable_sso && user && is_admin?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1049,4 +1049,17 @@ RSpec.describe Admin::UsersController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#sso_record' do
|
||||
fab!(:sso_record) { SingleSignOnRecord.create!(user_id: user.id, external_id: '12345', external_email: user.email, last_payload: '') }
|
||||
|
||||
it "deletes the record" do
|
||||
SiteSetting.sso_url = "https://www.example.com/sso"
|
||||
SiteSetting.enable_sso = true
|
||||
|
||||
delete "/admin/users/#{user.id}/sso_record.json"
|
||||
expect(response.status).to eq(200)
|
||||
expect(user.single_sign_on_record).to eq(nil)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue