Add access type checking

This commit is contained in:
Ritchie Martori 2013-12-06 17:04:47 -08:00
parent 4e1e3afb74
commit 216fee3015
3 changed files with 81 additions and 6 deletions

View File

@ -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) {

View File

@ -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();

View File

@ -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 -