0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-04-15 03:01:37 -05:00

Refactor handlePermissions

no issue
- extract handlePermissions to utils
- added NoPermissionError when canThis() rejects
- omitted users.js because it uses special permission handling
This commit is contained in:
Sebastian Gierlinger 2015-08-11 16:03:57 +02:00
parent 026e3de597
commit 44622d943d
9 changed files with 56 additions and 128 deletions

View file

@ -3,7 +3,6 @@
var Promise = require('bluebird'),
_ = require('lodash'),
dataProvider = require('../models'),
canThis = require('../permissions').canThis,
errors = require('../errors'),
utils = require('./utils'),
pipeline = require('../utils/pipeline'),
@ -113,20 +112,6 @@ posts = {
edit: function edit(object, options) {
var tasks;
/**
* ### Handle Permissions
* We need to be an authorised user to perform this action
* @param {Object} options
* @returns {Object} options
*/
function handlePermissions(options) {
return canThis(options.context).edit.post(options.id).then(function permissionGranted() {
return options;
}).catch(function handleError(error) {
return errors.handleAPIError(error, 'You do not have permission to edit posts.');
});
}
/**
* ### Model Query
* Make the call to the Model layer
@ -140,7 +125,7 @@ posts = {
// Push all of our tasks into a `tasks` array in the correct order
tasks = [
utils.validate(docName, {opts: utils.idDefaultOptions}),
handlePermissions,
utils.handlePermissions(docName, 'edit'),
utils.convertOptions(allowedIncludes),
modelQuery
];
@ -174,20 +159,6 @@ posts = {
add: function add(object, options) {
var tasks;
/**
* ### Handle Permissions
* We need to be an authorised user to perform this action
* @param {Object} options
* @returns {Object} options
*/
function handlePermissions(options) {
return canThis(options.context).add.post().then(function permissionGranted() {
return options;
}).catch(function () {
return Promise.reject(new errors.NoPermissionError('You do not have permission to add posts.'));
});
}
/**
* ### Model Query
* Make the call to the Model layer
@ -201,7 +172,7 @@ posts = {
// Push all of our tasks into a `tasks` array in the correct order
tasks = [
utils.validate(docName),
handlePermissions,
utils.handlePermissions(docName, 'add'),
utils.convertOptions(allowedIncludes),
modelQuery
];
@ -229,21 +200,6 @@ posts = {
destroy: function destroy(options) {
var tasks;
/**
* ### Handle Permissions
* We need to be an authorised user to perform this action
* @param {Object} options
* @returns {Object} options
*/
function handlePermissions(options) {
return canThis(options.context).destroy.post(options.id).then(function permissionGranted() {
options.status = 'all';
return options;
}).catch(function handleError(error) {
return errors.handleAPIError(error, 'You do not have permission to remove posts.');
});
}
/**
* ### Model Query
* Make the call to the Model layer
@ -251,6 +207,8 @@ posts = {
* @returns {Object} options
*/
function modelQuery(options) {
// Removing a post needs to include all posts.
options.status = 'all';
return posts.read(options).then(function (result) {
return dataProvider.Post.destroy(options).then(function () {
return result;
@ -261,7 +219,7 @@ posts = {
// Push all of our tasks into a `tasks` array in the correct order
tasks = [
utils.validate(docName, {opts: utils.idDefaultOptions}),
handlePermissions,
utils.handlePermissions(docName, 'destroy'),
utils.convertOptions(allowedIncludes),
modelQuery
];

View file

@ -3,7 +3,6 @@
var Promise = require('bluebird'),
canThis = require('../permissions').canThis,
dataProvider = require('../models'),
errors = require('../errors'),
pipeline = require('../utils/pipeline'),
utils = require('./utils'),
docName = 'roles',
@ -33,20 +32,6 @@ roles = {
var permittedOptions = ['permissions'],
tasks;
/**
* ### Handle Permissions
* We need to be an authorised user.
* @param {Object} options
* @returns {Object} options
*/
function handlePermissions(options) {
return canThis(options.context).browse.role().then(function () {
return options;
}).catch(function handleError(error) {
return errors.handleAPIError(error, 'You do not have permission to browse roles.');
});
}
/**
* ### Model Query
* Make the call to the Model layer
@ -60,7 +45,7 @@ roles = {
// Push all of our tasks into a `tasks` array in the correct order
tasks = [
utils.validate(docName, {opts: permittedOptions}),
handlePermissions,
utils.handlePermissions(docName, 'browse'),
modelQuery
];

View file

@ -1,7 +1,6 @@
// # Slug API
// RESTful API for the Slug resource
var canThis = require('../permissions').canThis,
dataProvider = require('../models'),
var dataProvider = require('../models'),
errors = require('../errors'),
Promise = require('bluebird'),
pipeline = require('../utils/pipeline'),
@ -39,20 +38,16 @@ slugs = {
};
/**
* ### Handle Permissions
* We need to be an authorized user and use an allowedType
* ### Check allowed types
* check if options.type contains an allowed type
* @param {Object} options
* @returns {Object} options
*/
function handlePermissions(options) {
return canThis(options.context).generate.slug().then(function () {
if (allowedTypes[options.type] === undefined) {
return Promise.reject(new errors.BadRequestError('Unknown slug type \'' + options.type + '\'.'));
}
return options;
}).catch(function handleError(error) {
return errors.handleAPIError(error, 'You do not have permission to generate a slug.');
});
function checkAllowedTypes(options) {
if (allowedTypes[options.type] === undefined) {
return Promise.reject(new errors.BadRequestError('Unknown slug type \'' + options.type + '\'.'));
}
return options;
}
/**
@ -68,7 +63,8 @@ slugs = {
// Push all of our tasks into a `tasks` array in the correct order
tasks = [
utils.validate(docName, {opts: opts, attrs: attrs}),
handlePermissions,
utils.handlePermissions(docName, 'generate'),
checkAllowedTypes,
modelQuery
];

View file

@ -2,7 +2,6 @@
// RESTful API for the Tag resource
var Promise = require('bluebird'),
_ = require('lodash'),
canThis = require('../permissions').canThis,
dataProvider = require('../models'),
errors = require('../errors'),
utils = require('./utils'),
@ -93,20 +92,6 @@ tags = {
add: function add(object, options) {
var tasks;
/**
* ### Handle Permissions
* We need to be an authorised user to perform this action
* @param {Object} options
* @returns {Object} options
*/
function handlePermissions(options) {
return canThis(options.context).add.tag(options.data).then(function permissionGranted() {
return options;
}).catch(function handleError(error) {
return errors.handleAPIError(error, 'You do not have permission to add tags.');
});
}
/**
* ### Model Query
* Make the call to the Model layer
@ -120,7 +105,7 @@ tags = {
// Push all of our tasks into a `tasks` array in the correct order
tasks = [
utils.validate(docName),
handlePermissions,
utils.handlePermissions(docName, 'add'),
utils.convertOptions(allowedIncludes),
doQuery
];
@ -144,20 +129,6 @@ tags = {
edit: function edit(object, options) {
var tasks;
/**
* ### Handle Permissions
* We need to be an authorised user to perform this action
* @param {Object} options
* @returns {Object} options
*/
function handlePermissions(options) {
return canThis(options.context).edit.tag(options.id).then(function permissionGranted() {
return options;
}).catch(function handleError(error) {
return errors.handleAPIError(error, 'You do not have permission to edit tags.');
});
}
/**
* Make the call to the Model layer
* @param {Object} options
@ -170,7 +141,7 @@ tags = {
// Push all of our tasks into a `tasks` array in the correct order
tasks = [
utils.validate(docName, {opts: utils.idDefaultOptions}),
handlePermissions,
utils.handlePermissions(docName, 'edit'),
utils.convertOptions(allowedIncludes),
doQuery
];
@ -197,20 +168,6 @@ tags = {
destroy: function destroy(options) {
var tasks;
/**
* ### Handle Permissions
* We need to be an authorised user to perform this action
* @param {Object} options
* @returns {Object} options
*/
function handlePermissions(options) {
return canThis(options.context).destroy.tag(options.id).then(function permissionGranted() {
return options;
}).catch(function handleError(error) {
return errors.handleAPIError(error, 'You do not have permission to remove tags.');
});
}
/**
* ### Model Query
* Make the call to the Model layer
@ -228,7 +185,7 @@ tags = {
// Push all of our tasks into a `tasks` array in the correct order
tasks = [
utils.validate(docName, {opts: utils.idDefaultOptions}),
handlePermissions,
utils.handlePermissions(docName, 'destroy'),
utils.convertOptions(allowedIncludes),
doQuery
];

View file

@ -185,6 +185,37 @@ utils = {
};
},
/**
* ## Handle Permissions
* @param {String} docName
* @param {String} method (browse || read || edit || add || destroy)
* @returns {Function}
*/
handlePermissions: function handlePermissions(docName, method) {
var singular = docName.replace(/s$/, '');
/**
* ### Handle Permissions
* We need to be an authorised user to perform this action
* @param {Object} options
* @returns {Object} options
*/
return function doHandlePermissions(options) {
var permsPromise = permissions.canThis(options.context)[method][singular](options.id);
return permsPromise.then(function permissionGranted() {
return options;
}).catch(errors.NoPermissionError, function handleNoPermissionError(error) {
// pimp error message
error.message = 'You do not have permission to ' + method + ' ' + docName;
// forward error to next catch()
return Promise.reject(error);
}).catch(function handleError(error) {
return errors.handleAPIError(error);
});
};
},
prepareInclude: function prepareInclude(include, allowedIncludes) {
include = include || '';
include = _.intersection(include.split(','), allowedIncludes);

View file

@ -556,7 +556,7 @@ Post = ghostBookshelf.Model.extend({
return Promise.resolve();
}
return Promise.reject();
return Promise.reject(new errors.NoPermissionError('You do not have permission to perform this action'));
}
});

View file

@ -75,7 +75,7 @@ Role = ghostBookshelf.Model.extend({
return Promise.resolve();
}
return Promise.reject();
return Promise.reject(new errors.NoPermissionError('You do not have permission to perform this action'));
}
});

View file

@ -489,7 +489,7 @@ User = ghostBookshelf.Model.extend({
if (action === 'destroy') {
// Owner cannot be deleted EVER
if (userModel.hasRole('Owner')) {
return Promise.reject();
return Promise.reject(new errors.NoPermissionError('You do not have permission to perform this action'));
}
// Users with the role 'Editor' have complex permissions when the action === 'destroy'
@ -506,7 +506,7 @@ User = ghostBookshelf.Model.extend({
return Promise.resolve();
}
return Promise.reject();
return Promise.reject(new errors.NoPermissionError('You do not have permission to perform this action'));
},
setWarning: function setWarning(user, options) {

View file

@ -3,6 +3,7 @@
var _ = require('lodash'),
Promise = require('bluebird'),
errors = require('../errors'),
Models = require('../models'),
effectivePerms = require('./effective'),
init,
@ -194,7 +195,7 @@ CanThisResult.prototype.buildObjectTypeHandlers = function (objTypes, actType, c
return;
}
return Promise.reject();
return Promise.reject(new errors.NoPermissionError('You do not have permission to perform this action'));
});
};