diff --git a/packages/core/content-manager/server/controllers/relations.js b/packages/core/content-manager/server/controllers/relations.js index 082adadb8a..dba671432e 100644 --- a/packages/core/content-manager/server/controllers/relations.js +++ b/packages/core/content-manager/server/controllers/relations.js @@ -6,15 +6,16 @@ const { hasDraftAndPublish } = require('@strapi/utils').contentTypes; const { PUBLISHED_AT_ATTRIBUTE } = require('@strapi/utils').contentTypes.constants; const { getService } = require('../utils'); -const { validateFindNew } = require('./validation/relations'); +const { validateFindAvailable } = require('./validation/relations'); module.exports = { - async findNew(ctx) { + async findAvailable(ctx) { + const { userAbility } = ctx.state; const { model, targetField } = ctx.params; - await validateFindNew(ctx.request.query); + await validateFindAvailable(ctx.request.query); - const { component, entityId, idsToOmit, page = 1, pageSize = 10, q } = ctx.request.query; + const { component, entityId, idsToOmit, page = 1, pageSize = 10, _q } = ctx.request.query; const sourceModelUid = component || model; @@ -23,6 +24,29 @@ module.exports = { return ctx.badRequest("The model doesn't exist"); } + // permission check + if (entityId) { + const entityManager = getService('entity-manager'); + const permissionChecker = getService('permission-checker').create({ + userAbility, + model: sourceModel, + }); + + if (permissionChecker.cannot.read()) { + return ctx.forbidden(); + } + + const entity = await entityManager.findOneWithCreatorRoles(entityId, model); + + if (!entity) { + return ctx.notFound(); + } + + if (permissionChecker.cannot.read(entity)) { + return ctx.forbidden(); + } + } + const attribute = sourceModel.attributes[targetField]; if (!attribute || attribute.type !== 'relation') { return ctx.badRequest("This relational field doesn't exist"); @@ -40,8 +64,8 @@ module.exports = { const query = strapi.db.queryBuilder(targetedModel.uid); - if (!isNil(q)) { - query.search(q); + if (!isNil(_q)) { + query.search(_q); } if (!isNil(ctx.request.query.filters)) { diff --git a/packages/core/content-manager/server/controllers/validation/relations.js b/packages/core/content-manager/server/controllers/validation/relations.js index 29630dd6d4..cf5372d5a8 100644 --- a/packages/core/content-manager/server/controllers/validation/relations.js +++ b/packages/core/content-manager/server/controllers/validation/relations.js @@ -2,12 +2,12 @@ const { yup, validateYupSchema } = require('@strapi/utils'); -const validateFindNewSchema = yup +const validateFindAvailableSchema = yup .object() .shape({ component: yup.string(), entityId: yup.strapiID(), - q: yup.string(), + _q: yup.string(), idsToOmit: yup.array().of(yup.strapiID()), page: yup .number() @@ -23,5 +23,5 @@ const validateFindNewSchema = yup .required(); module.exports = { - validateFindNew: validateYupSchema(validateFindNewSchema, { strict: false }), + validateFindAvailable: validateYupSchema(validateFindAvailableSchema, { strict: false }), }; diff --git a/packages/core/content-manager/server/routes/admin.js b/packages/core/content-manager/server/routes/admin.js index 5d891761b4..deac3c7015 100644 --- a/packages/core/content-manager/server/routes/admin.js +++ b/packages/core/content-manager/server/routes/admin.js @@ -82,7 +82,7 @@ module.exports = { { method: 'GET', path: '/relations/:model/:targetField', - handler: 'relations.findNew', + handler: 'relations.findAvailable', config: { policies: [ 'admin::isAuthenticatedAdmin', diff --git a/packages/core/content-manager/server/tests/relations-dp.test.e2e.js b/packages/core/content-manager/server/tests/relations-dp.test.e2e.js index 84581e9f82..94421deeee 100644 --- a/packages/core/content-manager/server/tests/relations-dp.test.e2e.js +++ b/packages/core/content-manager/server/tests/relations-dp.test.e2e.js @@ -112,7 +112,7 @@ describe('Relations with Draft & Publish', () => { await builder.cleanup(); }); - describe('findNew', () => { + describe('findAvailable', () => { test('relation not in a component && no entity', async () => { let res = await rq({ method: 'GET', diff --git a/packages/core/content-manager/server/tests/relations.test.e2e.js b/packages/core/content-manager/server/tests/relations.test.e2e.js index 56057c19ab..0278e7c2ef 100644 --- a/packages/core/content-manager/server/tests/relations.test.e2e.js +++ b/packages/core/content-manager/server/tests/relations.test.e2e.js @@ -106,7 +106,7 @@ describe('Relations', () => { await builder.cleanup(); }); - describe('findNew', () => { + describe('findAvailable', () => { test('relation not in a component && no entity', async () => { let res = await rq({ method: 'GET', diff --git a/packages/plugins/i18n/server/register.js b/packages/plugins/i18n/server/register.js index 372c02dd07..20e47d8474 100644 --- a/packages/plugins/i18n/server/register.js +++ b/packages/plugins/i18n/server/register.js @@ -22,9 +22,9 @@ const decorateRelations = () => { const { wrapParams } = getService('entity-service-decorator'); strapi.container.get('controllers').extend('plugin::content-manager.relations', controller => { - const oldFindNew = controller.findNew; + const oldFindAvailable = controller.findAvailable; return Object.assign(controller, { - async findNew(ctx, next) { + async findAvailable(ctx, next) { const { model, targetField } = ctx.params; const { component } = ctx.request.query; @@ -48,7 +48,7 @@ const decorateRelations = () => { ctx.request.query = await wrapParams(ctx.request.query); } - return oldFindNew(ctx, next); + return oldFindAvailable(ctx, next); }, }); });