2020-07-02 18:49:20 +02:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
const _ = require('lodash');
|
2021-09-20 18:50:48 +02:00
|
|
|
const { contentTypes: contentTypesUtils, sanitizeEntity } = require('@strapi/utils');
|
|
|
|
const { getService } = require('../utils');
|
|
|
|
const validateSettings = require('./validation/settings');
|
|
|
|
const validateUploadBody = require('./validation/upload');
|
2020-10-27 11:27:17 +01:00
|
|
|
|
2020-10-08 19:50:39 +02:00
|
|
|
const { CREATED_BY_ATTRIBUTE } = contentTypesUtils.constants;
|
2020-07-02 18:49:20 +02:00
|
|
|
|
|
|
|
const ACTIONS = {
|
2021-08-06 18:09:49 +02:00
|
|
|
read: 'plugin::upload.read',
|
|
|
|
readSettings: 'plugin::upload.settings.read',
|
|
|
|
create: 'plugin::upload.assets.create',
|
|
|
|
update: 'plugin::upload.assets.update',
|
|
|
|
download: 'plugin::upload.assets.download',
|
|
|
|
copyLink: 'plugin::upload.assets.copy-link',
|
2020-07-02 18:49:20 +02:00
|
|
|
};
|
|
|
|
|
2021-08-06 18:09:49 +02:00
|
|
|
const fileModel = 'plugin::upload.file';
|
2020-07-02 18:49:20 +02:00
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
async find(ctx) {
|
|
|
|
const {
|
|
|
|
state: { userAbility },
|
|
|
|
} = ctx;
|
|
|
|
|
2020-11-02 17:19:42 +01:00
|
|
|
const pm = strapi.admin.services.permission.createPermissionsManager({
|
|
|
|
ability: userAbility,
|
|
|
|
action: ACTIONS.read,
|
|
|
|
model: fileModel,
|
|
|
|
});
|
2020-07-02 18:49:20 +02:00
|
|
|
|
|
|
|
if (!pm.isAllowed) {
|
|
|
|
return ctx.forbidden();
|
|
|
|
}
|
|
|
|
|
2021-09-20 18:50:48 +02:00
|
|
|
const query = pm.addPermissionsQueryTo(ctx.query);
|
|
|
|
|
2021-07-28 21:03:32 +02:00
|
|
|
const files = await getService('upload').fetchAll(query);
|
2020-07-02 18:49:20 +02:00
|
|
|
|
2020-10-01 17:47:08 +02:00
|
|
|
ctx.body = pm.sanitize(files, { withPrivate: false });
|
2020-07-02 18:49:20 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
async findOne(ctx) {
|
|
|
|
const {
|
|
|
|
state: { userAbility },
|
|
|
|
params: { id },
|
|
|
|
} = ctx;
|
|
|
|
|
2020-07-06 16:25:25 +02:00
|
|
|
const { pm, file } = await findEntityAndCheckPermissions(
|
2020-07-02 18:49:20 +02:00
|
|
|
userAbility,
|
|
|
|
ACTIONS.read,
|
2020-07-06 16:25:25 +02:00
|
|
|
fileModel,
|
|
|
|
id
|
2020-07-02 18:49:20 +02:00
|
|
|
);
|
|
|
|
|
2020-10-01 17:47:08 +02:00
|
|
|
ctx.body = pm.sanitize(file, { withPrivate: false });
|
2020-07-02 18:49:20 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
async count(ctx) {
|
2020-11-02 17:19:42 +01:00
|
|
|
const pm = strapi.admin.services.permission.createPermissionsManager({
|
|
|
|
ability: ctx.state.userAbility,
|
|
|
|
action: ACTIONS.read,
|
|
|
|
model: fileModel,
|
|
|
|
});
|
2020-07-02 18:49:20 +02:00
|
|
|
|
|
|
|
if (!pm.isAllowed) {
|
|
|
|
return ctx.forbidden();
|
|
|
|
}
|
|
|
|
|
2021-09-20 18:50:48 +02:00
|
|
|
const query = pm.addPermissionsQueryTo(ctx.query);
|
2021-07-28 21:03:32 +02:00
|
|
|
const count = await getService('upload').count(query);
|
2020-07-02 18:49:20 +02:00
|
|
|
|
|
|
|
ctx.body = { count };
|
|
|
|
},
|
|
|
|
|
|
|
|
async destroy(ctx) {
|
|
|
|
const {
|
|
|
|
state: { userAbility },
|
|
|
|
params: { id },
|
|
|
|
} = ctx;
|
|
|
|
|
2020-07-06 16:25:25 +02:00
|
|
|
const { pm, file } = await findEntityAndCheckPermissions(
|
2020-07-02 18:49:20 +02:00
|
|
|
userAbility,
|
|
|
|
ACTIONS.update,
|
2020-07-06 16:25:25 +02:00
|
|
|
fileModel,
|
|
|
|
id
|
2020-07-02 18:49:20 +02:00
|
|
|
);
|
|
|
|
|
2021-08-19 22:27:00 +02:00
|
|
|
await getService('upload').remove(file);
|
2020-07-02 18:49:20 +02:00
|
|
|
|
2020-10-01 17:47:08 +02:00
|
|
|
ctx.body = pm.sanitize(file, { action: ACTIONS.read, withPrivate: false });
|
2020-07-02 18:49:20 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
async updateSettings(ctx) {
|
|
|
|
const {
|
|
|
|
request: { body },
|
|
|
|
state: { userAbility },
|
|
|
|
} = ctx;
|
|
|
|
|
2020-10-13 18:51:09 +02:00
|
|
|
if (userAbility.cannot(ACTIONS.readSettings, fileModel)) {
|
2020-07-02 18:49:20 +02:00
|
|
|
return ctx.forbidden();
|
|
|
|
}
|
|
|
|
|
|
|
|
const data = await validateSettings(body);
|
|
|
|
|
2021-07-08 22:07:52 +02:00
|
|
|
await getService('upload').setSettings(data);
|
2020-07-02 18:49:20 +02:00
|
|
|
|
|
|
|
ctx.body = { data };
|
|
|
|
},
|
|
|
|
|
|
|
|
async getSettings(ctx) {
|
|
|
|
const {
|
|
|
|
state: { userAbility },
|
|
|
|
} = ctx;
|
|
|
|
|
2020-07-06 16:25:25 +02:00
|
|
|
if (userAbility.cannot(ACTIONS.readSettings, fileModel)) {
|
2020-07-02 18:49:20 +02:00
|
|
|
return ctx.forbidden();
|
|
|
|
}
|
|
|
|
|
2021-07-08 22:07:52 +02:00
|
|
|
const data = await getService('upload').getSettings();
|
2020-07-02 18:49:20 +02:00
|
|
|
|
|
|
|
ctx.body = { data };
|
|
|
|
},
|
|
|
|
|
|
|
|
async updateFileInfo(ctx) {
|
|
|
|
const {
|
|
|
|
state: { userAbility, user },
|
|
|
|
query: { id },
|
|
|
|
request: { body },
|
|
|
|
} = ctx;
|
|
|
|
|
2021-07-08 22:07:52 +02:00
|
|
|
const uploadService = getService('upload');
|
2020-07-06 16:25:25 +02:00
|
|
|
const { pm } = await findEntityAndCheckPermissions(userAbility, ACTIONS.update, fileModel, id);
|
2020-07-02 18:49:20 +02:00
|
|
|
|
|
|
|
const data = await validateUploadBody(body);
|
2020-08-31 16:23:43 +02:00
|
|
|
const file = await uploadService.updateFileInfo(id, data.fileInfo, { user });
|
2020-07-02 18:49:20 +02:00
|
|
|
|
2020-10-01 17:47:08 +02:00
|
|
|
ctx.body = pm.sanitize(file, { action: ACTIONS.read, withPrivate: false });
|
2020-07-02 18:49:20 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
async replaceFile(ctx) {
|
|
|
|
const {
|
|
|
|
state: { userAbility, user },
|
|
|
|
query: { id },
|
|
|
|
request: { body, files: { files } = {} },
|
|
|
|
} = ctx;
|
|
|
|
|
2021-07-08 22:07:52 +02:00
|
|
|
const uploadService = getService('upload');
|
2020-07-06 16:25:25 +02:00
|
|
|
const { pm } = await findEntityAndCheckPermissions(userAbility, ACTIONS.update, fileModel, id);
|
2020-07-02 18:49:20 +02:00
|
|
|
|
|
|
|
if (Array.isArray(files)) {
|
|
|
|
throw strapi.errors.badRequest(null, {
|
|
|
|
errors: [
|
|
|
|
{ id: 'Upload.replace.single', message: 'Cannot replace a file with multiple ones' },
|
|
|
|
],
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
const data = await validateUploadBody(body);
|
2020-10-05 12:00:03 +02:00
|
|
|
const replacedFiles = await uploadService.replace(id, { data, file: files }, { user });
|
2020-07-02 18:49:20 +02:00
|
|
|
|
2020-10-01 17:47:08 +02:00
|
|
|
ctx.body = pm.sanitize(replacedFiles, { action: ACTIONS.read, withPrivate: false });
|
2020-07-02 18:49:20 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
async uploadFiles(ctx) {
|
|
|
|
const {
|
|
|
|
state: { userAbility, user },
|
|
|
|
request: { body, files: { files } = {} },
|
2020-07-02 19:18:33 +02:00
|
|
|
} = ctx;
|
2020-07-02 18:49:20 +02:00
|
|
|
|
2021-07-08 22:07:52 +02:00
|
|
|
const uploadService = getService('upload');
|
2020-11-02 17:19:42 +01:00
|
|
|
const pm = strapi.admin.services.permission.createPermissionsManager({
|
|
|
|
ability: userAbility,
|
|
|
|
action: ACTIONS.create,
|
|
|
|
model: fileModel,
|
|
|
|
});
|
2020-07-02 18:49:20 +02:00
|
|
|
|
|
|
|
if (!pm.isAllowed) {
|
|
|
|
throw strapi.errors.forbidden();
|
|
|
|
}
|
|
|
|
|
|
|
|
const data = await validateUploadBody(body);
|
2020-10-05 12:00:03 +02:00
|
|
|
const uploadedFiles = await uploadService.upload({ data, files }, { user });
|
2020-07-02 18:49:20 +02:00
|
|
|
|
2020-10-01 17:47:08 +02:00
|
|
|
ctx.body = pm.sanitize(uploadedFiles, { action: ACTIONS.read, withPrivate: false });
|
2020-07-02 18:49:20 +02:00
|
|
|
},
|
2021-09-20 18:50:48 +02:00
|
|
|
|
|
|
|
async upload(ctx) {
|
|
|
|
const {
|
|
|
|
query: { id },
|
|
|
|
request: { files: { files } = {} },
|
|
|
|
} = ctx;
|
|
|
|
|
|
|
|
if (id && (_.isEmpty(files) || files.size === 0)) {
|
|
|
|
return this.updateFileInfo(ctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_.isEmpty(files) || files.size === 0) {
|
|
|
|
throw strapi.errors.badRequest(null, {
|
|
|
|
errors: [{ id: 'Upload.status.empty', message: 'Files are empty' }],
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
await (id ? this.replaceFile : this.uploadFiles)(ctx);
|
|
|
|
},
|
|
|
|
|
|
|
|
async search(ctx) {
|
|
|
|
const { id } = ctx.params;
|
|
|
|
const model = strapi.getModel('plugin::upload.file');
|
|
|
|
const entries = await strapi.query('plugin::upload.file').findMany({
|
|
|
|
where: {
|
|
|
|
$or: [{ hash: { $contains: id } }, { name: { $contains: id } }],
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
ctx.body = sanitizeEntity(entries, { model });
|
|
|
|
},
|
2020-07-02 18:49:20 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
const findEntityAndCheckPermissions = async (ability, action, model, id) => {
|
2021-07-08 22:07:52 +02:00
|
|
|
const file = await getService('upload').findOne({ id }, [CREATED_BY_ATTRIBUTE]);
|
2021-07-08 21:53:30 +02:00
|
|
|
|
2020-07-02 18:49:20 +02:00
|
|
|
if (_.isNil(file)) {
|
|
|
|
throw strapi.errors.notFound();
|
|
|
|
}
|
|
|
|
|
2020-11-02 17:19:42 +01:00
|
|
|
const pm = strapi.admin.services.permission.createPermissionsManager({ ability, action, model });
|
2020-07-02 18:49:20 +02:00
|
|
|
|
2021-07-08 22:07:52 +02:00
|
|
|
const author = await strapi.admin.services.user.findOne({ id: file[CREATED_BY_ATTRIBUTE].id }, [
|
2021-06-17 12:00:02 +02:00
|
|
|
'roles',
|
|
|
|
]);
|
|
|
|
|
2021-09-22 17:04:57 +02:00
|
|
|
const fileWithRoles = _.set(_.cloneDeep(file), 'createdBy', author);
|
2020-07-06 16:25:25 +02:00
|
|
|
|
|
|
|
if (pm.ability.cannot(pm.action, pm.toSubject(fileWithRoles))) {
|
2020-07-02 18:49:20 +02:00
|
|
|
throw strapi.errors.forbidden();
|
|
|
|
}
|
|
|
|
|
2020-07-06 16:25:25 +02:00
|
|
|
return { pm, file };
|
2020-07-02 18:49:20 +02:00
|
|
|
};
|