Ghost/core/server/services/permissions/providers.js
Fabien O'Carroll fc73cd71bb Updated permissions service to handle api keys (#9967)
refs #9865

- Enabled the permissions module to lookup permissions based on an api_key id.
- Updated the "can this" part of the permissions service to load permissions for any api key in the context, and correctly use that to determine whether an action is permissible. It also updates the permissible interface that models can implement to pass in the hasApiKeyPermissions param.
2019-01-18 11:17:11 +00:00

76 lines
2.8 KiB
JavaScript

var _ = require('lodash'),
Promise = require('bluebird'),
models = require('../../models'),
common = require('../../lib/common');
module.exports = {
user: function (id) {
return models.User.findOne({id: id, status: 'all'}, {withRelated: ['permissions', 'roles', 'roles.permissions']})
.then(function (foundUser) {
// CASE: {context: {user: id}} where the id is not in our database
if (!foundUser) {
return Promise.reject(new common.errors.NotFoundError({
message: common.i18n.t('errors.models.user.userNotFound')
}));
}
var seenPerms = {},
rolePerms = _.map(foundUser.related('roles').models, function (role) {
return role.related('permissions').models;
}),
allPerms = [],
user = foundUser.toJSON();
rolePerms.push(foundUser.related('permissions').models);
_.each(rolePerms, function (rolePermGroup) {
_.each(rolePermGroup, function (perm) {
var key = perm.get('action_type') + '-' + perm.get('object_type') + '-' + perm.get('object_id');
// Only add perms once
if (seenPerms[key]) {
return;
}
allPerms.push(perm);
seenPerms[key] = true;
});
});
// @TODO fix this!
// Permissions is an array of models
// Roles is a JSON array
return {permissions: allPerms, roles: user.roles};
});
},
app: function (appName) {
return models.App.findOne({name: appName}, {withRelated: ['permissions']})
.then(function (foundApp) {
if (!foundApp) {
return [];
}
return {permissions: foundApp.related('permissions').models};
});
},
apiKey(id) {
return models.ApiKey.findOne({id}, {withRelated: ['role', 'role.permissions']})
.then((foundApiKey) => {
if (!foundApiKey) {
throw new common.errors.NotFoundError({
message: common.i18n.t('errors.models.api_key.apiKeyNotFound')
});
}
// api keys have a belongs_to relationship to a role and no individual permissions
// so there's no need for permission deduplication
const permissions = foundApiKey.related('role').related('permissions').models;
const roles = [foundApiKey.toJSON().role];
return {permissions, roles};
});
}
};