Skip to content

Commit

Permalink
🐛 fix invite permissions for editor (#7889)
Browse files Browse the repository at this point in the history
refs #7724

- we already fixed the permissions for the editor
- see 3d3101a
- but as we are inside of a refactoring process, we had two fixtures.json files
- we fixed the fixtures.json in the wrong place
- now that the permissions are used, we can see failing tests
- i have added the correct permissions handling
  • Loading branch information
kirrg001 authored and kevinansfield committed Jan 25, 2017
1 parent ca521e2 commit 042750f
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 34 deletions.
49 changes: 36 additions & 13 deletions core/server/api/invites.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,15 +91,7 @@ invites = {
function addInvite(options) {
var data = options.data;

return dataProvider.User.findOne({id: loggedInUser}, options)
.then(function (user) {
if (!user) {
return Promise.reject(new errors.NotFoundError({message: i18n.t('errors.api.users.userNotFound')}));
}

loggedInUser = user;
return dataProvider.Invite.add(data.invites[0], _.omit(options, 'data'));
})
return dataProvider.Invite.add(data.invites[0], _.omit(options, 'data'))
.then(function (_invite) {
invite = _invite;

Expand Down Expand Up @@ -177,25 +169,56 @@ invites = {
return Promise.reject(new errors.ValidationError({message: i18n.t('errors.api.invites.roleIsRequired')}));
}

// @TODO move this logic to permissible
// @TODO remove when we have a new permission unit
// Make sure user is allowed to add a user with this role
return dataProvider.Role.findOne({id: options.data.invites[0].role_id}).then(function (role) {
if (!role) {
// We cannot use permissible because we don't have access to the role_id!!!
// Adding a permissible function to the invite model, doesn't give us much context of the invite we would like to add
// As we are looking forward to replace the permission system completely, we do not add a hack here
return dataProvider.Role.findOne({id: options.data.invites[0].role_id}).then(function (roleToInvite) {
if (!roleToInvite) {
return Promise.reject(new errors.NotFoundError({message: i18n.t('errors.api.invites.roleNotFound')}));
}

if (role.get('name') === 'Owner') {
if (roleToInvite.get('name') === 'Owner') {
return Promise.reject(new errors.NoPermissionError({message: i18n.t('errors.api.invites.notAllowedToInviteOwner')}));
}

var loggedInUserRole = loggedInUser.related('roles').models[0].get('name'),
allowed = [];

if (loggedInUserRole === 'Owner' || loggedInUserRole === 'Administrator') {
allowed = ['Administrator', 'Editor', 'Author'];
} else if (loggedInUserRole === 'Editor') {
allowed = ['Author'];
}

if (allowed.indexOf(roleToInvite.get('name')) === -1) {
return Promise.reject(new errors.NoPermissionError({
message: i18n.t('errors.api.invites.notAllowedToInvite')
}));
}
}).then(function () {
return options;
});
}

function fetchLoggedInUser(options) {
return dataProvider.User.findOne({id: loggedInUser}, _.merge({}, options, {include: ['roles']}))
.then(function (user) {
if (!user) {
return Promise.reject(new errors.NotFoundError({message: i18n.t('errors.api.users.userNotFound')}));
}

loggedInUser = user;
return options;
});
}

tasks = [
utils.validate(docName, {opts: ['email']}),
utils.handlePermissions(docName, 'add'),
utils.convertOptions(allowedIncludes),
fetchLoggedInUser,
validation,
destroyOldInvite,
addInvite
Expand Down
3 changes: 2 additions & 1 deletion core/server/permissions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ CanThisResult.prototype.buildObjectTypeHandlers = function (objTypes, actType, c
user: Models.User,
permission: Models.Permission,
setting: Models.Settings,
subscriber: Models.Subscriber
subscriber: Models.Subscriber,
invite: Models.Invite
};

// Iterate through the object types, i.e. ['post', 'tag', 'user']
Expand Down
3 changes: 2 additions & 1 deletion core/server/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,8 @@
"error": "Error sending email: {message}",
"help": "Please check your email settings and resend the invitation."
},
"notAllowedToInviteOwner": "Not allowed to invire an owner user."
"notAllowedToInviteOwner": "Not allowed to invite an owner user.",
"notAllowedToInvite": "Not allowed to invite this role."
}
},
"data": {
Expand Down
51 changes: 33 additions & 18 deletions core/test/integration/api/api_invites_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ describe('Invites API', function () {
}

describe('Owner', function () {
it('CANNOT add an Owner', function (done) {
it('CANNOT invite an Owner', function (done) {
InvitesAPI.add({
invites: [
{
Expand All @@ -191,7 +191,7 @@ describe('Invites API', function () {
}).catch(checkForErrorType('NoPermissionError', done));
});

it('Can add an Admin', function (done) {
it('Can invite an Admin', function (done) {
InvitesAPI.add({
invites: [
{
Expand All @@ -206,7 +206,7 @@ describe('Invites API', function () {
}).catch(done);
});

it('Can add an Editor', function (done) {
it('Can invite an Editor', function (done) {
InvitesAPI.add({
invites: [
{
Expand All @@ -221,7 +221,7 @@ describe('Invites API', function () {
}).catch(done);
});

it('Can add an Author', function (done) {
it('Can invite an Author', function (done) {
InvitesAPI.add({
invites: [
{
Expand All @@ -236,7 +236,7 @@ describe('Invites API', function () {
}).catch(done);
});

it('Can add with role set as string', function (done) {
it('Can invite with role set as string', function (done) {
InvitesAPI.add({
invites: [
{
Expand All @@ -253,7 +253,7 @@ describe('Invites API', function () {
});

describe('Admin', function () {
it('CANNOT add an Owner', function (done) {
it('CANNOT invite an Owner', function (done) {
InvitesAPI.add({
invites: [
{
Expand All @@ -266,7 +266,7 @@ describe('Invites API', function () {
}).catch(checkForErrorType('NoPermissionError', done));
});

it('Can add an Admin', function (done) {
it('Can invite an Admin', function (done) {
InvitesAPI.add({
invites: [
{
Expand All @@ -281,7 +281,7 @@ describe('Invites API', function () {
}).catch(done);
});

it('Can add an Editor', function (done) {
it('Can invite an Editor', function (done) {
InvitesAPI.add({
invites: [
{
Expand All @@ -296,7 +296,7 @@ describe('Invites API', function () {
}).catch(done);
});

it('Can add an Author', function (done) {
it('Can invite an Author', function (done) {
InvitesAPI.add({
invites: [
{
Expand All @@ -313,7 +313,7 @@ describe('Invites API', function () {
});

describe('Editor', function () {
it('CANNOT add an Owner', function (done) {
it('CANNOT invite an Owner', function (done) {
InvitesAPI.add({
invites: [
{
Expand All @@ -322,11 +322,11 @@ describe('Invites API', function () {
}
]
}, context.editor).then(function () {
done(new Error('Editor should not be able to add an owner'));
done(new Error('Editor should not be able to invite an owner'));
}).catch(checkForErrorType('NoPermissionError', done));
});

it('CANNOT add an Adminstrator', function (done) {
it('CANNOT invite an Adminstrator', function (done) {
InvitesAPI.add({
invites: [
{
Expand All @@ -335,26 +335,41 @@ describe('Invites API', function () {
}
]
}, context.editor).then(function () {
done(new Error('Editor should not be able to add an owner'));
done(new Error('Editor should not be able to invite an administrator'));
}).catch(checkForErrorType('NoPermissionError', done));
});

it('CANNOT add an Author', function (done) {
it('CANNOT invite an Editor', function (done) {
InvitesAPI.add({
invites: [
{
email: 'test@example.com',
role_id: testUtils.roles.ids.author
role_id: testUtils.roles.ids.editor
}
]
}, context.editor).then(function () {
done(new Error('Editor should not be able to add an author'));
done(new Error('Editor should not be able to invite an editor'));
}).catch(checkForErrorType('NoPermissionError', done));
});

it('Can invite an Author', function (done) {
InvitesAPI.add({
invites: [
{
email: 'test@example.com',
role_id: testUtils.roles.ids.author
}
]
}, context.editor).then(function (response) {
checkAddResponse(response);
response.invites[0].role_id.should.equal(testUtils.roles.ids.author);
done();
}).catch(done);
});
});

describe('Author', function () {
it('CANNOT add an Owner', function (done) {
it('CANNOT invite an Owner', function (done) {
InvitesAPI.add({
invites: [
{
Expand All @@ -367,7 +382,7 @@ describe('Invites API', function () {
}).catch(checkForErrorType('NoPermissionError', done));
});

it('CANNOT add an Author', function (done) {
it('CANNOT invite an Author', function (done) {
InvitesAPI.add({
invites: [
{
Expand Down
2 changes: 1 addition & 1 deletion core/test/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ var Promise = require('bluebird'),
ghost = require('../../server'),
errors = require('../../server/errors'),
db = require('../../server/data/db'),
fixtureUtils = require('../../server/data/migration/fixtures/utils'),
fixtureUtils = require('../../server/data/schema/fixtures/utils'),
models = require('../../server/models'),
SettingsAPI = require('../../server/api/settings'),
permissions = require('../../server/permissions'),
Expand Down

0 comments on commit 042750f

Please sign in to comment.