Fix ACL check to support model wildcard
This commit is contained in:
parent
be91ba3dad
commit
29c5f20d90
|
@ -478,8 +478,15 @@ module.exports = function(ACL) {
|
||||||
var effectiveACLs = [];
|
var effectiveACLs = [];
|
||||||
var staticACLs = self.getStaticACLs(model.modelName, property);
|
var staticACLs = self.getStaticACLs(model.modelName, property);
|
||||||
|
|
||||||
this.find({where: {model: model.modelName, property: propertyQuery,
|
const query = {
|
||||||
accessType: accessTypeQuery}}, function(err, acls) {
|
where: {
|
||||||
|
model: {inq: [model.modelName, ACL.ALL]},
|
||||||
|
property: propertyQuery,
|
||||||
|
accessType: accessTypeQuery,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
this.find(query, function(err, acls) {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
var inRoleTasks = [];
|
var inRoleTasks = [];
|
||||||
|
|
||||||
|
|
|
@ -15,16 +15,13 @@ var supertest = require('supertest');
|
||||||
var Role = loopback.Role;
|
var Role = loopback.Role;
|
||||||
var RoleMapping = loopback.RoleMapping;
|
var RoleMapping = loopback.RoleMapping;
|
||||||
var User = loopback.User;
|
var User = loopback.User;
|
||||||
var testModel;
|
|
||||||
var async = require('async');
|
var async = require('async');
|
||||||
|
|
||||||
// Speed up the password hashing algorithm for tests
|
// Speed up the password hashing algorithm for tests
|
||||||
User.settings.saltWorkFactor = 4;
|
User.settings.saltWorkFactor = 4;
|
||||||
|
|
||||||
var ds = null;
|
var ds = null;
|
||||||
before(function() {
|
var testModel;
|
||||||
ds = loopback.createDataSource({connector: loopback.Memory});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('ACL model', function() {
|
describe('ACL model', function() {
|
||||||
it('provides DEFAULT_SCOPE constant', () => {
|
it('provides DEFAULT_SCOPE constant', () => {
|
||||||
|
@ -33,16 +30,7 @@ describe('ACL model', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('security scopes', function() {
|
describe('security scopes', function() {
|
||||||
beforeEach(function() {
|
beforeEach(setupTestModels);
|
||||||
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);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should allow access to models for the given scope by wildcard', function(done) {
|
it('should allow access to models for the given scope by wildcard', function(done) {
|
||||||
Scope.create({name: 'userScope', description: 'access user information'},
|
Scope.create({name: 'userScope', description: 'access user information'},
|
||||||
|
@ -98,6 +86,8 @@ describe('security scopes', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('security ACLs', function() {
|
describe('security ACLs', function() {
|
||||||
|
beforeEach(setupTestModels);
|
||||||
|
|
||||||
it('supports checkPermission() returning a promise', function() {
|
it('supports checkPermission() returning a promise', function() {
|
||||||
return ACL.create({
|
return ACL.create({
|
||||||
principalType: ACL.USER,
|
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() {
|
it('supports checkAccessForContext() returning a promise', function() {
|
||||||
var testModel = ds.createModel('testModel', {
|
var testModel = ds.createModel('testModel', {
|
||||||
acls: [
|
acls: [
|
||||||
|
@ -399,7 +427,6 @@ describe('security ACLs', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should check access against LDL, ACL, and Role', function(done) {
|
it('should check access against LDL, ACL, and Role', function(done) {
|
||||||
// var log = console.log;
|
|
||||||
var log = function() {};
|
var log = function() {};
|
||||||
|
|
||||||
// Create
|
// Create
|
||||||
|
@ -645,3 +672,14 @@ describe('authorized roles propagation in RemotingContext', function() {
|
||||||
.expect(200);
|
.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);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue