Make ACL model subclassing friendly
This commit is contained in:
parent
f155ba46c7
commit
d8647bb3c1
|
@ -294,9 +294,9 @@ ACL.checkPermission = function checkPermission(principalType, principalId,
|
||||||
|
|
||||||
var req = new AccessRequest(model, property, accessType);
|
var req = new AccessRequest(model, property, accessType);
|
||||||
|
|
||||||
var acls = ACL.getStaticACLs(model, property);
|
var acls = this.getStaticACLs(model, property);
|
||||||
|
|
||||||
var resolved = ACL.resolvePermission(acls, req);
|
var resolved = this.resolvePermission(acls, req);
|
||||||
|
|
||||||
if(resolved && resolved.permission === ACL.DENY) {
|
if(resolved && resolved.permission === ACL.DENY) {
|
||||||
debug('Permission denied by statically resolved permission');
|
debug('Permission denied by statically resolved permission');
|
||||||
|
@ -307,7 +307,8 @@ ACL.checkPermission = function checkPermission(principalType, principalId,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ACL.find({where: {principalType: principalType, principalId: principalId,
|
var self = this;
|
||||||
|
this.find({where: {principalType: principalType, principalId: principalId,
|
||||||
model: model, property: propertyQuery, accessType: accessTypeQuery}},
|
model: model, property: propertyQuery, accessType: accessTypeQuery}},
|
||||||
function (err, dynACLs) {
|
function (err, dynACLs) {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -315,7 +316,7 @@ ACL.checkPermission = function checkPermission(principalType, principalId,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
acls = acls.concat(dynACLs);
|
acls = acls.concat(dynACLs);
|
||||||
resolved = ACL.resolvePermission(acls, req);
|
resolved = self.resolvePermission(acls, req);
|
||||||
if(resolved && resolved.permission === ACL.DEFAULT) {
|
if(resolved && resolved.permission === ACL.DEFAULT) {
|
||||||
var modelClass = loopback.getModel(model);
|
var modelClass = loopback.getModel(model);
|
||||||
resolved.permission = (modelClass && modelClass.settings.defaultPermission) || ACL.ALLOW;
|
resolved.permission = (modelClass && modelClass.settings.defaultPermission) || ACL.ALLOW;
|
||||||
|
@ -326,7 +327,7 @@ ACL.checkPermission = function checkPermission(principalType, principalId,
|
||||||
|
|
||||||
ACL.prototype.debug = function() {
|
ACL.prototype.debug = function() {
|
||||||
if(debug.enabled) {
|
if(debug.enabled) {
|
||||||
debug('---ACL---')
|
debug('---ACL---');
|
||||||
debug('model %s', this.model);
|
debug('model %s', this.model);
|
||||||
debug('property %s', this.property);
|
debug('property %s', this.property);
|
||||||
debug('principalType %s', this.principalType);
|
debug('principalType %s', this.principalType);
|
||||||
|
@ -361,9 +362,10 @@ ACL.checkAccess = function (context, callback) {
|
||||||
var req = new AccessRequest(model.modelName, property, accessType);
|
var req = new AccessRequest(model.modelName, property, accessType);
|
||||||
|
|
||||||
var effectiveACLs = [];
|
var effectiveACLs = [];
|
||||||
var staticACLs = ACL.getStaticACLs(model.modelName, property);
|
var staticACLs = this.getStaticACLs(model.modelName, property);
|
||||||
|
|
||||||
ACL.find({where: {model: model.modelName, property: propertyQuery,
|
var self = this;
|
||||||
|
this.find({where: {model: model.modelName, property: propertyQuery,
|
||||||
accessType: accessTypeQuery}}, function (err, acls) {
|
accessType: accessTypeQuery}}, function (err, acls) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback && callback(err);
|
callback && callback(err);
|
||||||
|
@ -403,7 +405,7 @@ ACL.checkAccess = function (context, callback) {
|
||||||
callback && callback(err, null);
|
callback && callback(err, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var resolved = ACL.resolvePermission(effectiveACLs, req);
|
var resolved = self.resolvePermission(effectiveACLs, req);
|
||||||
debug('checkAccess() returns: %j', resolved);
|
debug('checkAccess() returns: %j', resolved);
|
||||||
callback && callback(null, resolved);
|
callback && callback(null, resolved);
|
||||||
});
|
});
|
||||||
|
@ -437,7 +439,7 @@ ACL.checkAccessForToken = function (token, model, modelId, method, callback) {
|
||||||
|
|
||||||
context.debug();
|
context.debug();
|
||||||
|
|
||||||
ACL.checkAccess(context, function (err, access) {
|
this.checkAccess(context, function (err, access) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback && callback(err);
|
callback && callback(err);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -53,7 +53,8 @@ RoleMapping.ROLE = 'ROLE';
|
||||||
*/
|
*/
|
||||||
RoleMapping.prototype.application = function (callback) {
|
RoleMapping.prototype.application = function (callback) {
|
||||||
if (this.principalType === RoleMapping.APPLICATION) {
|
if (this.principalType === RoleMapping.APPLICATION) {
|
||||||
loopback.Application.findById(this.principalId, callback);
|
var applicationModel = this.constructor.Application || loopback.Application;
|
||||||
|
applicationModel.findById(this.principalId, callback);
|
||||||
} else {
|
} else {
|
||||||
process.nextTick(function () {
|
process.nextTick(function () {
|
||||||
callback && callback(null, null);
|
callback && callback(null, null);
|
||||||
|
@ -69,6 +70,7 @@ RoleMapping.prototype.application = function (callback) {
|
||||||
*/
|
*/
|
||||||
RoleMapping.prototype.user = function (callback) {
|
RoleMapping.prototype.user = function (callback) {
|
||||||
if (this.principalType === RoleMapping.USER) {
|
if (this.principalType === RoleMapping.USER) {
|
||||||
|
var userModel = this.constructor.User || loopback.User;
|
||||||
loopback.User.findById(this.principalId, callback);
|
loopback.User.findById(this.principalId, callback);
|
||||||
} else {
|
} else {
|
||||||
process.nextTick(function () {
|
process.nextTick(function () {
|
||||||
|
@ -85,7 +87,8 @@ RoleMapping.prototype.user = function (callback) {
|
||||||
*/
|
*/
|
||||||
RoleMapping.prototype.childRole = function (callback) {
|
RoleMapping.prototype.childRole = function (callback) {
|
||||||
if (this.principalType === RoleMapping.ROLE) {
|
if (this.principalType === RoleMapping.ROLE) {
|
||||||
loopback.User.findById(this.principalId, callback);
|
var roleModel = this.constructor.Role || Role;
|
||||||
|
roleModel.findById(this.principalId, callback);
|
||||||
} else {
|
} else {
|
||||||
process.nextTick(function () {
|
process.nextTick(function () {
|
||||||
callback && callback(null, null);
|
callback && callback(null, null);
|
||||||
|
@ -107,10 +110,13 @@ var Role = loopback.createModel('Role', RoleSchema, {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Role.RoleMapping = RoleMapping;
|
||||||
|
|
||||||
// Set up the connection to users/applications/roles once the model
|
// Set up the connection to users/applications/roles once the model
|
||||||
Role.once('dataSourceAttached', function () {
|
Role.once('dataSourceAttached', function () {
|
||||||
|
var roleMappingModel = this.RoleMapping || RoleMapping;
|
||||||
Role.prototype.users = function (callback) {
|
Role.prototype.users = function (callback) {
|
||||||
RoleMapping.find({where: {roleId: this.id,
|
roleMappingModel.find({where: {roleId: this.id,
|
||||||
principalType: RoleMapping.USER}}, function (err, mappings) {
|
principalType: RoleMapping.USER}}, function (err, mappings) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback && callback(err);
|
callback && callback(err);
|
||||||
|
@ -123,7 +129,7 @@ Role.once('dataSourceAttached', function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
Role.prototype.applications = function (callback) {
|
Role.prototype.applications = function (callback) {
|
||||||
RoleMapping.find({where: {roleId: this.id,
|
roleMappingModel.find({where: {roleId: this.id,
|
||||||
principalType: RoleMapping.APPLICATION}}, function (err, mappings) {
|
principalType: RoleMapping.APPLICATION}}, function (err, mappings) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback && callback(err);
|
callback && callback(err);
|
||||||
|
@ -136,7 +142,7 @@ Role.once('dataSourceAttached', function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
Role.prototype.roles = function (callback) {
|
Role.prototype.roles = function (callback) {
|
||||||
RoleMapping.find({where: {roleId: this.id,
|
roleMappingModel.find({where: {roleId: this.id,
|
||||||
principalType: RoleMapping.ROLE}}, function (err, mappings) {
|
principalType: RoleMapping.ROLE}}, function (err, mappings) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback && callback(err);
|
callback && callback(err);
|
||||||
|
@ -330,7 +336,8 @@ Role.isInRole = function (role, context, callback) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Role.findOne({where: {name: role}}, function (err, result) {
|
var roleMappingModel = this.RoleMapping || RoleMapping;
|
||||||
|
this.findOne({where: {name: role}}, function (err, result) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback && callback(err);
|
callback && callback(err);
|
||||||
return;
|
return;
|
||||||
|
@ -346,7 +353,7 @@ Role.isInRole = function (role, context, callback) {
|
||||||
var principalType = p.type || undefined;
|
var principalType = p.type || undefined;
|
||||||
var principalId = p.id || undefined;
|
var principalId = p.id || undefined;
|
||||||
if (principalType && principalId) {
|
if (principalType && principalId) {
|
||||||
RoleMapping.findOne({where: {roleId: result.id,
|
roleMappingModel.findOne({where: {roleId: result.id,
|
||||||
principalType: principalType, principalId: principalId}},
|
principalType: principalType, principalId: principalId}},
|
||||||
function (err, result) {
|
function (err, result) {
|
||||||
debug('Role mapping found: %j', result);
|
debug('Role mapping found: %j', result);
|
||||||
|
@ -388,11 +395,12 @@ Role.getRoles = function (context, callback) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var self = this;
|
||||||
// Check against the smart roles
|
// Check against the smart roles
|
||||||
var inRoleTasks = [];
|
var inRoleTasks = [];
|
||||||
Object.keys(Role.resolvers).forEach(function (role) {
|
Object.keys(Role.resolvers).forEach(function (role) {
|
||||||
inRoleTasks.push(function (done) {
|
inRoleTasks.push(function (done) {
|
||||||
Role.isInRole(role, context, function (err, inRole) {
|
self.isInRole(role, context, function (err, inRole) {
|
||||||
if (!err && inRole) {
|
if (!err && inRole) {
|
||||||
addRole(role);
|
addRole(role);
|
||||||
done();
|
done();
|
||||||
|
@ -403,6 +411,7 @@ Role.getRoles = function (context, callback) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var roleMappingModel = this.RoleMapping || RoleMapping;
|
||||||
context.principals.forEach(function (p) {
|
context.principals.forEach(function (p) {
|
||||||
// Check against the role mappings
|
// Check against the role mappings
|
||||||
var principalType = p.type || undefined;
|
var principalType = p.type || undefined;
|
||||||
|
@ -416,7 +425,7 @@ Role.getRoles = function (context, callback) {
|
||||||
if (principalType && principalId) {
|
if (principalType && principalId) {
|
||||||
// Please find() treat undefined matches all values
|
// Please find() treat undefined matches all values
|
||||||
inRoleTasks.push(function (done) {
|
inRoleTasks.push(function (done) {
|
||||||
RoleMapping.find({where: {principalType: principalType,
|
roleMappingModel.find({where: {principalType: principalType,
|
||||||
principalId: principalId}}, function (err, mappings) {
|
principalId: principalId}}, function (err, mappings) {
|
||||||
debug('Role mappings found: %s %j', err, mappings);
|
debug('Role mappings found: %s %j', err, mappings);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|
Loading…
Reference in New Issue