loopback/test/route-acl.test.js

203 lines
4.2 KiB
JavaScript

var routeAcl = require('../server/middleware/acl');
var loopback = require('../index');
var options = {
scopes: {
catalog: [{
'methods': 'GET',
'path': '/api/catalog'
}],
order: [{
methods: 'ALL',
path: '/api/orders'
}],
cancelOrder: [{
methods: 'delete',
'path': '/api/orders/:id'
}],
deleteEntities: [
{
methods: ['delete'],
path: '/api/:model'
}
]
},
acls: [
{
role: '$everyone',
scopes: ['catalog'],
permission: 'ALLOW'
},
{
role: '$unauthenticated',
scopes: ['order'],
permission: 'DENY'
},
{
role: '$everyone',
scopes: ['deleteEntities'],
permission: 'DENY'
},
{
principalType: 'ROLE',
principalId: 'admin',
scopes: ['deleteEntities'],
permission: 'ALLOW'
},
{
principalType: 'ROLE',
principalId: 'cs',
scopes: ['cancelOrder'],
permission: 'ALLOW'
}
],
roles: {
admin: [
{principalType: 'USER', principalId: 'mary'}
],
demo: [
{principalType: 'USER', principalId: 'john'},
{principalType: 'APP', principalId: 'demo-app'}]
}
};
describe('route based ACLs', function() {
var handler;
before(function(done) {
handler = routeAcl(options);
var ds = loopback.createDataSource({
connector: 'memory',
name: 'db',
defaultForType: 'db'
});
loopback.Application.attachTo(ds);
loopback.User.attachTo(ds);
loopback.Role.attachTo(ds);
loopback.RoleMapping.attachTo(ds);
loopback.Role.create({name: 'cs'}, function(err, role) {
if (err) return done(err);
loopback.RoleMapping.create(
{roleId: role.id, principalType: 'USER', principalId: 'mike'}, done);
});
});
it('should allow $everyone to get /api/catalog', function(done) {
var req = {
method: 'get',
originalUrl: '/api/catalog',
url: '/api/catalog',
headers: {
'Accept': 'application/json'
},
query: {
filter: {
limit: 100
}
}
};
var res = {};
handler(req, res, done);
});
it('should allow $authenticated to get /api/catalog', function(done) {
var req = {
method: 'get',
originalUrl: '/api/catalog',
url: '/api/catalog',
headers: {
'Accept': 'application/json'
},
query: {
filter: {
limit: 100
}
},
accessToken: {
userId: 'john',
appId: 'demo-app'
}
};
var res = {};
handler(req, res, done);
});
it('should deny $unauthenticated get /api/orders', function(done) {
var req = {
method: 'get',
url: '/api/orders',
headers: {
'Accept': 'application/json'
},
query: {
filter: {
limit: 100
}
}
};
var res = {};
handler(req, res, function(err) {
if (err) return done();
else {
return done(new Error('The request should be denied'));
}
});
});
it('should allow deletes for admin users', function(done) {
var req = {
method: 'delete',
originalUrl: '/api/catalog',
url: '/api/catalog',
headers: {
'Accept': 'application/json'
},
accessToken: {
userId: 'mary',
appId: 'demo-app'
}
};
var res = {};
handler(req, res, done);
});
it('should reject deletes for non-admin users', function(done) {
var req = {
method: 'delete',
originalUrl: '/api/catalog',
url: '/api/catalog',
headers: {
'Accept': 'application/json'
},
accessToken: {
userId: 'john',
appId: 'demo-app'
}
};
var res = {};
handler(req, res, function(err) {
if (err) return done();
else {
return done(new Error('The request should be denied'));
}
});
});
it('should allow cancel order for cs users', function(done) {
var req = {
method: 'delete',
url: '/api/orders/100',
headers: {
'Accept': 'application/json'
},
accessToken: {
userId: 'mike',
appId: 'demo-app'
}
};
var res = {};
handler(req, res, done);
});
});