mirror of
https://github.com/strapi/strapi.git
synced 2025-08-14 19:56:41 +00:00
fix(rw): check transition permission to change assignee (#21311)
This commit is contained in:
parent
53b11740f9
commit
6c96a733d0
@ -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) };
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -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],
|
||||||
});
|
});
|
||||||
|
@ -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'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user