Merge pull request #2673 from strongloop/fix/acl-related-model-resolution-2x
Fix acl related model resolution
This commit is contained in:
commit
f99e1a0242
|
@ -394,7 +394,9 @@ module.exports = function(ACL) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ACL.checkAccessForContext = function(context, callback) {
|
ACL.checkAccessForContext = function(context, callback) {
|
||||||
var registry = this.registry;
|
var self = this;
|
||||||
|
self.resolveRelatedModels();
|
||||||
|
var roleModel = self.roleModel;
|
||||||
|
|
||||||
if (!(context instanceof AccessContext)) {
|
if (!(context instanceof AccessContext)) {
|
||||||
context = new AccessContext(context);
|
context = new AccessContext(context);
|
||||||
|
@ -417,11 +419,9 @@ module.exports = function(ACL) {
|
||||||
var req = new AccessRequest(modelName, property, accessType, ACL.DEFAULT, methodNames);
|
var req = new AccessRequest(modelName, property, accessType, ACL.DEFAULT, methodNames);
|
||||||
|
|
||||||
var effectiveACLs = [];
|
var effectiveACLs = [];
|
||||||
var staticACLs = this.getStaticACLs(model.modelName, property);
|
var staticACLs = self.getStaticACLs(model.modelName, property);
|
||||||
|
|
||||||
var self = this;
|
self.find({where: {model: model.modelName, property: propertyQuery,
|
||||||
var roleModel = registry.getModelByType(Role);
|
|
||||||
this.find({where: {model: model.modelName, property: propertyQuery,
|
|
||||||
accessType: accessTypeQuery}}, function(err, acls) {
|
accessType: accessTypeQuery}}, function(err, acls) {
|
||||||
if (err) {
|
if (err) {
|
||||||
if (callback) callback(err);
|
if (callback) callback(err);
|
||||||
|
@ -507,10 +507,10 @@ module.exports = function(ACL) {
|
||||||
ACL.resolveRelatedModels = function() {
|
ACL.resolveRelatedModels = function() {
|
||||||
if (!this.roleModel) {
|
if (!this.roleModel) {
|
||||||
var reg = this.registry;
|
var reg = this.registry;
|
||||||
this.roleModel = reg.getModelByType(loopback.Role);
|
this.roleModel = reg.getModelByType('Role');
|
||||||
this.roleMappingModel = reg.getModelByType(loopback.RoleMapping);
|
this.roleMappingModel = reg.getModelByType('RoleMapping');
|
||||||
this.userModel = reg.getModelByType(loopback.User);
|
this.userModel = reg.getModelByType('User');
|
||||||
this.applicationModel = reg.getModelByType(loopback.Application);
|
this.applicationModel = reg.getModelByType('Application');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -152,6 +152,34 @@ describe('access control - integration', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('/banks', function() {
|
describe('/banks', function() {
|
||||||
|
var SPECIAL_USER = { email: 'special@test.test', password: 'test' };
|
||||||
|
|
||||||
|
// define dynamic role that would only grant access when the authenticated user's email is equal to
|
||||||
|
// SPECIAL_USER's email
|
||||||
|
|
||||||
|
before(function() {
|
||||||
|
var roleModel = app.registry.getModel('Role');
|
||||||
|
var userModel = app.registry.getModel('user');
|
||||||
|
|
||||||
|
roleModel.registerResolver('$dynamic-role', function(role, context, callback) {
|
||||||
|
if (!(context && context.accessToken && context.accessToken.userId)) {
|
||||||
|
return process.nextTick(function() {
|
||||||
|
callback && callback(null, false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var accessToken = context.accessToken;
|
||||||
|
userModel.findById(accessToken.userId, function(err, user) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err, false);
|
||||||
|
}
|
||||||
|
if (user && user.email === SPECIAL_USER.email) {
|
||||||
|
return callback(null, true);
|
||||||
|
}
|
||||||
|
return callback(null, false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
lt.beforeEach.givenModel('bank');
|
lt.beforeEach.givenModel('bank');
|
||||||
|
|
||||||
lt.it.shouldBeAllowedWhenCalledAnonymously('GET', '/api/banks');
|
lt.it.shouldBeAllowedWhenCalledAnonymously('GET', '/api/banks');
|
||||||
|
@ -173,6 +201,7 @@ describe('access control - integration', function() {
|
||||||
lt.it.shouldBeDeniedWhenCalledAnonymously('DELETE', urlForBank);
|
lt.it.shouldBeDeniedWhenCalledAnonymously('DELETE', urlForBank);
|
||||||
lt.it.shouldBeDeniedWhenCalledUnauthenticated('DELETE', urlForBank);
|
lt.it.shouldBeDeniedWhenCalledUnauthenticated('DELETE', urlForBank);
|
||||||
lt.it.shouldBeDeniedWhenCalledByUser(CURRENT_USER, 'DELETE', urlForBank);
|
lt.it.shouldBeDeniedWhenCalledByUser(CURRENT_USER, 'DELETE', urlForBank);
|
||||||
|
lt.it.shouldBeAllowedWhenCalledByUser(SPECIAL_USER, 'DELETE', urlForBank);
|
||||||
|
|
||||||
function urlForBank() {
|
function urlForBank() {
|
||||||
return '/api/banks/' + this.bank.id;
|
return '/api/banks/' + this.bank.id;
|
||||||
|
|
|
@ -22,6 +22,12 @@
|
||||||
"permission": "ALLOW",
|
"permission": "ALLOW",
|
||||||
"principalType": "ROLE",
|
"principalType": "ROLE",
|
||||||
"principalId": "$everyone"
|
"principalId": "$everyone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"accessType": "WRITE",
|
||||||
|
"permission": "ALLOW",
|
||||||
|
"principalType": "ROLE",
|
||||||
|
"principalId": "$dynamic-role"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"properties": {}
|
"properties": {}
|
||||||
|
|
|
@ -5,7 +5,10 @@
|
||||||
|
|
||||||
var loopback = require('../../../..');
|
var loopback = require('../../../..');
|
||||||
var boot = require('loopback-boot');
|
var boot = require('loopback-boot');
|
||||||
var app = module.exports = loopback({ localRegistry: true });
|
var app = module.exports = loopback({
|
||||||
|
localRegistry: true,
|
||||||
|
loadBuiltinModels: true
|
||||||
|
});
|
||||||
|
|
||||||
boot(app, __dirname);
|
boot(app, __dirname);
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,11 @@
|
||||||
|
|
||||||
var loopback = require('../../../../index');
|
var loopback = require('../../../../index');
|
||||||
var boot = require('loopback-boot');
|
var boot = require('loopback-boot');
|
||||||
var app = module.exports = loopback({ localRegistry: true });
|
var app = module.exports = loopback({
|
||||||
|
localRegistry: true,
|
||||||
|
loadBuiltinModels: true
|
||||||
|
});
|
||||||
|
|
||||||
app.enableAuth();
|
app.enableAuth();
|
||||||
boot(app, __dirname);
|
boot(app, __dirname);
|
||||||
app.use(loopback.token({model: app.models.AccessToken}));
|
app.use(loopback.token({model: app.models.AccessToken}));
|
||||||
|
|
Loading…
Reference in New Issue