Skip to content

Instantly share code, notes, and snippets.

@8byr0
Last active June 26, 2020 16:00
Show Gist options
  • Save 8byr0/5a2be7d104ae43474eecfa19a00ad87f to your computer and use it in GitHub Desktop.
Save 8byr0/5a2be7d104ae43474eecfa19a00ad87f to your computer and use it in GitHub Desktop.
Is Owner policy for strapi HTTP (Not working with graphql). Freely inspired from https://github.com/strapi/strapi/issues/624#issuecomment-558666801
'use strict';
/**
* `isowner` policy.
*/
const pluralize = require('pluralize');
module.exports = async (ctx, next) => {
try {
const errMsg = 'You are not allowed to perform this action.';
// Fetch User data
const { id: userId } = await strapi.plugins['users-permissions'].services.jwt.getToken(ctx);
const { owner } = await strapi.query('user', 'users-permissions').findOne({ id: userId }, []);
const ownerId = owner.toString();
if (typeof ownerId === 'undefined' || ownerId === null) {
return ctx.unauthorized(`${errMsg} [1]`);
}
let error = null;
switch (ctx.request.method) {
case 'GET': {
console.log('GET');
error = await lifecycleHandlers.get(ctx, ownerId);
break;
}
case 'DELETE':
case 'PUT': {
console.log('DELETE, PUT');
error = await lifecycleHandlers.update(ctx, ownerId);
break;
}
case 'POST': {
console.log('POST');
error = await lifecycleHandlers.create(ctx, owner);
break;
}
}
if (error) {
console.log('an error occured', error);
return error;
}
await next();
if (ctx.request.method === 'GET') {
if (Object.prototype.toString.call(ctx.response.body) === '[object Object]') {
// Extract model name from request path eg. /messages/15
const modelName = ctx.request.path.match(/^\/(.*)\/\b\w{1,24}.*$/);
if (Array.isArray(modelName) === false || modelName.length !== 2 || modelName[1] === '') {
return ctx.unauthorized(`Invalid request ${ctx.request.path}`);
}
// Get existing entity and check for ownership
const existingEntity = await strapi.query(pluralize.singular(modelName[1])).findOne({
id: ctx.params.id,
});
if (typeof existingEntity === 'undefined' || existingEntity === null) {
return ctx.notFound('Not Found');
}
if (
typeof existingEntity.owner === 'undefined' ||
existingEntity.owner === null ||
typeof existingEntity.owner.id === 'undefined' ||
existingEntity.owner.id === null ||
existingEntity.owner.id.toString() !== ownerId.toString()
) {
return ctx.notFound('Not found');
}
}
}
} catch (error) {
console.log('error', error);
return ctx.unauthorized(error);
}
};
const lifecycleHandlers = {
async get(ctx, ownerId) {
for (const key in ctx.query) {
if (key.includes('owner')) {
delete ctx.query[key];
}
}
// Reset owner.id to current user id
ctx.query = Object.assign({ 'owner.id': ownerId }, ctx.query);
},
async create(ctx, ownerId) {
console.log(ctx.request.body);
if (!ctx.request.body) {
ctx.request.body = {};
}
ctx.request.body.owner = ownerId.toString();
},
/**
*
* @param {KoaContext} ctx
* @param {string} ownerId
*/
async update(ctx, ownerId) {
if (
!(
typeof ctx.params !== 'undefined' &&
ctx.params !== null &&
typeof ctx.params.id !== 'undefined' &&
ctx.params.id !== null &&
ctx.params.id !== ''
)
) {
return ctx.unauthorized('You are not allowed to perform this action [2]');
}
// Extract model name from request path eg. /messages/15
const modelName = ctx.request.path.match(/^\/(.*)\/\b\w{1,24}.*$/);
if (Array.isArray(modelName) === false || modelName.length !== 2 || modelName[1] === '') {
return ctx.unauthorized('You are not allowed to perform this action [2]');
}
// Get existing entity and check for ownership
const existingEntity = await strapi.query(pluralize.singular(modelName[1])).findOne({
id: ctx.params.id,
});
if (typeof existingEntity === 'undefined' || existingEntity === null) {
return ctx.notFound('Not Found');
}
if (
typeof existingEntity.owner === 'undefined' ||
existingEntity.owner === null ||
typeof existingEntity.owner.id === 'undefined' ||
existingEntity.owner.id === null ||
existingEntity.owner.id.toString() !== ownerId.toString()
) {
return ctx.unauthorized('$[2]');
}
// Set owner to current user
ctx.request.body.owner = ownerId;
},
async delete() {
return this.update();
},
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment