diff --git a/common/models/role.js b/common/models/role.js index b8c1242d..c4e7e8b3 100644 --- a/common/models/role.js +++ b/common/models/role.js @@ -128,8 +128,9 @@ module.exports = function(Role) { /** * Add custom handler for roles. * @param {String} role Name of role. - * @param {Function} resolver Function that determines if a principal is in the specified role. - * Signature must be `function(role, context, callback)` + * @param {Function} resolver Function that determines + * if a principal is in the specified role. + * Should provide a callback or return a promise. */ Role.registerResolver = function(role, resolver) { if (!Role.resolvers) { @@ -295,7 +296,14 @@ module.exports = function(Role) { var resolver = Role.resolvers[role]; if (resolver) { debug('Custom resolver found for role %s', role); - resolver(role, context, callback); + + var promise = resolver(role, context, callback); + if (promise && typeof promise.then === 'function') { + promise.then( + function(result) { callback(null, result); }, + callback + ); + } return; } diff --git a/test/role.test.js b/test/role.test.js index 0c98fbce..50a5e032 100644 --- a/test/role.test.js +++ b/test/role.test.js @@ -13,6 +13,7 @@ var Application = loopback.Application; var ACL = loopback.ACL; var async = require('async'); var expect = require('chai').expect; +var Promise = require('bluebird'); function checkResult(err, result) { assert(!err); @@ -181,6 +182,13 @@ describe('role model', function() { }); it('should support owner role resolver', function() { + Role.registerResolver('returnPromise', function(role, context) { + return new Promise(function(resolve) { + process.nextTick(function() { + resolve(true); + }); + }); + }); var Album = ds.createModel('Album', { name: String, @@ -196,10 +204,18 @@ describe('role model', function() { }); User.create({name: 'Raymond', email: 'x@y.com', password: 'foobar'}, function(err, user) { - Role.isInRole(Role.AUTHENTICATED, {principalType: ACL.USER, principalId: user.id}, function(err, yes) { + Role.isInRole('returnPromise', { principalType: ACL.USER, principalId: user.id }, + function(err, yes) { assert(!err && yes); }); - Role.isInRole(Role.AUTHENTICATED, {principalType: ACL.USER, principalId: null}, function(err, yes) { + + Role.isInRole(Role.AUTHENTICATED, { principalType: ACL.USER, principalId: user.id }, + function(err, yes) { + assert(!err && yes); + }); + + Role.isInRole(Role.AUTHENTICATED, { principalType: ACL.USER, principalId: null }, + function(err, yes) { assert(!err && !yes); });