implement document user permission condition

This commit is contained in:
Mads Rasmussen
2024-04-06 22:38:41 +02:00
parent 8dc6c706d7
commit 9fd36fa334
7 changed files with 104 additions and 50 deletions

View File

@@ -0,0 +1,91 @@
import { UMB_ENTITY_CONTEXT } from '@umbraco-cms/backoffice/entity';
import { UMB_CURRENT_USER_CONTEXT } from '../../../user/current-user/current-user.context.js';
import { isDocumentUserPermission } from './utils.js';
import { observeMultiple } from '@umbraco-cms/backoffice/observable-api';
import { UmbConditionBase } from '@umbraco-cms/backoffice/extension-registry';
import type {
ManifestCondition,
UmbConditionConfigBase,
UmbConditionControllerArguments,
UmbExtensionCondition,
} from '@umbraco-cms/backoffice/extension-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import type { DocumentPermissionPresentationModel } from '@umbraco-cms/backoffice/external/backend-api';
export class UmbDocumentUserPermissionCondition
extends UmbConditionBase<UmbDocumentUserPermissionConditionConfig>
implements UmbExtensionCondition
{
#entityType: string | undefined;
#unique: string | null | undefined;
#documentPermissions: Array<DocumentPermissionPresentationModel> = [];
#fallbackPermissions: string[] = [];
constructor(
host: UmbControllerHost,
args: UmbConditionControllerArguments<UmbDocumentUserPermissionConditionConfig>,
) {
super(host, args);
this.consumeContext(UMB_CURRENT_USER_CONTEXT, (context) => {
this.observe(
context.currentUser,
(currentUser) => {
this.#documentPermissions = currentUser?.permissions?.filter(isDocumentUserPermission) || [];
this.#fallbackPermissions = currentUser?.fallbackPermissions || [];
this.#isAllowed();
},
'umbUserPermissionConditionObserver',
);
});
this.consumeContext(UMB_ENTITY_CONTEXT, (context) => {
if (!context) return;
this.observe(
observeMultiple([context.entityType, context.unique]),
([entityType, unique]) => {
this.#entityType = entityType;
this.#unique = unique;
this.#isAllowed();
},
'umbUserPermissionEntityContextObserver',
);
});
}
#isAllowed() {
if (!this.#entityType) return;
if (this.#unique === undefined) return;
let verbs: Array<string> = [];
if (this.#documentPermissions) {
const permissionsForCurrentDocument = this.#documentPermissions.find(
(permission) => permission.document.id === this.#unique,
);
const currentDocumentVerbs = permissionsForCurrentDocument ? permissionsForCurrentDocument.verbs : [];
verbs = this.#fallbackPermissions.concat(currentDocumentVerbs);
}
this.permitted = verbs.includes(this.config.match);
}
}
export type UmbDocumentUserPermissionConditionConfig =
UmbConditionConfigBase<'Umb.Condition.UserPermission.Document'> & {
/**
*
*
* @example
* "Umb.Document.Create"
*/
match: string;
};
export const manifest: ManifestCondition = {
type: 'condition',
name: 'Document User Permission Condition',
alias: 'Umb.Condition.UserPermission.Document',
api: UmbDocumentUserPermissionCondition,
};

View File

@@ -17,6 +17,7 @@ import {
UMB_USER_PERMISSION_DOCUMENT_ROLLBACK,
} from './constants.js';
import { manifests as repositoryManifests } from './repository/manifests.js';
import { manifest as conditionManifest } from './document-user-permission.condition.js';
import type {
ManifestGranularUserPermission,
ManifestEntityUserPermission,
@@ -211,4 +212,4 @@ export const granularPermissions: Array<ManifestGranularUserPermission> = [
},
];
export const manifests = [...repositoryManifests, ...permissions, ...granularPermissions];
export const manifests = [...repositoryManifests, ...permissions, ...granularPermissions, conditionManifest];

View File

@@ -0,0 +1,10 @@
import type {
DocumentPermissionPresentationModel,
UnknownTypePermissionPresentationModel,
} from '@umbraco-cms/backoffice/external/backend-api';
export function isDocumentUserPermission(
permission: DocumentPermissionPresentationModel | UnknownTypePermissionPresentationModel,
): permission is DocumentPermissionPresentationModel {
return (permission as DocumentPermissionPresentationModel).$type === 'DocumentPermissionPresentationModel';
}

View File

@@ -1 +0,0 @@
export * from './user-permission.condition.js';

View File

@@ -1,45 +0,0 @@
import { UMB_CURRENT_USER_CONTEXT } from '../../current-user/current-user.context.js';
import { UmbConditionBase } from '@umbraco-cms/backoffice/extension-registry';
import type {
ManifestCondition,
UmbConditionConfigBase,
UmbConditionControllerArguments,
UmbExtensionCondition,
} from '@umbraco-cms/backoffice/extension-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
export class UmbUserPermissionCondition
extends UmbConditionBase<UserPermissionConditionConfig>
implements UmbExtensionCondition
{
constructor(host: UmbControllerHost, args: UmbConditionControllerArguments<UserPermissionConditionConfig>) {
super(host, args);
this.consumeContext(UMB_CURRENT_USER_CONTEXT, (context) => {
this.observe(
context.currentUser,
(currentUser) => {
//this.permitted = currentUser?.permissions?.includes(this.config.match) || false;
},
'umbUserPermissionConditionObserver',
);
});
}
}
export type UserPermissionConditionConfig = UmbConditionConfigBase<'Umb.Condition.UserPermission'> & {
/**
*
*
* @example
* "Umb.UserPermission.Document.Create"
*/
match: string;
};
export const manifest: ManifestCondition = {
type: 'condition',
name: 'User Permission Condition',
alias: 'Umb.Condition.UserPermission',
api: UmbUserPermissionCondition,
};

View File

@@ -1,4 +1,3 @@
export * from './components/index.js';
export * from './conditions/index.js';
export type { UmbUserPermissionModel } from './types.js';

View File

@@ -1,4 +1,3 @@
import { manifest as userPermissionConditionManifest } from './conditions/user-permission.condition.js';
import { manifests as userPermissionModalManifests } from './modals/manifests.js';
export const manifests = [userPermissionConditionManifest, ...userPermissionModalManifests];
export const manifests = [...userPermissionModalManifests];