refactor: mark uid as a prohibited field & separate auto-clone route (#16957)

Co-authored-by: Josh <37798644+joshuaellis@users.noreply.github.com>
This commit is contained in:
Marc 2023-06-09 11:24:03 +02:00 committed by Josh
parent 0f5668e16e
commit 674dc96b89
5 changed files with 34 additions and 12 deletions

View File

@ -921,7 +921,7 @@ describe('Relations', () => {
});
describe('Clone entity with relations', () => {
test('Clone entity with relations', async () => {
test('Auto cloning entity with relations should fail', async () => {
const createdShop = await createEntry(
'shop',
{
@ -943,7 +943,7 @@ describe('Relations', () => {
// Clone with empty data
const res = await rq({
method: 'POST',
url: `/content-manager/collection-types/api::shop.shop/clone/${createdShop.id}`,
url: `/content-manager/collection-types/api::shop.shop/auto-clone/${createdShop.id}`,
body: {},
});

View File

@ -53,7 +53,7 @@ export const TableRows = ({
const handleCloneClick = (id) => async () => {
try {
const { data } = await post(
`/content-manager/collection-types/${contentType.uid}/clone/${id}?${pluginsQueryParams}`
`/content-manager/collection-types/${contentType.uid}/auto-clone/${id}?${pluginsQueryParams}`
);
if ('id' in data) {

View File

@ -1,7 +1,6 @@
'use strict';
const { setCreatorFields, pipeAsync } = require('@strapi/utils');
const { isEmpty } = require('lodash/fp');
const { ApplicationError } = require('@strapi/utils').errors;
const { getService, pickWritableAttributes } = require('../utils');
@ -165,14 +164,6 @@ module.exports = {
return ctx.forbidden();
}
// Trying to automatically clone the entity
// and model has unique or relational fields
if (isEmpty(body) && hasProhibitedCloningFields(model)) {
throw new ApplicationError(
'Entity could not be cloned as it has unique and/or relational fields. Please edit those fields manually and save to complete the cloning.'
);
}
const entity = await entityManager.findOneWithCreatorRoles(id, model);
if (!entity) {
@ -198,6 +189,20 @@ module.exports = {
ctx.body = await permissionChecker.sanitizeOutput(clonedEntity);
},
async autoClone(ctx) {
const { model } = ctx.params;
// Trying to automatically clone the entity and model has unique or relational fields
if (hasProhibitedCloningFields(model)) {
throw new ApplicationError(
'Entity could not be cloned as it has unique and/or relational fields. ' +
'Please edit those fields manually and save to complete the cloning.'
);
}
this.clone(ctx);
},
async delete(ctx) {
const { userAbility } = ctx.state;
const { id, model } = ctx.params;

View File

@ -29,6 +29,8 @@ const hasProhibitedCloningFields = (uid) => {
return (attribute.components || []).some((componentUID) =>
hasProhibitedCloningFields(componentUID)
);
case 'uid':
return true;
default:
return attribute?.unique ?? false;
}

View File

@ -246,6 +246,21 @@ module.exports = {
],
},
},
{
method: 'POST',
path: '/collection-types/:model/auto-clone/:sourceId',
handler: 'collection-types.autoClone',
config: {
middlewares: [routing],
policies: [
'admin::isAuthenticatedAdmin',
{
name: 'plugin::content-manager.hasPermissions',
config: { actions: ['plugin::content-manager.explorer.create'] },
},
],
},
},
{
method: 'GET',
path: '/collection-types/:model/:id',