add action to check if the current logged-in user is allowed to perform actions on the selected user

This commit is contained in:
Jacob Overgaard
2024-04-02 16:47:52 +02:00
parent 7fe68649d7
commit 5bc8be81e3
5 changed files with 60 additions and 31 deletions

View File

@@ -4,32 +4,16 @@ import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
export const isCurrentUser = async (host: UmbControllerHost, userUnique: string) => {
const ctrl = new UmbContextConsumerController(host, UMB_CURRENT_USER_CONTEXT);
let currentUserContext = await ctrl.asPromise();
const currentUserContext = await ctrl.asPromise();
ctrl.destroy();
const controller = new UmbContextConsumerController(host, UMB_CURRENT_USER_CONTEXT, (context) => {
currentUserContext = context;
});
await controller.asPromise();
controller.destroy();
return currentUserContext!.isUserCurrentUser(userUnique);
};
export const isCurrentUserAnAdmin = async (host: UmbControllerHost) => {
const ctrl = new UmbContextConsumerController(host, UMB_CURRENT_USER_CONTEXT);
let currentUserContext = await ctrl.asPromise();
const currentUserContext = await ctrl.asPromise();
ctrl.destroy();
const controller = new UmbContextConsumerController(host, UMB_CURRENT_USER_CONTEXT, (context) => {
currentUserContext = context;
});
await controller.asPromise();
controller.destroy();
return currentUserContext!.isCurrentUserAdmin();
};

View File

@@ -3,6 +3,7 @@ import { manifest as userAllowEnableActionManifest } from './user-allow-enable-a
import { manifest as userAllowUnlockActionManifest } from './user-allow-unlock-action.condition.js';
import { manifest as userAllowMfaActionManifest } from './user-allow-mfa-action.condition.js';
import { manifest as userAllowDeleteActionManifest } from './user-allow-delete-action.condition.js';
import { manifest as userCanPerformActionsManifest } from './user-can-perform-actions.condition.js';
export const manifests = [
userAllowDisableActionManifest,
@@ -10,4 +11,5 @@ export const manifests = [
userAllowUnlockActionManifest,
userAllowMfaActionManifest,
userAllowDeleteActionManifest,
userCanPerformActionsManifest,
];

View File

@@ -1,3 +1,4 @@
import { isUserAdmin } from '../utils/index.js';
import type { UmbUserStateEnum } from '../types.js';
import { UMB_USER_WORKSPACE_CONTEXT } from '../workspace/user-workspace.context-token.js';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
@@ -56,10 +57,18 @@ export abstract class UmbUserActionConditionBase
* Check if the current user is an admin
* @protected
*/
protected async isCurrentUserAdmin() {
protected isCurrentUserAdmin() {
return isCurrentUserAnAdmin(this._host);
}
/**
* Check if the selected user is an admin
* @protected
*/
protected async isUserAdmin() {
return this.userUnique ? isUserAdmin(this._host, this.userUnique) : false;
}
/**
* Called when the user data changes
* @protected

View File

@@ -4,20 +4,10 @@ import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registr
export class UmbUserAllowMfaActionCondition extends UmbUserActionConditionBase {
async _onUserDataChange() {
const isCurrentUser = await this.isCurrentUser();
let isAdmin = false;
// If it's not the current user being clicked, we need to check if the current logged-in user is an admin
if (!isCurrentUser) {
isAdmin = await this.isCurrentUserAdmin();
}
const isCurrentUserOrAdmin = isCurrentUser || isAdmin;
// Check if there are any MFA providers available and if the user is allowed to use them
// Check if there are any MFA providers available
this.observe(
umbExtensionsRegistry.byType('mfaLoginProvider'),
(exts) => (this.permitted = isCurrentUserOrAdmin && exts.length > 0),
(exts) => (this.permitted = exts.length > 0),
'_userAllowMfaActionConditionProviders',
);
}

View File

@@ -0,0 +1,44 @@
import { UmbUserActionConditionBase } from './user-allow-action-base.condition.js';
import type { ManifestCondition } from '@umbraco-cms/backoffice/extension-api';
/**
* Condition that checks if the current user is allowed to perform actions on the selected user.
* The logic is generally laid out so that admins can perform actions on any user, while users can only perform actions on other users.
*/
export class UmbUserCanPerformActionsCondition extends UmbUserActionConditionBase {
async _onUserDataChange() {
// Must have selected a user
if (this.userUnique === undefined) {
this.permitted = false;
return;
}
// If the user is the current user, they can perform actions
if (await this.isCurrentUser()) {
this.permitted = true;
return;
}
// If the current user is an admin, they can perform actions on any user
if (await this.isCurrentUserAdmin()) {
this.permitted = true;
return;
}
// Otherwise, the current user can only perform actions on other users
if (await this.isUserAdmin()) {
this.permitted = false;
return;
}
// The current user seems to be able to perform actions on the selected user
this.permitted = true;
}
}
export const manifest: ManifestCondition = {
type: 'condition',
name: 'User Can Perform Actions Condition',
alias: 'Umb.Condition.User.CanPerformActions',
api: UmbUserCanPerformActionsCondition,
};