0
Fork 0
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:
Gabor Javorszky 2014-07-15 16:22:06 +01:00
parent 4c276603ec
commit 80f9023020
5 changed files with 128 additions and 5 deletions

View file

@ -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
View 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;

View file

@ -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"]
}
}
}

View file

@ -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();
}
});

View file

@ -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));