fix(rw): check transition permission to change assignee (#21311)

This commit is contained in:
Rémi de Juvigny 2024-09-17 10:59:03 -04:00 committed by GitHub
parent 53b11740f9
commit 6c96a733d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 28 additions and 7 deletions

View File

@ -2,6 +2,7 @@ import type { Context } from 'koa';
import { getService } from '../utils'; import { getService } from '../utils';
import { validateUpdateAssigneeOnEntity, validateLocale } from '../validation/review-workflows'; import { validateUpdateAssigneeOnEntity, validateLocale } from '../validation/review-workflows';
import { ENTITY_STAGE_ATTRIBUTE, STAGE_TRANSITION_UID } from '../constants/workflows';
export default { export default {
/** /**
@ -20,31 +21,52 @@ export default {
async updateEntity(ctx: Context) { async updateEntity(ctx: Context) {
const assigneeService = getService('assignees'); const assigneeService = getService('assignees');
const workflowService = getService('workflows'); const workflowService = getService('workflows');
const stagePermissions = getService('stage-permissions');
const { model_uid: model, id: documentId } = ctx.params; const { model_uid: model, id: documentId } = ctx.params;
const { locale } = ctx.request.query || {}; const locale = (await validateLocale(ctx.request.query?.locale)) ?? undefined;
const { sanitizeOutput } = strapi const { sanitizeOutput } = strapi
.plugin('content-manager') .plugin('content-manager')
.service('permission-checker') .service('permission-checker')
.create({ userAbility: ctx.state.userAbility, model }); .create({ userAbility: ctx.state.userAbility, model });
// Retrieve the entity so we can get its current stage
const entity = await strapi.documents(model).findOne({
documentId,
locale,
populate: [ENTITY_STAGE_ATTRIBUTE],
});
if (!entity) {
ctx.throw(404, 'Entity not found');
}
// Only allow users who can update the current stage to change the assignee
const canTransitionStage = stagePermissions.can(
STAGE_TRANSITION_UID,
entity[ENTITY_STAGE_ATTRIBUTE]?.id
);
if (!canTransitionStage) {
ctx.throw(403, 'Stage transition permission is required');
}
// TODO: check if user has update permission on the entity // TODO: check if user has update permission on the entity
const { id: assigneeId } = await validateUpdateAssigneeOnEntity( const { id: assigneeId } = await validateUpdateAssigneeOnEntity(
ctx.request?.body?.data, ctx.request?.body?.data,
'You should pass a valid id to the body of the put request.' 'You should pass a valid id to the body of the put request.'
); );
await validateLocale(locale);
await workflowService.assertContentTypeBelongsToWorkflow(model); await workflowService.assertContentTypeBelongsToWorkflow(model);
const entity = await assigneeService.updateEntityAssignee( const updatedEntity = await assigneeService.updateEntityAssignee(
documentId, documentId,
locale || null, locale || null,
model, model,
assigneeId assigneeId
); );
ctx.body = { data: await sanitizeOutput(entity) }; ctx.body = { data: await sanitizeOutput(updatedEntity) };
}, },
}; };

View File

@ -159,10 +159,9 @@ export default {
} }
// Load entity // Load entity
const locale = await validateLocale(query?.locale); const locale = (await validateLocale(query?.locale)) ?? undefined;
const entity = await strapi.documents(modelUID).findOne({ const entity = await strapi.documents(modelUID).findOne({
documentId, documentId,
// @ts-expect-error - locale should be also null in the doc service types
locale, locale,
populate: [ENTITY_STAGE_ATTRIBUTE], populate: [ENTITY_STAGE_ATTRIBUTE],
}); });

View File

@ -135,7 +135,7 @@ export default {
{ {
name: 'admin::hasPermissions', name: 'admin::hasPermissions',
config: { config: {
actions: ['admin::users.read', 'admin::review-workflows.read'], actions: ['admin::users.read'],
}, },
}, },
], ],