2017-09-26 19:06:14 +03:00
|
|
|
var should = require('should'), // jshint ignore:line
|
2017-09-25 12:17:06 +03:00
|
|
|
sinon = require('sinon'),
|
|
|
|
testUtils = require('../../utils'),
|
|
|
|
Promise = require('bluebird'),
|
|
|
|
_ = require('lodash'),
|
|
|
|
models = require('../../../server/models'),
|
|
|
|
permissions = require('../../../server/permissions'),
|
|
|
|
effective = require('../../../server/permissions/effective'),
|
|
|
|
|
|
|
|
sandbox = sinon.sandbox.create();
|
|
|
|
|
|
|
|
describe('Permissions', function () {
|
|
|
|
var fakePermissions = [],
|
|
|
|
findPostSpy,
|
|
|
|
findTagSpy;
|
|
|
|
|
|
|
|
before(function () {
|
|
|
|
models.init();
|
|
|
|
});
|
|
|
|
|
|
|
|
beforeEach(function () {
|
|
|
|
sandbox.stub(models.Permission, 'findAll', function () {
|
|
|
|
return Promise.resolve(models.Permissions.forge(fakePermissions));
|
|
|
|
});
|
|
|
|
|
|
|
|
findPostSpy = sandbox.stub(models.Post, 'findOne', function () {
|
|
|
|
return Promise.resolve(models.Post.forge(testUtils.DataGenerator.Content.posts[0]));
|
|
|
|
});
|
|
|
|
|
|
|
|
findTagSpy = sandbox.stub(models.Tag, 'findOne', function () {
|
|
|
|
return Promise.resolve({});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(function () {
|
|
|
|
sandbox.restore();
|
|
|
|
});
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Default test actionMap looks like this:
|
|
|
|
* {
|
|
|
|
* browse: [ 'post' ],
|
|
|
|
* edit: [ 'post', 'tag', 'user', 'page' ],
|
|
|
|
* add: [ 'post', 'user', 'page' ],
|
|
|
|
* destroy: [ 'post', 'user' ]
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* @param {object} options
|
|
|
|
* @return {Array|*}
|
|
|
|
*/
|
|
|
|
function loadFakePermissions(options) {
|
|
|
|
options = options || {};
|
|
|
|
|
|
|
|
var fixturePermissions = testUtils.DataGenerator.Content.permissions,
|
|
|
|
extraPerm = {
|
|
|
|
name: 'test',
|
|
|
|
action_type: 'edit',
|
|
|
|
object_type: 'post'
|
|
|
|
};
|
|
|
|
|
|
|
|
if (options.extra) {
|
|
|
|
fixturePermissions.push(extraPerm);
|
|
|
|
}
|
|
|
|
|
|
|
|
return _.map(fixturePermissions, function (testPerm) {
|
|
|
|
return testUtils.DataGenerator.forKnex.createPermission(testPerm);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
describe('No init (no action map)', function () {
|
|
|
|
it('throws an error without init', function () {
|
|
|
|
permissions.canThis.should.throw(/No actions map found/);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('Init (build actions map)', function () {
|
|
|
|
it('can load an actions map from existing permissions', function (done) {
|
|
|
|
fakePermissions = loadFakePermissions();
|
|
|
|
|
|
|
|
permissions.init().then(function (actionsMap) {
|
|
|
|
should.exist(actionsMap);
|
|
|
|
|
|
|
|
_.keys(actionsMap).should.eql(['browse', 'edit', 'add', 'destroy']);
|
|
|
|
|
|
|
|
actionsMap.browse.should.eql(['post']);
|
|
|
|
actionsMap.edit.should.eql(['post', 'tag', 'user', 'page']);
|
|
|
|
actionsMap.add.should.eql(['post', 'user', 'page']);
|
|
|
|
actionsMap.destroy.should.eql(['post', 'user']);
|
|
|
|
|
|
|
|
actionsMap.should.equal(permissions.actionsMap);
|
|
|
|
|
|
|
|
done();
|
|
|
|
}).catch(done);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('can load an actions map from existing permissions, and deduplicate', function (done) {
|
|
|
|
fakePermissions = loadFakePermissions({extra: true});
|
|
|
|
|
|
|
|
permissions.init().then(function (actionsMap) {
|
|
|
|
should.exist(actionsMap);
|
|
|
|
|
|
|
|
_.keys(actionsMap).should.eql(['browse', 'edit', 'add', 'destroy']);
|
|
|
|
|
|
|
|
actionsMap.browse.should.eql(['post']);
|
|
|
|
actionsMap.edit.should.eql(['post', 'tag', 'user', 'page']);
|
|
|
|
actionsMap.add.should.eql(['post', 'user', 'page']);
|
|
|
|
actionsMap.destroy.should.eql(['post', 'user']);
|
|
|
|
|
|
|
|
actionsMap.should.equal(permissions.actionsMap);
|
|
|
|
|
|
|
|
done();
|
|
|
|
}).catch(done);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('CanThis', function () {
|
|
|
|
beforeEach(function () {
|
|
|
|
fakePermissions = loadFakePermissions();
|
|
|
|
|
|
|
|
return permissions.init();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('canThisResult gets build properly', function () {
|
|
|
|
var canThisResult = permissions.canThis();
|
|
|
|
|
|
|
|
canThisResult.browse.should.be.an.Object();
|
|
|
|
canThisResult.browse.post.should.be.a.Function();
|
|
|
|
|
|
|
|
canThisResult.edit.should.be.an.Object();
|
|
|
|
canThisResult.edit.post.should.be.a.Function();
|
|
|
|
canThisResult.edit.tag.should.be.a.Function();
|
|
|
|
canThisResult.edit.user.should.be.a.Function();
|
|
|
|
canThisResult.edit.page.should.be.a.Function();
|
|
|
|
|
|
|
|
canThisResult.add.should.be.an.Object();
|
|
|
|
canThisResult.add.post.should.be.a.Function();
|
|
|
|
canThisResult.add.user.should.be.a.Function();
|
|
|
|
canThisResult.add.page.should.be.a.Function();
|
|
|
|
|
|
|
|
canThisResult.destroy.should.be.an.Object();
|
|
|
|
canThisResult.destroy.post.should.be.a.Function();
|
|
|
|
canThisResult.destroy.user.should.be.a.Function();
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('Non user/app permissions', function () {
|
|
|
|
// TODO change to using fake models in tests!
|
|
|
|
// Permissions need to be NOT fundamentally baked into Ghost, but a separate module, at some point
|
|
|
|
// It can depend on bookshelf, but should NOT use hard coded model knowledge.
|
|
|
|
describe('with permissible calls (post model)', function () {
|
|
|
|
it('No context: does not allow edit post (no model)', function (done) {
|
|
|
|
permissions
|
|
|
|
.canThis() // no context
|
|
|
|
.edit
|
|
|
|
.post() // post id
|
|
|
|
.then(function () {
|
|
|
|
done(new Error('was able to edit post without permission'));
|
|
|
|
})
|
|
|
|
.catch(function (err) {
|
|
|
|
err.errorType.should.eql('NoPermissionError');
|
|
|
|
|
|
|
|
findPostSpy.callCount.should.eql(0);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('No context: does not allow edit post (model syntax)', function (done) {
|
|
|
|
permissions
|
|
|
|
.canThis() // no context
|
|
|
|
.edit
|
|
|
|
.post({id: 1}) // post id in model syntax
|
|
|
|
.then(function () {
|
|
|
|
done(new Error('was able to edit post without permission'));
|
|
|
|
})
|
|
|
|
.catch(function (err) {
|
|
|
|
err.errorType.should.eql('NoPermissionError');
|
|
|
|
|
|
|
|
findPostSpy.callCount.should.eql(1);
|
|
|
|
findPostSpy.firstCall.args[0].should.eql({id: 1, status: 'all'});
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('No context: does not allow edit post (model ID syntax)', function (done) {
|
|
|
|
permissions
|
|
|
|
.canThis({}) // no context
|
|
|
|
.edit
|
|
|
|
.post(1) // post id using number syntax
|
|
|
|
.then(function () {
|
|
|
|
done(new Error('was able to edit post without permission'));
|
|
|
|
})
|
|
|
|
.catch(function (err) {
|
|
|
|
err.errorType.should.eql('NoPermissionError');
|
|
|
|
|
|
|
|
findPostSpy.callCount.should.eql(1);
|
|
|
|
findPostSpy.firstCall.args[0].should.eql({id: 1, status: 'all'});
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Internal context: instantly grants permissions', function (done) {
|
|
|
|
permissions
|
|
|
|
.canThis({internal: true}) // internal context
|
|
|
|
.edit
|
|
|
|
.post({id: 1}) // post id
|
|
|
|
.then(function () {
|
|
|
|
// We don't get this far, permissions are instantly granted for internal
|
|
|
|
findPostSpy.callCount.should.eql(0);
|
|
|
|
done();
|
|
|
|
})
|
|
|
|
.catch(function () {
|
|
|
|
done(new Error('Should allow editing post with { internal: true }'));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('External context: does not grant permissions', function (done) {
|
|
|
|
permissions
|
|
|
|
.canThis({external: true}) // internal context
|
|
|
|
.edit
|
|
|
|
.post({id: 1}) // post id
|
|
|
|
.then(function () {
|
|
|
|
done(new Error('was able to edit post without permission'));
|
|
|
|
})
|
|
|
|
.catch(function (err) {
|
|
|
|
err.errorType.should.eql('NoPermissionError');
|
|
|
|
|
|
|
|
findPostSpy.callCount.should.eql(1);
|
|
|
|
findPostSpy.firstCall.args[0].should.eql({id: 1, status: 'all'});
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('without permissible (tag model)', function () {
|
|
|
|
it('No context: does not allow edit tag (model syntax)', function (done) {
|
|
|
|
permissions
|
|
|
|
.canThis() // no context
|
|
|
|
.edit
|
|
|
|
.tag({id: 1}) // tag id in model syntax
|
|
|
|
.then(function () {
|
|
|
|
done(new Error('was able to edit tag without permission'));
|
|
|
|
})
|
|
|
|
.catch(function (err) {
|
|
|
|
err.errorType.should.eql('NoPermissionError');
|
|
|
|
|
|
|
|
// We don't look up tags
|
|
|
|
findTagSpy.callCount.should.eql(0);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Internal context: instantly grants permissions', function (done) {
|
|
|
|
permissions
|
|
|
|
.canThis({internal: true}) // internal context
|
|
|
|
.edit
|
|
|
|
.tag({id: 1}) // tag id
|
|
|
|
.then(function () {
|
|
|
|
// We don't look up tags
|
|
|
|
findTagSpy.callCount.should.eql(0);
|
|
|
|
done();
|
|
|
|
})
|
|
|
|
.catch(function () {
|
|
|
|
done(new Error('Should allow editing post with { internal: true }'));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('External context: does not grant permissions', function (done) {
|
|
|
|
permissions
|
|
|
|
.canThis({external: true}) // external context
|
|
|
|
.edit
|
|
|
|
.tag({id: 1}) // tag id
|
|
|
|
.then(function () {
|
|
|
|
done(new Error('was able to edit tag without permission'));
|
|
|
|
})
|
|
|
|
.catch(function (err) {
|
|
|
|
err.errorType.should.eql('NoPermissionError');
|
|
|
|
|
|
|
|
findTagSpy.callCount.should.eql(0);
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('User-based permissions', function () {
|
|
|
|
// TODO change to using fake models in tests!
|
|
|
|
// Permissions need to be NOT fundamentally baked into Ghost, but a separate module, at some point
|
|
|
|
// It can depend on bookshelf, but should NOT use hard coded model knowledge.
|
|
|
|
// We use the tag model here because it doesn't have permissible, once that changes, these tests must also change
|
|
|
|
it('No permissions: cannot edit tag (no permissible function on model)', function (done) {
|
|
|
|
var effectiveUserStub = sandbox.stub(effective, 'user', function () {
|
|
|
|
// Fake the response from effective.user, which contains permissions and roles
|
|
|
|
return Promise.resolve({
|
|
|
|
permissions: [],
|
|
|
|
roles: undefined
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
permissions
|
|
|
|
.canThis({user: {}}) // user context
|
|
|
|
.edit
|
|
|
|
.tag({id: 1}) // tag id in model syntax
|
|
|
|
.then(function () {
|
|
|
|
done(new Error('was able to edit tag without permission'));
|
|
|
|
})
|
|
|
|
.catch(function (err) {
|
|
|
|
effectiveUserStub.callCount.should.eql(1);
|
|
|
|
err.errorType.should.eql('NoPermissionError');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('With permissions: can edit specific tag (no permissible function on model)', function (done) {
|
|
|
|
var effectiveUserStub = sandbox.stub(effective, 'user', function () {
|
|
|
|
// Fake the response from effective.user, which contains permissions and roles
|
|
|
|
return Promise.resolve({
|
|
|
|
permissions: models.Permissions.forge(testUtils.DataGenerator.Content.permissions).models,
|
|
|
|
roles: undefined
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
permissions
|
|
|
|
.canThis({user: {}}) // user context
|
|
|
|
.edit
|
|
|
|
.tag({id: 1}) // tag id in model syntax
|
|
|
|
.then(function (res) {
|
|
|
|
effectiveUserStub.callCount.should.eql(1);
|
|
|
|
should.not.exist(res);
|
|
|
|
done();
|
|
|
|
})
|
|
|
|
.catch(done);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('With permissions: can edit non-specific tag (no permissible function on model)', function (done) {
|
|
|
|
var effectiveUserStub = sandbox.stub(effective, 'user', function () {
|
|
|
|
// Fake the response from effective.user, which contains permissions and roles
|
|
|
|
return Promise.resolve({
|
|
|
|
permissions: models.Permissions.forge(testUtils.DataGenerator.Content.permissions).models,
|
|
|
|
roles: undefined
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
permissions
|
|
|
|
.canThis({user: {}}) // user context
|
|
|
|
.edit
|
|
|
|
.tag() // tag id in model syntax
|
|
|
|
.then(function (res) {
|
|
|
|
effectiveUserStub.callCount.should.eql(1);
|
|
|
|
should.not.exist(res);
|
|
|
|
done();
|
|
|
|
})
|
|
|
|
.catch(done);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Specific permissions: can edit correct specific tag (no permissible function on model)', function (done) {
|
|
|
|
var effectiveUserStub = sandbox.stub(effective, 'user', function () {
|
|
|
|
// Fake the response from effective.user, which contains permissions and roles
|
|
|
|
return Promise.resolve({
|
|
|
|
permissions: models.Permissions.forge([
|
|
|
|
{
|
|
|
|
id: 'abc123',
|
|
|
|
name: 'test',
|
|
|
|
action_type: 'edit',
|
|
|
|
object_type: 'tag',
|
|
|
|
object_id: 1
|
|
|
|
}
|
|
|
|
]).models,
|
|
|
|
roles: undefined
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
permissions
|
|
|
|
.canThis({user: {}}) // user context
|
|
|
|
.edit
|
|
|
|
.tag({id: 1}) // tag id in model syntax
|
|
|
|
.then(function (res) {
|
|
|
|
effectiveUserStub.callCount.should.eql(1);
|
|
|
|
should.not.exist(res);
|
|
|
|
done();
|
|
|
|
})
|
|
|
|
.catch(done);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Specific permissions: cannot edit incorrect specific tag (no permissible function on model)', function (done) {
|
|
|
|
var effectiveUserStub = sandbox.stub(effective, 'user', function () {
|
|
|
|
// Fake the response from effective.user, which contains permissions and roles
|
|
|
|
return Promise.resolve({
|
|
|
|
permissions: models.Permissions.forge([
|
|
|
|
{
|
|
|
|
id: 'abc123',
|
|
|
|
name: 'test',
|
|
|
|
action_type: 'edit',
|
|
|
|
object_type: 'tag',
|
|
|
|
object_id: 1
|
|
|
|
}
|
|
|
|
]).models,
|
|
|
|
roles: undefined
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
permissions
|
|
|
|
.canThis({user: {}}) // user context
|
|
|
|
.edit
|
|
|
|
.tag({id: 10}) // tag id in model syntax
|
|
|
|
.then(function () {
|
|
|
|
done(new Error('was able to edit tag without permission'));
|
|
|
|
})
|
|
|
|
.catch(function (err) {
|
|
|
|
effectiveUserStub.callCount.should.eql(1);
|
|
|
|
err.errorType.should.eql('NoPermissionError');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
// @TODO fix this case - it makes no sense?!
|
|
|
|
it('Specific permissions: CAN edit non-specific tag (no permissible function on model) @TODO fix this', function (done) {
|
|
|
|
var effectiveUserStub = sandbox.stub(effective, 'user', function () {
|
|
|
|
// Fake the response from effective.user, which contains permissions and roles
|
|
|
|
return Promise.resolve({
|
|
|
|
permissions: models.Permissions.forge([
|
|
|
|
{
|
|
|
|
id: 'abc123',
|
|
|
|
name: 'test',
|
|
|
|
action_type: 'edit',
|
|
|
|
object_type: 'tag',
|
|
|
|
object_id: 1
|
|
|
|
}
|
|
|
|
]).models,
|
|
|
|
roles: undefined
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
permissions
|
|
|
|
.canThis({user: {}}) // user context
|
|
|
|
.edit
|
|
|
|
.tag() // tag id in model syntax
|
|
|
|
.then(function (res) {
|
|
|
|
effectiveUserStub.callCount.should.eql(1);
|
|
|
|
should.not.exist(res);
|
|
|
|
done();
|
|
|
|
})
|
|
|
|
.catch(done);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('With owner role: can edit tag (no permissible function on model)', function (done) {
|
|
|
|
var effectiveUserStub = sandbox.stub(effective, 'user', function () {
|
|
|
|
// Fake the response from effective.user, which contains permissions and roles
|
|
|
|
return Promise.resolve({
|
|
|
|
permissions: [],
|
|
|
|
// This should be JSON, so no need to run it through the model layer. 3 === owner
|
|
|
|
roles: [testUtils.DataGenerator.Content.roles[3]]
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
permissions
|
|
|
|
.canThis({user: {}}) // user context
|
|
|
|
.edit
|
|
|
|
.tag({id: 1}) // tag id in model syntax
|
|
|
|
.then(function (res) {
|
|
|
|
effectiveUserStub.callCount.should.eql(1);
|
|
|
|
should.not.exist(res);
|
|
|
|
done();
|
|
|
|
})
|
|
|
|
.catch(done);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('App-based permissions (requires user as well)', function () {
|
|
|
|
// @TODO: revisit this - do we really need to have USER permissions AND app permissions?
|
|
|
|
it('No permissions: cannot edit tag with app only (no permissible function on model)', function (done) {
|
|
|
|
var effectiveAppStub = sandbox.stub(effective, 'app', function () {
|
|
|
|
// Fake the response from effective.app, which contains an empty array for this case
|
|
|
|
return Promise.resolve([]);
|
|
|
|
});
|
|
|
|
|
|
|
|
permissions
|
|
|
|
.canThis({app: {}}) // app context
|
|
|
|
.edit
|
|
|
|
.tag({id: 1}) // tag id in model syntax
|
|
|
|
.then(function () {
|
|
|
|
done(new Error('was able to edit tag without permission'));
|
|
|
|
})
|
|
|
|
.catch(function (err) {
|
|
|
|
effectiveAppStub.callCount.should.eql(1);
|
|
|
|
err.errorType.should.eql('NoPermissionError');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('No permissions: cannot edit tag (no permissible function on model)', function (done) {
|
|
|
|
var effectiveAppStub = sandbox.stub(effective, 'app', function () {
|
|
|
|
// Fake the response from effective.app, which contains an empty array for this case
|
|
|
|
return Promise.resolve([]);
|
|
|
|
}),
|
|
|
|
effectiveUserStub = sandbox.stub(effective, 'user', function () {
|
|
|
|
// Fake the response from effective.user, which contains permissions and roles
|
|
|
|
return Promise.resolve({
|
|
|
|
permissions: [],
|
|
|
|
roles: undefined
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
permissions
|
|
|
|
.canThis({app: {}, user: {}}) // app context
|
|
|
|
.edit
|
|
|
|
.tag({id: 1}) // tag id in model syntax
|
|
|
|
.then(function () {
|
|
|
|
done(new Error('was able to edit tag without permission'));
|
|
|
|
})
|
|
|
|
.catch(function (err) {
|
|
|
|
effectiveAppStub.callCount.should.eql(1);
|
|
|
|
effectiveUserStub.callCount.should.eql(1);
|
|
|
|
err.errorType.should.eql('NoPermissionError');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('With permissions: can edit specific tag (no permissible function on model)', function (done) {
|
|
|
|
var effectiveAppStub = sandbox.stub(effective, 'app', function () {
|
|
|
|
// Fake the response from effective.app, which contains permissions only
|
|
|
|
return Promise.resolve({
|
|
|
|
permissions: models.Permissions.forge(testUtils.DataGenerator.Content.permissions).models
|
|
|
|
});
|
|
|
|
}),
|
|
|
|
effectiveUserStub = sandbox.stub(effective, 'user', function () {
|
|
|
|
// Fake the response from effective.user, which contains permissions and roles
|
|
|
|
return Promise.resolve({
|
|
|
|
permissions: models.Permissions.forge(testUtils.DataGenerator.Content.permissions).models,
|
|
|
|
roles: undefined
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
permissions
|
|
|
|
.canThis({app: {}, user: {}}) // app context
|
|
|
|
.edit
|
|
|
|
.tag({id: 1}) // tag id in model syntax
|
|
|
|
.then(function (res) {
|
|
|
|
effectiveAppStub.callCount.should.eql(1);
|
|
|
|
effectiveUserStub.callCount.should.eql(1);
|
|
|
|
should.not.exist(res);
|
|
|
|
done();
|
|
|
|
})
|
|
|
|
.catch(done);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('With permissions: can edit non-specific tag (no permissible function on model)', function (done) {
|
|
|
|
var effectiveAppStub = sandbox.stub(effective, 'app', function () {
|
|
|
|
// Fake the response from effective.app, which contains permissions only
|
|
|
|
return Promise.resolve({
|
|
|
|
permissions: models.Permissions.forge(testUtils.DataGenerator.Content.permissions).models
|
|
|
|
});
|
|
|
|
}),
|
|
|
|
effectiveUserStub = sandbox.stub(effective, 'user', function () {
|
|
|
|
// Fake the response from effective.user, which contains permissions and roles
|
|
|
|
return Promise.resolve({
|
|
|
|
permissions: models.Permissions.forge(testUtils.DataGenerator.Content.permissions).models,
|
|
|
|
roles: undefined
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
permissions
|
|
|
|
.canThis({app: {}, user: {}}) // app context
|
|
|
|
.edit
|
|
|
|
.tag() // tag id in model syntax
|
|
|
|
.then(function (res) {
|
|
|
|
effectiveAppStub.callCount.should.eql(1);
|
|
|
|
effectiveUserStub.callCount.should.eql(1);
|
|
|
|
should.not.exist(res);
|
|
|
|
done();
|
|
|
|
})
|
|
|
|
.catch(done);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('permissible (overridden)', function () {
|
|
|
|
it('can use permissible function on model to forbid something (post model)', function (done) {
|
|
|
|
var effectiveUserStub = sandbox.stub(effective, 'user', function () {
|
|
|
|
// Fake the response from effective.user, which contains permissions and roles
|
|
|
|
return Promise.resolve({
|
|
|
|
permissions: models.Permissions.forge(testUtils.DataGenerator.Content.permissions).models,
|
|
|
|
roles: undefined
|
|
|
|
});
|
|
|
|
}),
|
|
|
|
permissibleStub = sandbox.stub(models.Post, 'permissible', function () {
|
|
|
|
return Promise.reject({message: 'Hello World!'});
|
|
|
|
});
|
|
|
|
|
|
|
|
permissions
|
|
|
|
.canThis({user: {}}) // user context
|
|
|
|
.edit
|
|
|
|
.post({id: 1}) // tag id in model syntax
|
|
|
|
.then(function () {
|
|
|
|
done(new Error('was able to edit post without permission'));
|
|
|
|
})
|
|
|
|
.catch(function (err) {
|
|
|
|
permissibleStub.callCount.should.eql(1);
|
2017-09-26 19:06:14 +03:00
|
|
|
permissibleStub.firstCall.args.should.have.lengthOf(7);
|
|
|
|
|
|
|
|
permissibleStub.firstCall.args[0].should.eql(1);
|
|
|
|
permissibleStub.firstCall.args[1].should.eql('edit');
|
|
|
|
permissibleStub.firstCall.args[2].should.be.an.Object();
|
|
|
|
permissibleStub.firstCall.args[3].should.be.an.Object();
|
|
|
|
permissibleStub.firstCall.args[4].should.be.an.Object();
|
|
|
|
permissibleStub.firstCall.args[5].should.be.true();
|
|
|
|
permissibleStub.firstCall.args[6].should.be.true();
|
|
|
|
|
2017-09-25 12:17:06 +03:00
|
|
|
effectiveUserStub.callCount.should.eql(1);
|
|
|
|
err.message.should.eql('Hello World!');
|
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('can use permissible function on model to allow something (post model)', function (done) {
|
|
|
|
var effectiveUserStub = sandbox.stub(effective, 'user', function () {
|
|
|
|
// Fake the response from effective.user, which contains permissions and roles
|
|
|
|
return Promise.resolve({
|
|
|
|
permissions: models.Permissions.forge(testUtils.DataGenerator.Content.permissions).models,
|
|
|
|
roles: undefined
|
|
|
|
});
|
|
|
|
}),
|
|
|
|
permissibleStub = sandbox.stub(models.Post, 'permissible', function () {
|
|
|
|
return Promise.resolve();
|
|
|
|
});
|
|
|
|
|
|
|
|
permissions
|
|
|
|
.canThis({user: {}}) // user context
|
|
|
|
.edit
|
|
|
|
.post({id: 1}) // tag id in model syntax
|
|
|
|
.then(function (res) {
|
|
|
|
permissibleStub.callCount.should.eql(1);
|
2017-09-26 19:06:14 +03:00
|
|
|
permissibleStub.firstCall.args.should.have.lengthOf(7);
|
|
|
|
permissibleStub.firstCall.args[0].should.eql(1);
|
|
|
|
permissibleStub.firstCall.args[1].should.eql('edit');
|
|
|
|
permissibleStub.firstCall.args[2].should.be.an.Object();
|
|
|
|
permissibleStub.firstCall.args[3].should.be.an.Object();
|
|
|
|
permissibleStub.firstCall.args[4].should.be.an.Object();
|
|
|
|
permissibleStub.firstCall.args[5].should.be.true();
|
|
|
|
permissibleStub.firstCall.args[6].should.be.true();
|
|
|
|
|
2017-09-25 12:17:06 +03:00
|
|
|
effectiveUserStub.callCount.should.eql(1);
|
|
|
|
should.not.exist(res);
|
|
|
|
done();
|
|
|
|
})
|
|
|
|
.catch(done);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|