Merge pull request #5655 from sebgie/extract-permissions

Refactor handlePermissions
This commit is contained in:
Hannah Wolfe 2015-08-11 19:32:20 +01:00
commit 16407b41ee
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'),
@ -116,20 +115,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
@ -143,7 +128,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
];
@ -177,20 +162,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
@ -204,7 +175,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
];
@ -232,21 +203,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
@ -254,6 +210,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;
@ -264,7 +222,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

@ -573,7 +573,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'));
});
};