| 
									
										
										
										
											2020-07-02 18:49:20 +02:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const _ = require('lodash'); | 
					
						
							| 
									
										
										
										
											2021-09-24 15:59:51 +02:00
										 |  |  | const { contentTypes: contentTypesUtils } = require('@strapi/utils'); | 
					
						
							| 
									
										
										
										
											2021-10-27 18:54:58 +02:00
										 |  |  | const { ApplicationError, NotFoundError, ForbiddenError } = require('@strapi/utils').errors; | 
					
						
							| 
									
										
										
										
											2021-09-20 18:50:48 +02:00
										 |  |  | 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-10-07 18:05:06 +02:00
										 |  |  |     const { results, pagination } = await getService('upload').findPage(query); | 
					
						
							| 
									
										
										
										
											2020-07-02 18:49:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-04 15:47:53 +01:00
										 |  |  |     const sanitizedResults = await pm.sanitizeOutput(results); | 
					
						
							| 
									
										
										
										
											2021-10-07 18:05:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return { results: sanitizedResults, pagination }; | 
					
						
							| 
									
										
										
										
											2020-07-02 18:49:20 +02:00
										 |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   async findOne(ctx) { | 
					
						
							|  |  |  |     const { | 
					
						
							|  |  |  |       state: { userAbility }, | 
					
						
							|  |  |  |       params: { id }, | 
					
						
							|  |  |  |     } = ctx; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-27 18:54:58 +02:00
										 |  |  |     const { pm, file } = await findEntityAndCheckPermissions( | 
					
						
							|  |  |  |       userAbility, | 
					
						
							|  |  |  |       ACTIONS.read, | 
					
						
							|  |  |  |       fileModel, | 
					
						
							|  |  |  |       id | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-04 15:47:53 +01:00
										 |  |  |     ctx.body = await pm.sanitizeOutput(file); | 
					
						
							| 
									
										
										
										
											2020-07-02 18:49:20 +02:00
										 |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   async destroy(ctx) { | 
					
						
							| 
									
										
										
										
											2021-10-07 09:24:04 +02:00
										 |  |  |     const { id } = ctx.params; | 
					
						
							|  |  |  |     const { userAbility } = ctx.state; | 
					
						
							| 
									
										
										
										
											2020-07-02 18:49:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-27 18:54:58 +02:00
										 |  |  |     const { pm, file } = await findEntityAndCheckPermissions( | 
					
						
							|  |  |  |       userAbility, | 
					
						
							|  |  |  |       ACTIONS.update, | 
					
						
							|  |  |  |       fileModel, | 
					
						
							|  |  |  |       id | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await getService('upload').remove(file); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-04 15:47:53 +01:00
										 |  |  |     ctx.body = await pm.sanitizeOutput(file, { action: ACTIONS.read }); | 
					
						
							| 
									
										
										
										
											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'); | 
					
						
							| 
									
										
										
										
											2021-10-27 18:54:58 +02:00
										 |  |  |     const { pm } = await findEntityAndCheckPermissions(userAbility, ACTIONS.update, fileModel, id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const data = await validateUploadBody(body); | 
					
						
							|  |  |  |     const file = await uploadService.updateFileInfo(id, data.fileInfo, { user }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-04 15:47:53 +01:00
										 |  |  |     ctx.body = await pm.sanitizeOutput(file, { action: ACTIONS.read }); | 
					
						
							| 
									
										
										
										
											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'); | 
					
						
							| 
									
										
										
										
											2021-10-27 18:54:58 +02:00
										 |  |  |     const { pm } = await findEntityAndCheckPermissions(userAbility, ACTIONS.update, fileModel, id); | 
					
						
							| 
									
										
										
										
											2020-07-02 18:49:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (Array.isArray(files)) { | 
					
						
							| 
									
										
										
										
											2021-10-20 17:30:05 +02:00
										 |  |  |       throw new ApplicationError('Cannot replace a file with multiple ones'); | 
					
						
							| 
									
										
										
										
											2020-07-02 18:49:20 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-04 15:47:53 +01:00
										 |  |  |     ctx.body = await pm.sanitizeOutput(replacedFiles, { action: ACTIONS.read }); | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2021-10-20 17:30:05 +02:00
										 |  |  |       return ctx.forbidden(); | 
					
						
							| 
									
										
										
										
											2020-07-02 18:49:20 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-04 15:47:53 +01:00
										 |  |  |     ctx.body = await pm.sanitizeOutput(uploadedFiles, { action: ACTIONS.read }); | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2021-10-20 17:30:05 +02:00
										 |  |  |       throw new ApplicationError('Files are empty'); | 
					
						
							| 
									
										
										
										
											2021-09-20 18:50:48 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await (id ? this.replaceFile : this.uploadFiles)(ctx); | 
					
						
							|  |  |  |   }, | 
					
						
							| 
									
										
										
										
											2020-07-02 18:49:20 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const findEntityAndCheckPermissions = async (ability, action, model, id) => { | 
					
						
							| 
									
										
										
										
											2021-09-24 15:40:02 +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)) { | 
					
						
							| 
									
										
										
										
											2021-10-20 17:30:05 +02:00
										 |  |  |     throw new NotFoundError(); | 
					
						
							| 
									
										
										
										
											2020-07-02 18:49:20 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-12-22 17:58:22 +09:00
										 |  |  |   const creatorId = _.get(file, [CREATED_BY_ATTRIBUTE, 'id']); | 
					
						
							|  |  |  |   const author = creatorId ? await strapi.admin.services.user.findOne(creatorId, ['roles']) : null; | 
					
						
							| 
									
										
										
										
											2021-06-17 12:00:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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))) { | 
					
						
							| 
									
										
										
										
											2021-10-20 17:30:05 +02:00
										 |  |  |     throw new ForbiddenError(); | 
					
						
							| 
									
										
										
										
											2020-07-02 18:49:20 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-06 16:25:25 +02:00
										 |  |  |   return { pm, file }; | 
					
						
							| 
									
										
										
										
											2020-07-02 18:49:20 +02:00
										 |  |  | }; |