loopback/test/acl.test.js

308 lines
10 KiB
JavaScript
Raw Normal View History

2013-11-10 06:22:16 +00:00
var assert = require('assert');
var loopback = require('../index');
var acl = require('../lib/models/acl');
2013-11-12 06:16:51 +00:00
var Scope = acl.Scope;
var ACL = acl.ACL;
2013-11-20 21:31:30 +00:00
var role = require('../lib/models/role');
var Role = role.Role;
var RoleMapping = role.RoleMapping;
2013-11-10 06:22:16 +00:00
var User = loopback.User;
var testModel;
2013-11-10 06:22:16 +00:00
2013-11-12 18:10:32 +00:00
function checkResult(err, result) {
// console.log(err, result);
assert(!err);
}
var ds = null;
before(function() {
ds = loopback.createDataSource({connector: loopback.Memory});
});
2013-11-10 06:22:16 +00:00
describe('security scopes', function () {
beforeEach(function() {
var ds = this.ds = loopback.createDataSource({connector: loopback.Memory});
2014-06-05 07:45:09 +00:00
testModel = loopback.PersistedModel.extend('testModel');
ACL.attachTo(ds);
Role.attachTo(ds);
RoleMapping.attachTo(ds);
User.attachTo(ds);
Scope.attachTo(ds);
testModel.attachTo(ds);
});
2013-11-12 06:16:51 +00:00
it("should allow access to models for the given scope by wildcard", function () {
2013-11-15 17:41:26 +00:00
Scope.create({name: 'userScope', description: 'access user information'}, function (err, scope) {
ACL.create({principalType: ACL.SCOPE, principalId: scope.id, model: 'User', property: ACL.ALL,
2013-11-13 18:02:59 +00:00
accessType: ACL.ALL, permission: ACL.ALLOW},
2013-11-12 18:10:32 +00:00
function (err, resource) {
2013-11-15 17:41:26 +00:00
Scope.checkPermission('userScope', 'User', ACL.ALL, ACL.ALL, checkResult);
Scope.checkPermission('userScope', 'User', 'name', ACL.ALL, checkResult);
Scope.checkPermission('userScope', 'User', 'name', ACL.READ, checkResult);
2013-11-10 06:22:16 +00:00
});
});
});
2013-11-12 06:16:51 +00:00
it("should allow access to models for the given scope", function () {
Scope.create({name: 'testModelScope', description: 'access testModel information'}, function (err, scope) {
2013-11-13 18:02:59 +00:00
ACL.create({principalType: ACL.SCOPE, principalId: scope.id,
model: 'testModel', property: 'name', accessType: ACL.READ, permission: ACL.ALLOW},
2013-11-12 18:10:32 +00:00
function (err, resource) {
2013-11-14 01:07:43 +00:00
ACL.create({principalType: ACL.SCOPE, principalId: scope.id,
model: 'testModel', property: 'name', accessType: ACL.WRITE, permission: ACL.DENY},
2013-11-14 01:07:43 +00:00
function (err, resource) {
// console.log(resource);
Scope.checkPermission('testModelScope', 'testModel', ACL.ALL, ACL.ALL, function (err, perm) {
2013-11-14 01:24:42 +00:00
assert(perm.permission === ACL.DENY); // because name.WRITE == DENY
2013-11-14 01:07:43 +00:00
});
Scope.checkPermission('testModelScope', 'testModel', 'name', ACL.ALL, function (err, perm) {
2013-11-14 01:24:42 +00:00
assert(perm.permission === ACL.DENY); // because name.WRITE == DENY
2013-11-14 01:07:43 +00:00
});
Scope.checkPermission('testModelScope', 'testModel', 'name', ACL.READ, function (err, perm) {
2013-11-14 01:07:43 +00:00
assert(perm.permission === ACL.ALLOW);
});
Scope.checkPermission('testModelScope', 'testModel', 'name', ACL.WRITE, function (err, perm) {
2013-11-14 01:07:43 +00:00
assert(perm.permission === ACL.DENY);
});
});
});
2013-11-12 06:16:51 +00:00
});
});
});
describe('security ACLs', function () {
it('should order ACL entries based on the matching score', function() {
var acls = [
{
"model": "account",
"accessType": "*",
"permission": "DENY",
"principalType": "ROLE",
"principalId": "$everyone"
},
{
"model": "account",
"accessType": "*",
"permission": "ALLOW",
"principalType": "ROLE",
"principalId": "$owner"
},
{
"model": "account",
"accessType": "READ",
"permission": "ALLOW",
"principalType": "ROLE",
"principalId": "$everyone"
}];
var req = {
model: 'account',
property: 'find',
accessType: 'WRITE'
};
acls = acls.map(function(a) { return new ACL(a)});
var perm = ACL.resolvePermission(acls, req);
assert.deepEqual(perm, { model: 'account',
property: 'find',
accessType: 'WRITE',
permission: 'ALLOW',
methodNames: []});
});
2013-11-12 06:16:51 +00:00
it("should allow access to models for the given principal by wildcard", function () {
2013-11-15 17:41:26 +00:00
ACL.create({principalType: ACL.USER, principalId: 'u001', model: 'User', property: ACL.ALL,
2013-11-12 18:10:32 +00:00
accessType: ACL.ALL, permission: ACL.ALLOW}, function (err, acl) {
2013-11-12 06:16:51 +00:00
2013-11-15 17:41:26 +00:00
ACL.create({principalType: ACL.USER, principalId: 'u001', model: 'User', property: ACL.ALL,
2013-11-14 01:24:42 +00:00
accessType: ACL.READ, permission: ACL.DENY}, function (err, acl) {
2013-11-15 17:41:26 +00:00
ACL.checkPermission(ACL.USER, 'u001', 'User', 'name', ACL.READ, function (err, perm) {
2013-11-14 01:24:42 +00:00
assert(perm.permission === ACL.DENY);
});
2013-11-15 17:41:26 +00:00
ACL.checkPermission(ACL.USER, 'u001', 'User', 'name', ACL.ALL, function (err, perm) {
2013-11-14 01:24:42 +00:00
assert(perm.permission === ACL.DENY);
});
});
2013-11-12 06:16:51 +00:00
});
});
it("should allow access to models by exception", function () {
ACL.create({principalType: ACL.USER, principalId: 'u001', model: 'testModel', property: ACL.ALL,
accessType: ACL.ALL, permission: ACL.DENY}, function (err, acl) {
ACL.create({principalType: ACL.USER, principalId: 'u001', model: 'testModel', property: ACL.ALL,
accessType: ACL.READ, permission: ACL.ALLOW}, function (err, acl) {
ACL.checkPermission(ACL.USER, 'u001', 'testModel', 'name', ACL.READ, function (err, perm) {
assert(perm.permission === ACL.ALLOW);
});
ACL.checkPermission(ACL.USER, 'u001', 'testModel', ACL.ALL, ACL.READ, function (err, perm) {
assert(perm.permission === ACL.ALLOW);
});
ACL.checkPermission(ACL.USER, 'u001', 'testModel', 'name', ACL.WRITE, function (err, perm) {
assert(perm.permission === ACL.DENY);
});
ACL.checkPermission(ACL.USER, 'u001', 'testModel', 'name', ACL.ALL, function (err, perm) {
assert(perm.permission === ACL.DENY);
});
});
});
});
2013-11-20 21:31:30 +00:00
it("should honor defaultPermission from the model", function () {
var Customer = ds.createModel('Customer', {
name: {
type: String,
acls: [
{principalType: ACL.USER, principalId: 'u001', accessType: ACL.WRITE, permission: ACL.DENY},
{principalType: ACL.USER, principalId: 'u001', accessType: ACL.ALL, permission: ACL.ALLOW}
]
}
}, {
acls: [
{principalType: ACL.USER, principalId: 'u001', accessType: ACL.ALL, permission: ACL.ALLOW}
]
});
Customer.settings.defaultPermission = ACL.DENY;
ACL.checkPermission(ACL.USER, 'u001', 'Customer', 'name', ACL.WRITE, function (err, perm) {
assert(perm.permission === ACL.DENY);
});
ACL.checkPermission(ACL.USER, 'u001', 'Customer', 'name', ACL.READ, function (err, perm) {
assert(perm.permission === ACL.ALLOW);
});
ACL.checkPermission(ACL.USER, 'u002', 'Customer', 'name', ACL.WRITE, function (err, perm) {
assert(perm.permission === ACL.DENY);
});
});
2013-11-15 17:41:26 +00:00
it("should honor static ACLs from the model", function () {
var Customer = ds.createModel('Customer', {
name: {
type: String,
acls: [
{principalType: ACL.USER, principalId: 'u001', accessType: ACL.WRITE, permission: ACL.DENY},
{principalType: ACL.USER, principalId: 'u001', accessType: ACL.ALL, permission: ACL.ALLOW}
]
}
}, {
acls: [
{principalType: ACL.USER, principalId: 'u001', accessType: ACL.ALL, permission: ACL.ALLOW}
]
});
/*
Customer.settings.acls = [
{principalType: ACL.USER, principalId: 'u001', accessType: ACL.ALL, permission: ACL.ALLOW}
];
*/
ACL.checkPermission(ACL.USER, 'u001', 'Customer', 'name', ACL.WRITE, function (err, perm) {
assert(perm.permission === ACL.DENY);
});
ACL.checkPermission(ACL.USER, 'u001', 'Customer', 'name', ACL.READ, function (err, perm) {
assert(perm.permission === ACL.ALLOW);
});
ACL.checkPermission(ACL.USER, 'u001', 'Customer', 'name', ACL.ALL, function (err, perm) {
assert(perm.permission === ACL.ALLOW);
2013-11-15 17:41:26 +00:00
});
});
2013-11-20 21:31:30 +00:00
it("should check access against LDL, ACL, and Role", function () {
// var log = console.log;
var log = function() {};
// Create
User.create({name: 'Raymond', email: 'x@y.com', password: 'foobar'}, function (err, user) {
log('User: ', user.toObject());
var userId = user.id;
2013-11-20 21:31:30 +00:00
// Define a model with static ACLs
var Customer = ds.createModel('Customer', {
name: {
type: String,
acls: [
{principalType: ACL.USER, principalId: userId, accessType: ACL.WRITE, permission: ACL.DENY},
{principalType: ACL.USER, principalId: userId, accessType: ACL.ALL, permission: ACL.ALLOW}
2013-11-20 21:31:30 +00:00
]
}
}, {
acls: [
{principalType: ACL.USER, principalId: userId, accessType: ACL.ALL, permission: ACL.ALLOW}
2014-01-16 23:05:10 +00:00
],
defaultPermission: 'DENY'
2013-11-20 21:31:30 +00:00
});
ACL.create({principalType: ACL.USER, principalId: userId, model: 'Customer', property: ACL.ALL,
2013-11-20 21:31:30 +00:00
accessType: ACL.ALL, permission: ACL.ALLOW}, function (err, acl) {
log('ACL 1: ', acl.toObject());
Role.create({name: 'MyRole'}, function (err, myRole) {
log('Role: ', myRole.toObject());
myRole.principals.create({principalType: RoleMapping.USER, principalId: userId}, function (err, p) {
2013-11-20 21:31:30 +00:00
log('Principal added to role: ', p.toObject());
ACL.create({principalType: ACL.ROLE, principalId: 'MyRole', model: 'Customer', property: ACL.ALL,
2013-11-20 21:31:30 +00:00
accessType: ACL.READ, permission: ACL.DENY}, function (err, acl) {
log('ACL 2: ', acl.toObject());
ACL.checkAccessForContext({
2013-11-20 21:31:30 +00:00
principals: [
{type: ACL.USER, id: userId}
2013-11-20 21:31:30 +00:00
],
model: 'Customer',
property: 'name',
accessType: ACL.READ
}, function(err, access) {
assert(!err && access.permission === ACL.ALLOW);
});
2014-01-16 23:05:10 +00:00
ACL.checkAccessForContext({
2014-01-16 23:05:10 +00:00
principals: [
{type: ACL.ROLE, id: Role.EVERYONE}
],
model: 'Customer',
property: 'name',
accessType: ACL.READ
}, function(err, access) {
assert(!err && access.permission === ACL.DENY);
});
2013-11-20 21:31:30 +00:00
});
});
});
});
});
});
2013-11-10 06:22:16 +00:00
});