Add access type checking
This commit is contained in:
parent
4e1e3afb74
commit
216fee3015
|
@ -361,11 +361,14 @@ ACL.checkAccessForToken = function(token, model, modelId, method, callback) {
|
|||
if(token.appId) {
|
||||
principals.push({principalType: ACL.APPLICATION, principalId: token.appId});
|
||||
}
|
||||
|
||||
var modelCtor = loopback.getModel(model);
|
||||
|
||||
var context = {
|
||||
principals: principals,
|
||||
model: model,
|
||||
property: method,
|
||||
accessType: ACL.EXECUTE,
|
||||
accessType: modelCtor._getAccessTypeForMethod(method),
|
||||
id: modelId
|
||||
};
|
||||
ACL.checkAccess(context, function(err, access) {
|
||||
|
|
|
@ -20,11 +20,6 @@ Model.shared = true;
|
|||
Model.setup = function () {
|
||||
var ModelCtor = this;
|
||||
|
||||
// each model has its
|
||||
// own access control
|
||||
// list
|
||||
ModelCtor.acl = [];
|
||||
|
||||
ModelCtor.sharedCtor = function (data, id, fn) {
|
||||
if(typeof data === 'function') {
|
||||
fn = data;
|
||||
|
@ -138,6 +133,54 @@ Model.checkAccess = function(token, modelId, method, callback) {
|
|||
ACL.checkAccessForToken(token, this.modelName, modelId, methodName, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Determine the access type for the given `RemoteMethod`.
|
||||
*
|
||||
* @api private
|
||||
* @param {RemoteMethod} method
|
||||
*/
|
||||
|
||||
Model._getAccessTypeForMethod = function(method) {
|
||||
if(typeof method === 'string') {
|
||||
method = {name: method};
|
||||
}
|
||||
assert(
|
||||
typeof method === 'object',
|
||||
'method is a required argument and must be a RemoteMethod object'
|
||||
);
|
||||
|
||||
var ACL = getACL();
|
||||
|
||||
switch(method.name) {
|
||||
case'create':
|
||||
return ACL.WRITE;
|
||||
case 'updateOrCreate':
|
||||
return ACL.WRITE;
|
||||
case 'upsert':
|
||||
return ACL.WRITE;
|
||||
case 'exists':
|
||||
return ACL.READ;
|
||||
case 'findById':
|
||||
return ACL.READ;
|
||||
case 'find':
|
||||
return ACL.READ;
|
||||
case 'findOne':
|
||||
return ACL.READ;
|
||||
case 'destroyById':
|
||||
return ACL.WRITE;
|
||||
case 'deleteById':
|
||||
return ACL.WRITE;
|
||||
case 'removeById':
|
||||
return ACL.WRITE;
|
||||
case 'count':
|
||||
return ACL.READ;
|
||||
break;
|
||||
default:
|
||||
return ACL.EXECUTE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// setup the initial model
|
||||
Model.setup();
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
var ACL = require('../').ACL;
|
||||
|
||||
describe('Model', function() {
|
||||
|
||||
var User, memory;
|
||||
|
@ -552,6 +554,33 @@ describe('Model', function() {
|
|||
|
||||
});
|
||||
|
||||
describe('Model.checkAccessTypeForMethod(remoteMethod)', function () {
|
||||
shouldReturn('create', ACL.WRITE);
|
||||
shouldReturn('updateOrCreate', ACL.WRITE);
|
||||
shouldReturn('upsert', ACL.WRITE);
|
||||
shouldReturn('exists', ACL.READ);
|
||||
shouldReturn('findById', ACL.READ);
|
||||
shouldReturn('find', ACL.READ);
|
||||
shouldReturn('findOne', ACL.READ);
|
||||
shouldReturn('destroyById', ACL.WRITE);
|
||||
shouldReturn('deleteById', ACL.WRITE);
|
||||
shouldReturn('removeById', ACL.WRITE);
|
||||
shouldReturn('count', ACL.READ);
|
||||
shouldReturn('unkown-model-method', ACL.EXECUTE);
|
||||
|
||||
function shouldReturn(methodName, expectedAccessType) {
|
||||
describe(methodName, function () {
|
||||
it('should return ' + expectedAccessType, function() {
|
||||
var remoteMethod = {name: methodName};
|
||||
assert.equal(
|
||||
User._getAccessTypeForMethod(remoteMethod),
|
||||
expectedAccessType
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// describe('Model.hasAndBelongsToMany()', function() {
|
||||
// it("TODO: implement / document", function(done) {
|
||||
// /* example -
|
||||
|
|
Loading…
Reference in New Issue