Fix ACL check to support model wildcard

This commit is contained in:
Moshe Malka 2018-07-22 17:31:24 +03:00 committed by Miroslav Bajtoš
parent be91ba3dad
commit 29c5f20d90
No known key found for this signature in database
GPG Key ID: 6F2304BA9361C7E3
2 changed files with 62 additions and 17 deletions

View File

@ -478,8 +478,15 @@ module.exports = function(ACL) {
var effectiveACLs = [];
var staticACLs = self.getStaticACLs(model.modelName, property);
this.find({where: {model: model.modelName, property: propertyQuery,
accessType: accessTypeQuery}}, function(err, acls) {
const query = {
where: {
model: {inq: [model.modelName, ACL.ALL]},
property: propertyQuery,
accessType: accessTypeQuery,
},
};
this.find(query, function(err, acls) {
if (err) return callback(err);
var inRoleTasks = [];

View File

@ -15,16 +15,13 @@ var supertest = require('supertest');
var Role = loopback.Role;
var RoleMapping = loopback.RoleMapping;
var User = loopback.User;
var testModel;
var async = require('async');
// Speed up the password hashing algorithm for tests
User.settings.saltWorkFactor = 4;
var ds = null;
before(function() {
ds = loopback.createDataSource({connector: loopback.Memory});
});
var testModel;
describe('ACL model', function() {
it('provides DEFAULT_SCOPE constant', () => {
@ -33,16 +30,7 @@ describe('ACL model', function() {
});
describe('security scopes', function() {
beforeEach(function() {
var ds = this.ds = loopback.createDataSource({connector: loopback.Memory});
testModel = loopback.PersistedModel.extend('testModel');
ACL.attachTo(ds);
Role.attachTo(ds);
RoleMapping.attachTo(ds);
User.attachTo(ds);
Scope.attachTo(ds);
testModel.attachTo(ds);
});
beforeEach(setupTestModels);
it('should allow access to models for the given scope by wildcard', function(done) {
Scope.create({name: 'userScope', description: 'access user information'},
@ -98,6 +86,8 @@ describe('security scopes', function() {
});
describe('security ACLs', function() {
beforeEach(setupTestModels);
it('supports checkPermission() returning a promise', function() {
return ACL.create({
principalType: ACL.USER,
@ -115,6 +105,44 @@ describe('security ACLs', function() {
});
});
it('supports ACL rules with a wildcard for models', function() {
const A_USER_ID = 'a-test-user';
// By default, access is allowed to all users
return assertPermission(ACL.ALLOW, 'initial state')
// An ACL rule applying to all models denies access to everybody
.then(() => ACL.create({
model: '*',
property: '*',
accessType: '*',
principalType: 'ROLE',
principalId: '$everyone',
permission: 'DENY',
}))
.then(() => assertPermission(ACL.DENY, 'all denied'))
// A rule for a specific model overrides the rule matching all models
.then(() => ACL.create({
model: testModel.modelName,
property: '*',
accessType: '*',
principalType: ACL.USER,
principalId: A_USER_ID,
permission: ACL.ALLOW,
}))
.then(() => assertPermission(ACL.ALLOW, 'only a single model allowed'));
function assertPermission(expectedPermission, msg) {
return ACL.checkAccessForContext({
principals: [{type: ACL.USER, id: A_USER_ID}],
model: testModel.modelName,
accessType: ACL.ALL,
}).then(accessContext => {
const actual = accessContext.isAllowed() ? ACL.ALLOW : ACL.DENY;
expect(actual, msg).to.equal(expectedPermission);
});
}
});
it('supports checkAccessForContext() returning a promise', function() {
var testModel = ds.createModel('testModel', {
acls: [
@ -399,7 +427,6 @@ describe('security ACLs', function() {
});
it('should check access against LDL, ACL, and Role', function(done) {
// var log = console.log;
var log = function() {};
// Create
@ -645,3 +672,14 @@ describe('authorized roles propagation in RemotingContext', function() {
.expect(200);
}
});
function setupTestModels() {
ds = this.ds = loopback.createDataSource({connector: loopback.Memory});
testModel = loopback.PersistedModel.extend('testModel');
ACL.attachTo(ds);
Role.attachTo(ds);
RoleMapping.attachTo(ds);
User.attachTo(ds);
Scope.attachTo(ds);
testModel.attachTo(ds);
}