Ghost/core/test/unit/permissions_spec.js

400 lines
13 KiB
JavaScript
Raw Normal View History

/*globals describe, before, beforeEach, afterEach, it*/
var testUtils = require('../utils'),
should = require('should'),
sinon = require('sinon'),
when = require('when'),
2014-02-05 12:40:30 +04:00
_ = require("lodash"),
errors = require('../../server/errorHandling'),
// Stuff we are testing
permissions = require('../../server/permissions'),
effectivePerms = require('../../server/permissions/effective'),
Models = require('../../server/models'),
UserProvider = Models.User,
PermissionsProvider = Models.Permission,
PostProvider = Models.Post;
describe('Permissions', function () {
var sandbox;
before(function (done) {
testUtils.clearData().then(function () {
done();
}, done);
});
beforeEach(function (done) {
sandbox = sinon.sandbox.create();
testUtils.initData()
.then(testUtils.insertDefaultUser)
.then(testUtils.insertDefaultApp)
.then(function () {
done();
}, done);
});
afterEach(function (done) {
sandbox.restore();
testUtils.clearData()
.then(function () {
done();
}, done);
});
after(function (done) {
testUtils.clearData().then(function () {
done();
}, done);
});
var testPerms = [
{ act: "edit", obj: "post" },
{ act: "edit", obj: "tag" },
{ act: "edit", obj: "user" },
{ act: "edit", obj: "page" },
{ act: "add", obj: "post" },
{ act: "add", obj: "user" },
{ act: "add", obj: "page" },
{ act: "remove", obj: "post" },
{ act: "remove", obj: "user" }
],
currTestPermId = 1,
// currTestUserId = 1,
// createTestUser = function (email) {
// if (!email) {
// currTestUserId += 1;
// email = "test" + currTestPermId + "@test.com";
// }
// var newUser = {
// id: currTestUserId,
// email: email,
// password: "testing123"
// };
// return UserProvider.add(newUser);
// },
createPermission = function (name, act, obj) {
if (!name) {
currTestPermId += 1;
name = "test" + currTestPermId;
}
var newPerm = {
name: name,
action_type: act,
object_type: obj
};
return PermissionsProvider.add(newPerm);
},
createTestPermissions = function () {
var createActions = _.map(testPerms, function (testPerm) {
return createPermission(null, testPerm.act, testPerm.obj);
});
return when.all(createActions);
};
it('can load an actions map from existing permissions', function (done) {
createTestPermissions()
.then(permissions.init)
.then(function (actionsMap) {
should.exist(actionsMap);
actionsMap.edit.sort().should.eql(['post', 'tag', 'user', 'page'].sort());
actionsMap.should.equal(permissions.actionsMap);
done();
}).then(null, done);
});
it('can add user to role', function (done) {
var existingUserRoles;
UserProvider.read({id: 1}, { withRelated: ['roles'] }).then(function (foundUser) {
var testRole = new Models.Role({
name: 'testrole1',
description: 'testrole1 description'
});
should.exist(foundUser);
should.exist(foundUser.roles());
existingUserRoles = foundUser.related('roles').length;
return testRole.save().then(function () {
return foundUser.roles().attach(testRole);
});
}).then(function () {
return UserProvider.read({id: 1}, { withRelated: ['roles'] });
}).then(function (updatedUser) {
should.exist(updatedUser);
updatedUser.related('roles').length.should.equal(existingUserRoles + 1);
done();
}).then(null, done);
});
it('can add user permissions', function (done) {
Models.User.read({id: 1}, { withRelated: ['permissions']}).then(function (testUser) {
var testPermission = new Models.Permission({
name: "test edit posts",
action_type: 'edit',
object_type: 'post'
});
testUser.related('permissions').length.should.equal(0);
return testPermission.save().then(function () {
return testUser.permissions().attach(testPermission);
});
}).then(function () {
return Models.User.read({id: 1}, { withRelated: ['permissions']});
}).then(function (updatedUser) {
should.exist(updatedUser);
updatedUser.related('permissions').length.should.equal(1);
done();
}).then(null, done);
});
it('can add role permissions', function (done) {
var testRole = new Models.Role({
name: "test2",
description: "test2 description"
});
testRole.save()
.then(function () {
return testRole.load('permissions');
})
.then(function () {
var rolePermission = new Models.Permission({
name: "test edit posts",
action_type: 'edit',
object_type: 'post'
});
testRole.related('permissions').length.should.equal(0);
return rolePermission.save().then(function () {
return testRole.permissions().attach(rolePermission);
});
})
.then(function () {
return Models.Role.read({id: testRole.id}, { withRelated: ['permissions']});
})
.then(function (updatedRole) {
should.exist(updatedRole);
updatedRole.related('permissions').length.should.equal(1);
done();
}).then(null, done);
});
it('does not allow edit post without permission', function (done) {
var fakePage = {
id: 1
};
createTestPermissions()
.then(permissions.init)
.then(function () {
return Models.User.read({id: 1});
})
.then(function (foundUser) {
var canThisResult = permissions.canThis(foundUser);
should.exist(canThisResult.edit);
should.exist(canThisResult.edit.post);
return canThisResult.edit.page(fakePage);
})
.then(function () {
errors.logError(new Error("Allowed edit post without permission"));
}, done);
});
it('allows edit post with permission', function (done) {
var fakePost = {
id: "1"
};
createTestPermissions()
.then(permissions.init)
.then(function () {
return Models.User.read({id: 1});
})
.then(function (foundUser) {
var newPerm = new Models.Permission({
name: "test3 edit post",
action_type: "edit",
object_type: "post"
});
return newPerm.save().then(function () {
return foundUser.permissions().attach(newPerm);
});
})
.then(function () {
return Models.User.read({id: 1}, { withRelated: ['permissions']});
})
.then(function (updatedUser) {
// TODO: Verify updatedUser.related('permissions') has the permission?
2013-08-16 03:22:08 +04:00
var canThisResult = permissions.canThis(updatedUser.id);
should.exist(canThisResult.edit);
should.exist(canThisResult.edit.post);
return canThisResult.edit.post(fakePost);
})
.then(function () {
done();
}, done);
});
it('can use permissable function on Model to allow something', function (done) {
var testUser,
permissableStub = sandbox.stub(PostProvider, 'permissable', function () {
return when.resolve();
});
// createTestUser()
UserProvider.browse()
.then(function (foundUser) {
testUser = foundUser.models[0];
return permissions.canThis(testUser).edit.post(123);
})
.then(function () {
permissableStub.restore();
permissableStub.calledWith(123, testUser.id, 'edit').should.equal(true);
done();
})
.otherwise(function () {
permissableStub.restore();
errors.logError(new Error("Did not allow testUser"));
done();
});
});
it('can use permissable function on Model to forbid something', function (done) {
var testUser,
permissableStub = sandbox.stub(PostProvider, 'permissable', function () {
return when.reject();
});
// createTestUser()
UserProvider.browse()
.then(function (foundUser) {
testUser = foundUser.models[0];
return permissions.canThis(testUser).edit.post(123);
})
.then(function () {
permissableStub.restore();
done(new Error("Allowed testUser to edit post"));
})
.otherwise(function () {
permissableStub.restore();
permissableStub.calledWith(123, { user: testUser.id, app: null }, 'edit').should.equal(true);
done();
});
});
it("can get effective user permissions", function (done) {
effectivePerms.user(1).then(function (effectivePermissions) {
should.exist(effectivePermissions);
effectivePermissions.length.should.be.above(0);
done();
}).then(null, done);
});
it('can check an apps effective permissions', function (done) {
effectivePerms.app('Kudos')
.then(function (effectivePermissions) {
should.exist(effectivePermissions);
effectivePermissions.length.should.be.above(0);
done();
})
.otherwise(done);
});
it('does not allow an app to edit a post without permission', function (done) {
// Change the author of the post so the author override doesn't affect the test
PostProvider.edit({id: 1, 'author_id': 2})
.then(function (updatedPost) {
// Add user permissions
return Models.User.read({id: 1})
.then(function (foundUser) {
var newPerm = new Models.Permission({
name: "app test edit post",
action_type: "edit",
object_type: "post"
});
return newPerm.save().then(function () {
return foundUser.permissions().attach(newPerm).then(function () {
return when.all([updatedPost, foundUser]);
});
});
});
})
.then(function (results) {
var updatedPost = results[0],
updatedUser = results[1];
return permissions.canThis({ user: updatedUser.id })
.edit
.post(updatedPost.id)
.then(function () {
return results;
})
.otherwise(function (err) {
done(new Error("Did not allow user 1 to edit post 1"));
});
})
.then(function (results) {
var updatedPost = results[0],
updatedUser = results[1];
// Confirm app cannot edit it.
return permissions.canThis({ app: 'Hemingway', user: updatedUser.id })
.edit
.post(updatedPost.id)
.then(function () {
done(new Error("Allowed an edit of post 1"));
})
.otherwise(function () {
done();
});
}).otherwise(done);
});
it('allows an app to edit a post with permission', function (done) {
permissions.canThis({ app: 'Kudos', user: 1 })
.edit
.post(1)
.then(function () {
done();
})
.otherwise(function () {
done(new Error("Allowed an edit of post 1"));
});
});
});