mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-17 23:44:39 -05:00
🐛 fix invite permissions for editor (#7889)
refs #7724
- we already fixed the permissions for the editor
- see 3d3101ad0e
- 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
This commit is contained in:
parent
ca521e234f
commit
042750f4cf
5 changed files with 75 additions and 35 deletions
|
@ -91,15 +91,7 @@ invites = {
|
||||||
function addInvite(options) {
|
function addInvite(options) {
|
||||||
var data = options.data;
|
var data = options.data;
|
||||||
|
|
||||||
return dataProvider.User.findOne({id: loggedInUser}, options)
|
return dataProvider.Invite.add(data.invites[0], _.omit(options, 'data'))
|
||||||
.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'));
|
|
||||||
})
|
|
||||||
.then(function (_invite) {
|
.then(function (_invite) {
|
||||||
invite = _invite;
|
invite = _invite;
|
||||||
|
|
||||||
|
@ -177,25 +169,56 @@ invites = {
|
||||||
return Promise.reject(new errors.ValidationError({message: i18n.t('errors.api.invites.roleIsRequired')}));
|
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
|
// 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) {
|
// We cannot use permissible because we don't have access to the role_id!!!
|
||||||
if (!role) {
|
// 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')}));
|
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')}));
|
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 () {
|
}).then(function () {
|
||||||
return options;
|
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 = [
|
tasks = [
|
||||||
utils.validate(docName, {opts: ['email']}),
|
utils.validate(docName, {opts: ['email']}),
|
||||||
utils.handlePermissions(docName, 'add'),
|
utils.handlePermissions(docName, 'add'),
|
||||||
utils.convertOptions(allowedIncludes),
|
utils.convertOptions(allowedIncludes),
|
||||||
|
fetchLoggedInUser,
|
||||||
validation,
|
validation,
|
||||||
destroyOldInvite,
|
destroyOldInvite,
|
||||||
addInvite
|
addInvite
|
||||||
|
|
|
@ -124,7 +124,8 @@ CanThisResult.prototype.buildObjectTypeHandlers = function (objTypes, actType, c
|
||||||
user: Models.User,
|
user: Models.User,
|
||||||
permission: Models.Permission,
|
permission: Models.Permission,
|
||||||
setting: Models.Settings,
|
setting: Models.Settings,
|
||||||
subscriber: Models.Subscriber
|
subscriber: Models.Subscriber,
|
||||||
|
invite: Models.Invite
|
||||||
};
|
};
|
||||||
|
|
||||||
// Iterate through the object types, i.e. ['post', 'tag', 'user']
|
// Iterate through the object types, i.e. ['post', 'tag', 'user']
|
||||||
|
|
|
@ -399,7 +399,8 @@
|
||||||
"error": "Error sending email: {message}",
|
"error": "Error sending email: {message}",
|
||||||
"help": "Please check your email settings and resend the invitation."
|
"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": {
|
"data": {
|
||||||
|
|
|
@ -178,7 +178,7 @@ describe('Invites API', function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('Owner', function () {
|
describe('Owner', function () {
|
||||||
it('CANNOT add an Owner', function (done) {
|
it('CANNOT invite an Owner', function (done) {
|
||||||
InvitesAPI.add({
|
InvitesAPI.add({
|
||||||
invites: [
|
invites: [
|
||||||
{
|
{
|
||||||
|
@ -191,7 +191,7 @@ describe('Invites API', function () {
|
||||||
}).catch(checkForErrorType('NoPermissionError', done));
|
}).catch(checkForErrorType('NoPermissionError', done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Can add an Admin', function (done) {
|
it('Can invite an Admin', function (done) {
|
||||||
InvitesAPI.add({
|
InvitesAPI.add({
|
||||||
invites: [
|
invites: [
|
||||||
{
|
{
|
||||||
|
@ -206,7 +206,7 @@ describe('Invites API', function () {
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Can add an Editor', function (done) {
|
it('Can invite an Editor', function (done) {
|
||||||
InvitesAPI.add({
|
InvitesAPI.add({
|
||||||
invites: [
|
invites: [
|
||||||
{
|
{
|
||||||
|
@ -221,7 +221,7 @@ describe('Invites API', function () {
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Can add an Author', function (done) {
|
it('Can invite an Author', function (done) {
|
||||||
InvitesAPI.add({
|
InvitesAPI.add({
|
||||||
invites: [
|
invites: [
|
||||||
{
|
{
|
||||||
|
@ -236,7 +236,7 @@ describe('Invites API', function () {
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Can add with role set as string', function (done) {
|
it('Can invite with role set as string', function (done) {
|
||||||
InvitesAPI.add({
|
InvitesAPI.add({
|
||||||
invites: [
|
invites: [
|
||||||
{
|
{
|
||||||
|
@ -253,7 +253,7 @@ describe('Invites API', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Admin', function () {
|
describe('Admin', function () {
|
||||||
it('CANNOT add an Owner', function (done) {
|
it('CANNOT invite an Owner', function (done) {
|
||||||
InvitesAPI.add({
|
InvitesAPI.add({
|
||||||
invites: [
|
invites: [
|
||||||
{
|
{
|
||||||
|
@ -266,7 +266,7 @@ describe('Invites API', function () {
|
||||||
}).catch(checkForErrorType('NoPermissionError', done));
|
}).catch(checkForErrorType('NoPermissionError', done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Can add an Admin', function (done) {
|
it('Can invite an Admin', function (done) {
|
||||||
InvitesAPI.add({
|
InvitesAPI.add({
|
||||||
invites: [
|
invites: [
|
||||||
{
|
{
|
||||||
|
@ -281,7 +281,7 @@ describe('Invites API', function () {
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Can add an Editor', function (done) {
|
it('Can invite an Editor', function (done) {
|
||||||
InvitesAPI.add({
|
InvitesAPI.add({
|
||||||
invites: [
|
invites: [
|
||||||
{
|
{
|
||||||
|
@ -296,7 +296,7 @@ describe('Invites API', function () {
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Can add an Author', function (done) {
|
it('Can invite an Author', function (done) {
|
||||||
InvitesAPI.add({
|
InvitesAPI.add({
|
||||||
invites: [
|
invites: [
|
||||||
{
|
{
|
||||||
|
@ -313,7 +313,7 @@ describe('Invites API', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Editor', function () {
|
describe('Editor', function () {
|
||||||
it('CANNOT add an Owner', function (done) {
|
it('CANNOT invite an Owner', function (done) {
|
||||||
InvitesAPI.add({
|
InvitesAPI.add({
|
||||||
invites: [
|
invites: [
|
||||||
{
|
{
|
||||||
|
@ -322,11 +322,11 @@ describe('Invites API', function () {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}, context.editor).then(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));
|
}).catch(checkForErrorType('NoPermissionError', done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('CANNOT add an Adminstrator', function (done) {
|
it('CANNOT invite an Adminstrator', function (done) {
|
||||||
InvitesAPI.add({
|
InvitesAPI.add({
|
||||||
invites: [
|
invites: [
|
||||||
{
|
{
|
||||||
|
@ -335,11 +335,24 @@ describe('Invites API', function () {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}, context.editor).then(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));
|
}).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.editor
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}, context.editor).then(function () {
|
||||||
|
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({
|
InvitesAPI.add({
|
||||||
invites: [
|
invites: [
|
||||||
{
|
{
|
||||||
|
@ -347,14 +360,16 @@ describe('Invites API', function () {
|
||||||
role_id: testUtils.roles.ids.author
|
role_id: testUtils.roles.ids.author
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}, context.editor).then(function () {
|
}, context.editor).then(function (response) {
|
||||||
done(new Error('Editor should not be able to add an author'));
|
checkAddResponse(response);
|
||||||
}).catch(checkForErrorType('NoPermissionError', done));
|
response.invites[0].role_id.should.equal(testUtils.roles.ids.author);
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Author', function () {
|
describe('Author', function () {
|
||||||
it('CANNOT add an Owner', function (done) {
|
it('CANNOT invite an Owner', function (done) {
|
||||||
InvitesAPI.add({
|
InvitesAPI.add({
|
||||||
invites: [
|
invites: [
|
||||||
{
|
{
|
||||||
|
@ -367,7 +382,7 @@ describe('Invites API', function () {
|
||||||
}).catch(checkForErrorType('NoPermissionError', done));
|
}).catch(checkForErrorType('NoPermissionError', done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('CANNOT add an Author', function (done) {
|
it('CANNOT invite an Author', function (done) {
|
||||||
InvitesAPI.add({
|
InvitesAPI.add({
|
||||||
invites: [
|
invites: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,7 +10,7 @@ var Promise = require('bluebird'),
|
||||||
ghost = require('../../server'),
|
ghost = require('../../server'),
|
||||||
errors = require('../../server/errors'),
|
errors = require('../../server/errors'),
|
||||||
db = require('../../server/data/db'),
|
db = require('../../server/data/db'),
|
||||||
fixtureUtils = require('../../server/data/migration/fixtures/utils'),
|
fixtureUtils = require('../../server/data/schema/fixtures/utils'),
|
||||||
models = require('../../server/models'),
|
models = require('../../server/models'),
|
||||||
SettingsAPI = require('../../server/api/settings'),
|
SettingsAPI = require('../../server/api/settings'),
|
||||||
permissions = require('../../server/permissions'),
|
permissions = require('../../server/permissions'),
|
||||||
|
|
Loading…
Add table
Reference in a new issue