0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-01-20 22:42:53 -05:00

Add permissions models & relations for clients

refs #6301, #4176

Add migration for:
- 5 new client permissions
- 15 relations between the admin, editor & author role and the 5 new permissions
- updates to tests to show that permissions get updated properly
This commit is contained in:
Hannah Wolfe 2016-04-08 10:09:26 +01:00
parent 8b9734ea31
commit 5884fe0323
7 changed files with 205 additions and 20 deletions

View file

@ -0,0 +1,30 @@
// Update the permissions & permissions_roles tables to get the new entries
var utils = require('../utils');
function getClientPermissions() {
return utils.findModelFixtures('Permission', {object_type: 'client'});
}
function getClientRelations() {
return utils.findPermissionRelationsForObject('client');
}
function printResult(logger, result, message) {
if (result.done === result.expected) {
logger.info(message);
} else {
logger.warn('(' + result.done + '/' + result.expected + ') ' + message);
}
}
module.exports = function addClientPermissions(options, logger) {
var modelToAdd = getClientPermissions(),
relationToAdd = getClientRelations();
return utils.addFixturesForModel(modelToAdd).then(function (result) {
printResult(logger, result, 'Adding permissions fixtures for clients');
return utils.addFixturesForRelation(relationToAdd);
}).then(function (result) {
printResult(logger, result, 'Adding permissions_roles fixtures for clients');
});
};

View file

@ -2,5 +2,7 @@ module.exports = [
// add jquery setting and privacy info
require('./01-update-ghost-client-secrets'),
// add ghost-scheduler client
require('./02-add-ghost-scheduler-client')
require('./02-add-ghost-scheduler-client'),
// add client permissions and permission_role relations
require('./03-add-client-permissions')
];

View file

@ -224,6 +224,31 @@
"name": "Browse roles",
"action_type": "browse",
"object_type": "role"
},
{
"name": "Browse clients",
"action_type": "browse",
"object_type": "client"
},
{
"name": "Read clients",
"action_type": "read",
"object_type": "client"
},
{
"name": "Edit clients",
"action_type": "edit",
"object_type": "client"
},
{
"name": "Add clients",
"action_type": "add",
"object_type": "client"
},
{
"name": "Delete clients",
"action_type": "destroy",
"object_type": "client"
}
]
}
@ -251,7 +276,8 @@
"tag": "all",
"theme": "all",
"user": "all",
"role": "all"
"role": "all",
"client": "all"
},
"Editor": {
"post": "all",
@ -259,7 +285,8 @@
"slug": "all",
"tag": "all",
"user": "all",
"role": "all"
"role": "all",
"client": "all"
},
"Author": {
"post": ["browse", "read", "add"],
@ -267,7 +294,8 @@
"slug": "all",
"tag": ["browse", "read", "add"],
"user": ["browse", "read"],
"role": ["browse"]
"role": ["browse"],
"client": "all"
}
}
},

View file

