mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-03 23:00:14 -05:00
Added /roles/ API endpoint
Closes #3196 * adds `/roles/` endpoint * is given the current user as context * wraps everything in a canthis.browse.role * gets all the available roles (should "Owner" be filtered out?) * optional parameter: `permission=assign`. Gets all roles authenticated user could assign * if we're not signed in, gives a "please sign in" (standard) error * if we're signed in, but user is not in the context, gives a "there was no user in the context" error * if the user is an "Author", gives a "there are no available roles to assign" error * implemented hacky filter because when.js produces heisenbugs past 3.2.3 (when.filter not available) * added extra fixtures to `permissions.json`. Might need a migration. Caveats: * there are no tests * for some reason the setup functional test was failing for me locally
This commit is contained in:
parent
4c276603ec
commit
80f9023020
5 changed files with 128 additions and 5 deletions
|
@ -12,6 +12,7 @@ var _ = require('lodash'),
|
|||
mail = require('./mail'),
|
||||
notifications = require('./notifications'),
|
||||
posts = require('./posts'),
|
||||
roles = require('./roles'),
|
||||
settings = require('./settings'),
|
||||
tags = require('./tags'),
|
||||
themes = require('./themes'),
|
||||
|
@ -280,6 +281,7 @@ module.exports = {
|
|||
mail: mail,
|
||||
notifications: notifications,
|
||||
posts: posts,
|
||||
roles: roles,
|
||||
settings: settings,
|
||||
tags: tags,
|
||||
themes: themes,
|
||||
|
|
60
core/server/api/roles.js
Normal file
60
core/server/api/roles.js
Normal file
|
@ -0,0 +1,60 @@
|
|||
// # Posts API
|
||||
// RESTful API for the Post resource
|
||||
var when = require('when'),
|
||||
_ = require('lodash'),
|
||||
canThis = require('../permissions').canThis,
|
||||
dataProvider = require('../models'),
|
||||
errors = require('../errors'),
|
||||
|
||||
roles;
|
||||
|
||||
/**
|
||||
* ## Roles API Methods
|
||||
*
|
||||
* **See:** [API Methods](index.js.html#api%20methods)
|
||||
*/
|
||||
roles = {
|
||||
/**
|
||||
* ### Browse
|
||||
* Find all roles
|
||||
*
|
||||
* Will return all roles that the current user is able to assign
|
||||
*
|
||||
*
|
||||
* @public
|
||||
* @param {{context, page, limit, status, staticPages, tag}} options (optional)
|
||||
* @returns {Promise(Roles)} Roles Collection
|
||||
*/
|
||||
browse: function browse(options) {
|
||||
var permissionMap = [];
|
||||
options = options || {};
|
||||
|
||||
return canThis(options.context).browse.role().then(function () {
|
||||
return dataProvider.Role.findAll(options).then(function (foundRoles) {
|
||||
if (options.permissions === 'assign') {
|
||||
// Hacky implementation of filtering because when.filter is only available in when 3.4.0,
|
||||
// but that's buggy and kills other tests and introduces Heisenbugs. Until we turn everything
|
||||
// to Bluebird, this works. Sorry.
|
||||
// TODO: replace with better filter when bluebird lands
|
||||
_.each(foundRoles.toJSON(), function (role) {
|
||||
permissionMap.push(canThis(options.context).assign.role(role).then(function () {
|
||||
return role;
|
||||
}, function () {
|
||||
return null;
|
||||
}));
|
||||
});
|
||||
|
||||
return when.all(permissionMap).then(function (resolved) {
|
||||
return { roles: _.filter(resolved, function (role) {
|
||||
return role !== null;
|
||||
}) };
|
||||
}).catch(errors.logAndThrowError);
|
||||
}
|
||||
return { roles: foundRoles.toJSON() };
|
||||
});
|
||||
})
|
||||
.catch(errors.logAndThrowError);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = roles;
|
|
@ -129,6 +129,16 @@
|
|||
"name": "Delete users",
|
||||
"action_type": "destroy"
|
||||
}
|
||||
],
|
||||
"role": [
|
||||
{
|
||||
"name": "Assign a role",
|
||||
"action_type": "assign"
|
||||
},
|
||||
{
|
||||
"name": "Browse roles",
|
||||
"action_type": "browse"
|
||||
}
|
||||
]
|
||||
},
|
||||
"permissions_roles": {
|
||||
|
@ -141,22 +151,26 @@
|
|||
"slug": "all",
|
||||
"tag": "all",
|
||||
"theme": "all",
|
||||
"user": "all"
|
||||
"user": "all",
|
||||
"role": "all"
|
||||
},
|
||||
"Editor": {
|
||||
"post": "all",
|
||||
"setting": ["browse", "read"],
|
||||
"slug": "all",
|
||||
"tag": "all",
|
||||
"user": "all"
|
||||
|
||||
"user": "all",
|
||||
"setting": ["browse", "read"],
|
||||
"role": "all"
|
||||
},
|
||||
"Author": {
|
||||
"post": ["browse", "read", "add"],
|
||||
"setting": ["browse", "read"],
|
||||
"slug": "all",
|
||||
"tag": ["browse", "read", "add"],
|
||||
"user": ["browse", "read"]
|
||||
"user": ["browse", "read"],
|
||||
"setting": ["browse", "read"],
|
||||
"role": ["browse"]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,7 @@
|
|||
var ghostBookshelf = require('./base'),
|
||||
var _ = require('lodash'),
|
||||
errors = require('../errors'),
|
||||
ghostBookshelf = require('./base'),
|
||||
when = require('when'),
|
||||
|
||||
Role,
|
||||
Roles;
|
||||
|
@ -34,6 +37,47 @@ Role = ghostBookshelf.Model.extend({
|
|||
}
|
||||
|
||||
return options;
|
||||
},
|
||||
|
||||
|
||||
permissable: function (roleModelOrId, context, loadedPermissions, hasUserPermission, hasAppPermission) {
|
||||
var self = this,
|
||||
checkAgainst = [],
|
||||
origArgs;
|
||||
|
||||
// If we passed in an id instead of a model, get the model
|
||||
// then check the permissions
|
||||
if (_.isNumber(roleModelOrId) || _.isString(roleModelOrId)) {
|
||||
// Grab the original args without the first one
|
||||
origArgs = _.toArray(arguments).slice(1);
|
||||
// Get the actual post model
|
||||
return this.findOne({id: roleModelOrId, status: 'all'}).then(function (foundRoleModel) {
|
||||
// Build up the original args but substitute with actual model
|
||||
var newArgs = [foundRoleModel].concat(origArgs);
|
||||
|
||||
return self.permissable.apply(self, newArgs);
|
||||
}, errors.logAndThrowError);
|
||||
}
|
||||
|
||||
switch (loadedPermissions.user) {
|
||||
case 'Owner':
|
||||
case 'Administrator':
|
||||
checkAgainst = ['Administrator', 'Editor', 'Author'];
|
||||
break;
|
||||
case 'Editor':
|
||||
checkAgainst = ['Editor', 'Author'];
|
||||
}
|
||||
|
||||
// If we have a role passed into here
|
||||
if (roleModelOrId && !_.contains(checkAgainst, roleModelOrId.get('name'))) {
|
||||
// Role not in the list of permissible roles
|
||||
hasUserPermission = false;
|
||||
}
|
||||
|
||||
if (hasUserPermission && hasAppPermission) {
|
||||
return when.resolve();
|
||||
}
|
||||
return when.reject();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -34,6 +34,9 @@ apiRoutes = function (middleware) {
|
|||
// ## Tags
|
||||
router.get('/tags', api.http(api.tags.browse));
|
||||
|
||||
// ## Roles
|
||||
router.get('/roles/', api.http(api.roles.browse));
|
||||
|
||||
// ## Slugs
|
||||
router.get('/slugs/:type/:name', api.http(api.slugs.generate));
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue