From 9fb0977433d79a811fac7741e8bd8f08a864ad0b Mon Sep 17 00:00:00 2001 From: Raymond Feng Date: Thu, 7 Aug 2014 22:19:27 -0700 Subject: [PATCH] Pass in remotingContext for ACL See https://github.com/strongloop/loopback/issues/451 --- lib/application.js | 1 + lib/models/access-context.js | 1 + lib/models/model.js | 12 ++++++++++-- test/access-control.integration.js | 14 +++++++++++++- test/fixtures/access-control/models.json | 7 +++++++ 5 files changed, 32 insertions(+), 3 deletions(-) diff --git a/lib/application.js b/lib/application.js index fdb56884..6fda62f3 100644 --- a/lib/application.js +++ b/lib/application.js @@ -323,6 +323,7 @@ app.enableAuth = function() { req.accessToken, modelId, method, + ctx, function(err, allowed) { // Emit any cached data events that fired while checking access. req.resume(); diff --git a/lib/models/access-context.js b/lib/models/access-context.js index 681c366c..2bf03733 100644 --- a/lib/models/access-context.js +++ b/lib/models/access-context.js @@ -66,6 +66,7 @@ function AccessContext(context) { if (token.appId) { this.addPrincipal(Principal.APPLICATION, token.appId); } + this.remotingContext = context.remotingContext; } // Define constant for the wildcard diff --git a/lib/models/model.js b/lib/models/model.js index e0f3b0de..24b9fc6c 100644 --- a/lib/models/model.js +++ b/lib/models/model.js @@ -234,15 +234,22 @@ Model._ACL = function getACL(ACL) { * @param {AccessToken} token The access token * @param {*} modelId The model ID. * @param {SharedMethod} sharedMethod The method in question + * @param {Object} ctx The remote invocation context * @callback {Function} callback The callback function * @param {String|Error} err The error object * @param {Boolean} allowed True if the request is allowed; false otherwise. */ -Model.checkAccess = function(token, modelId, sharedMethod, callback) { +Model.checkAccess = function(token, modelId, sharedMethod, ctx, callback) { var ANONYMOUS = require('./access-token').ANONYMOUS; token = token || ANONYMOUS; var aclModel = Model._ACL(); + + ctx = ctx || {}; + if(typeof ctx === 'function' && callback === undefined) { + callback = ctx; + ctx = {}; + } aclModel.checkAccessForContext({ accessToken: token, @@ -251,7 +258,8 @@ Model.checkAccess = function(token, modelId, sharedMethod, callback) { method: sharedMethod.name, sharedMethod: sharedMethod, modelId: modelId, - accessType: this._getAccessTypeForMethod(sharedMethod) + accessType: this._getAccessTypeForMethod(sharedMethod), + remotingContext: ctx }, function(err, accessRequest) { if(err) return callback(err); callback(null, accessRequest.isAllowed()); diff --git a/test/access-control.integration.js b/test/access-control.integration.js index 575baebd..28e48031 100644 --- a/test/access-control.integration.js +++ b/test/access-control.integration.js @@ -160,6 +160,19 @@ describe('access control - integration', function () { }); describe('/accounts', function () { + var count = 0; + before(function() { + var roleModel = loopback.getModelByType(loopback.Role); + roleModel.registerResolver('$dummy', function (role, context, callback) { + process.nextTick(function () { + if(context.remotingContext) { + count++; + } + callback && callback(null, false); // Always true + }); + }); + }); + lt.beforeEach.givenModel('account'); lt.it.shouldBeDeniedWhenCalledAnonymously('GET', '/api/accounts'); @@ -170,7 +183,6 @@ describe('access control - integration', function () { lt.it.shouldBeDeniedWhenCalledUnauthenticated('GET', urlForAccount); lt.it.shouldBeDeniedWhenCalledByUser(CURRENT_USER, 'GET', urlForAccount); - lt.it.shouldBeDeniedWhenCalledAnonymously('POST', '/api/accounts'); lt.it.shouldBeDeniedWhenCalledUnauthenticated('POST', '/api/accounts'); lt.it.shouldBeDeniedWhenCalledByUser(CURRENT_USER, 'POST', '/api/accounts'); diff --git a/test/fixtures/access-control/models.json b/test/fixtures/access-control/models.json index a1385443..e6b1c292 100644 --- a/test/fixtures/access-control/models.json +++ b/test/fixtures/access-control/models.json @@ -124,6 +124,13 @@ "principalType": "ROLE", "principalId": "$owner", "property": "deleteById" + }, + { + "accessType": "*", + "permission": "DENY", + "property": "find", + "principalType": "ROLE", + "principalId": "$dummy" } ] },