@ -6,6 +6,7 @@ var testUtils = require('../utils'),
Promise = require('bluebird'),
fixtures = require('../../server/data/migration/fixtures'),
fixtures005 = require('../../server/data/migration/fixtures/005'),
Models = require('../../server/models'),
sandbox = sinon.sandbox.create();
@ -122,6 +123,18 @@ describe('Database Migration (special functions)', function () {
permissions[28].should.be.AssignedToRoles(['Administrator', 'Editor']);
permissions[29].name.should.eql('Browse roles');
permissions[29].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
// Clients
permissions[30].name.should.eql('Browse clients');
permissions[30].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
permissions[31].name.should.eql('Read clients');
permissions[31].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
permissions[32].name.should.eql('Edit clients');
permissions[32].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
permissions[33].name.should.eql('Add clients');
permissions[33].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
permissions[34].name.should.eql('Delete clients');
permissions[34].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
});
describe('Populate', function () {
@ -180,7 +193,7 @@ describe('Database Migration (special functions)', function () {
result.roles.at(3).get('name').should.eql('Owner');
// Permissions
result.permissions.length.should.eql(30);
result.permissions.length.should.eql(35);
result.permissions.toJSON().should.be.CompletePermissions();
done();
@ -188,6 +201,60 @@ describe('Database Migration (special functions)', function () {
}).catch(done);
});
});
describe('Update', function () {
// We need the roles, and lets add some other perms to simulate the "Update" environment
beforeEach(testUtils.setup('users:roles', 'perms:db', 'perms:init'));
it('should update client permissions correctly', function (done) {
fixtures005[2]({}, loggerStub).then(function () {
var props = {
roles: Models.Role.findAll(),
permissions: Models.Permission.findAll({include: ['roles']})
}, permissions;
loggerStub.info.called.should.be.true();
loggerStub.warn.called.should.be.false();
return Promise.props(props).then(function (result) {
should.exist(result);
should.exist(result.roles);
result.roles.length.should.eql(4);
result.roles.at(0).get('name').should.eql('Administrator');
result.roles.at(1).get('name').should.eql('Editor');
result.roles.at(2).get('name').should.eql('Author');
result.roles.at(3).get('name').should.eql('Owner');
// Permissions
result.permissions.length.should.eql(8);
permissions = result.permissions.toJSON();
// DB Perms
permissions[0].name.should.eql('Export database');
permissions[0].should.be.AssignedToRoles(['Administrator']);
permissions[1].name.should.eql('Import database');
permissions[1].should.be.AssignedToRoles(['Administrator']);
permissions[2].name.should.eql('Delete all content');
permissions[2].should.be.AssignedToRoles(['Administrator']);
// Client Perms
permissions[3].name.should.eql('Browse clients');
permissions[3].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
permissions[4].name.should.eql('Read clients');
permissions[4].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
permissions[5].name.should.eql('Edit clients');
permissions[5].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
permissions[6].name.should.eql('Add clients');
permissions[6].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
permissions[7].name.should.eql('Delete clients');
permissions[7].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
done();
}).catch(done);
});
});
});
});
});

View file

@ -11,6 +11,7 @@ var should = require('should'),
versioning = require('../../server/data/schema/versioning'),
update = rewire('../../server/data/migration/fixtures/update'),
populate = rewire('../../server/data/migration/fixtures/populate'),
fixtureUtils = require('../../server/data/migration/fixtures/utils'),
fixtures004 = require('../../server/data/migration/fixtures/004'),
fixtures005 = require('../../server/data/migration/fixtures/005'),
ensureDefaultSettings = require('../../server/data/migration/fixtures/settings'),
@ -718,9 +719,10 @@ describe('Fixtures', function () {
sequenceStub.firstCall.args[0][0].should.be.a.Function().with.property('name', 'runVersionTasks');
sequenceStub.secondCall.calledWith(sinon.match.array, sinon.match.object, loggerStub).should.be.true();
sequenceStub.secondCall.args[0].should.be.an.Array().with.lengthOf(2);
sequenceStub.secondCall.args[0].should.be.an.Array().with.lengthOf(3);
sequenceStub.secondCall.args[0][0].should.be.a.Function().with.property('name', 'updateGhostClientsSecrets');
sequenceStub.secondCall.args[0][1].should.be.a.Function().with.property('name', 'addGhostFrontendClient');
sequenceStub.secondCall.args[0][2].should.be.a.Function().with.property('name', 'addClientPermissions');
// Reset
sequenceReset();
@ -731,7 +733,7 @@ describe('Fixtures', function () {
describe('Tasks:', function () {
it('should have tasks for 005', function () {
should.exist(fixtures005);
fixtures005.should.be.an.Array().with.lengthOf(2);
fixtures005.should.be.an.Array().with.lengthOf(3);
});
describe('01-update-ghost-client-secrets', function () {
@ -813,6 +815,62 @@ describe('Fixtures', function () {
}).catch(done);
});
});
describe('03-add-client-permissions', function () {
var modelResult, addModelStub, relationResult, addRelationStub;
beforeEach(function () {
modelResult = {expected: 1, done: 1};
addModelStub = sandbox.stub(fixtureUtils, 'addFixturesForModel')
.returns(Promise.resolve(modelResult));
relationResult = {expected: 1, done: 1};
addRelationStub = sandbox.stub(fixtureUtils, 'addFixturesForRelation')
.returns(Promise.resolve(relationResult));
});
it('should find the correct model & relation to add', function (done) {
// Execute
fixtures005[2]({}, loggerStub).then(function () {
addModelStub.calledOnce.should.be.true();
addModelStub.calledWith(
fixtureUtils.findModelFixtures('Permission', {object_type: 'client'})
).should.be.true();
addRelationStub.calledOnce.should.be.true();
addRelationStub.calledWith(
fixtureUtils.findPermissionRelationsForObject('client')
).should.be.true();
loggerStub.info.calledTwice.should.be.true();
loggerStub.warn.called.should.be.false();
done();
});
});
it('should warn the result shows less work was done than expected', function (done) {
// Setup
modelResult.expected = 3;
// Execute
fixtures005[2]({}, loggerStub).then(function () {
addModelStub.calledOnce.should.be.true();
addModelStub.calledWith(
fixtureUtils.findModelFixtures('Permission', {object_type: 'client'})
).should.be.true();
addRelationStub.calledOnce.should.be.true();
addRelationStub.calledWith(
fixtureUtils.findPermissionRelationsForObject('client')
).should.be.true();
loggerStub.info.calledOnce.should.be.true();
loggerStub.warn.calledOnce.should.be.true();
done();
});
});
});
});
});
});
@ -863,9 +921,9 @@ describe('Fixtures', function () {
clientOneStub.calledThrice.should.be.true();
clientAddStub.calledThrice.should.be.true();
permOneStub.callCount.should.eql(30);
permOneStub.callCount.should.eql(35);
permsAddStub.called.should.be.true();
permsAddStub.callCount.should.eql(30);
permsAddStub.callCount.should.eql(35);
permsAllStub.calledOnce.should.be.true();
rolesAllStub.calledOnce.should.be.true();
@ -874,8 +932,8 @@ describe('Fixtures', function () {
// Relations
modelMethodStub.filter.called.should.be.true();
// 22 permissions, 1 tag
modelMethodStub.filter.callCount.should.eql(22 + 1);
// 25 permissions, 1 tag
modelMethodStub.filter.callCount.should.eql(25 + 1);
modelMethodStub.find.called.should.be.true();
// 3 roles, 1 post
modelMethodStub.find.callCount.should.eql(3 + 1);

View file

@ -152,21 +152,21 @@ describe('Utils', function () {
fixtureUtils.addFixturesForRelation(fixtures.relations[0]).then(function (result) {
should.exist(result);
result.should.be.an.Object();
result.should.have.property('expected', 22);
result.should.have.property('done', 22);
result.should.have.property('expected', 25);
result.should.have.property('done', 25);
// Permissions & Roles
permsAllStub.calledOnce.should.be.true();
rolesAllStub.calledOnce.should.be.true();
dataMethodStub.filter.callCount.should.eql(22);
dataMethodStub.filter.callCount.should.eql(25);
dataMethodStub.find.callCount.should.eql(3);
fromItem.related.callCount.should.eql(22);
fromItem.findWhere.callCount.should.eql(22);
toItem[0].get.callCount.should.eql(44);
fromItem.related.callCount.should.eql(25);
fromItem.findWhere.callCount.should.eql(25);
toItem[0].get.callCount.should.eql(50);
fromItem.permissions.callCount.should.eql(22);
fromItem.attach.callCount.should.eql(22);
fromItem.permissions.callCount.should.eql(25);
fromItem.attach.callCount.should.eql(25);
fromItem.attach.calledWith(toItem).should.be.true();
done();

View file

@ -33,7 +33,7 @@ describe('DB version integrity', function () {
// Only these variables should need updating
var currentDbVersion = '005',
currentSchemaHash = 'be706cdbeb06103d90703ee733efc556',
currentFixturesHash = '21dd859601c8e1c12eaff9eccfbe966a';
currentFixturesHash = 'ba195b645386b019a69c4b79e6854138';
// If this test is failing, then it is likely a change has been made that requires a DB version bump,
// and the values above will need updating as confirmation