{"action":"created","comment":{"url":"https://api.github.com/repos/strongloop/loopback/pulls/comments/106865730","pull_request_review_id":27806634,"id":106865730,"diff_hunk":"@@ -250,16 +262,23 @@ Principal.prototype.equals = function(p) {\n \n /**\n  * A request to access protected resources.\n- * @param {String} model The model name\n- * @param {String} property\n+ *\n+ * The method can either be called with the following signature or with a single\n+ * argument: an AccessRequest instance or an object containing all the required properties.\n+ *\n+ * @class\n+ * @options {String|AccessRequest|Object} model|req The model name,<br>\n+ *    or an AccessRequest instance/object.\n+ * @param {String} property The property/method/relation name\n  * @param {String} accessType The access type\n  * @param {String} permission The requested permission\n+ * @param {String[]} methodNames The names of involved methods\n+ * @param {Registry} registry The application or global registry\n  * @returns {AccessRequest}\n- * @class\n  */\n-function AccessRequest(model, property, accessType, permission, methodNames) {\n+function AccessRequest(model, property, accessType, permission, methodNames, registry) {\n   if (!(this instanceof AccessRequest)) {\n-    return new AccessRequest(model, property, accessType);\n+    return new AccessRequest(model, property, accessType, permission, methodNames);","path":"lib/access-context.js","position":60,"original_position":60,"commit_id":"8a34495debee9dc615de484c0dd73833644e4367","original_commit_id":"8a34495debee9dc615de484c0dd73833644e4367","user":{"login":"bajtos","id":1140553,"avatar_url":"https://avatars2.githubusercontent.com/u/1140553?v=3","gravatar_id":"","url":"https://api.github.com/users/bajtos","html_url":"https://github.com/bajtos","followers_url":"https://api.github.com/users/bajtos/followers","following_url":"https://api.github.com/users/bajtos/following{/other_user}","gists_url":"https://api.github.com/users/bajtos/gists{/gist_id}","starred_url":"https://api.github.com/users/bajtos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bajtos/subscriptions","organizations_url":"https://api.github.com/users/bajtos/orgs","repos_url":"https://api.github.com/users/bajtos/repos","events_url":"https://api.github.com/users/bajtos/events{/privacy}","received_events_url":"https://api.github.com/users/bajtos/received_events","type":"User","site_admin":false},"body":"I think this will not work, because the new argument `registry` is not forwarded.","created_at":"2017-03-20T10:13:01Z","updated_at":"2017-03-20T10:13:01Z","html_url":"https://github.com/strongloop/loopback/pull/2957#discussion_r106865730","pull_request_url":"https://api.github.com/repos/strongloop/loopback/pulls/2957","_links":{"self":{"href":"https://api.github.com/repos/strongloop/loopback/pulls/comments/106865730"},"html":{"href":"https://github.com/strongloop/loopback/pull/2957#discussion_r106865730"},"pull_request":{"href":"https://api.github.com/repos/strongloop/loopback/pulls/2957"}}},"pull_request":{"url":"https://api.github.com/repos/strongloop/loopback/pulls/2957","id":94460926,"html_url":"https://github.com/strongloop/loopback/pull/2957","diff_url":"https://github.com/strongloop/loopback/pull/2957.diff","patch_url":"https://github.com/strongloop/loopback/pull/2957.patch","issue_url":"https://api.github.com/repos/strongloop/loopback/issues/2957","number":2957,"state":"open","locked":false,"title":"propagate resolved roles in remoting context","user":{"login":"ebarault","id":12000935,"avatar_url":"https://avatars0.githubusercontent.com/u/12000935?v=3","gravatar_id":"","url":"https://api.github.com/users/ebarault","html_url":"https://github.com/ebarault","followers_url":"https://api.github.com/users/ebarault/followers","following_url":"https://api.github.com/users/ebarault/following{/other_user}","gists_url":"https://api.github.com/users/ebarault/gists{/gist_id}","starred_url":"https://api.github.com/users/ebarault/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ebarault/subscriptions","organizations_url":"https://api.github.com/users/ebarault/orgs","repos_url":"https://api.github.com/users/ebarault/repos","events_url":"https://api.github.com/users/ebarault/events{/privacy}","received_events_url":"https://api.github.com/users/ebarault/received_events","type":"User","site_admin":false},"body":"### Description\r\n\r\nFor some **advanced CRUD access control in remote methods**, it is often required to **get/check roles resolved** (i.e. allowed) for a user against a method with `Role.getRoles(context)` or `Role.isInRole(role, context)`.\r\nIn addition to clutter the remote methods / hooks code, it forces the app to run again through all static roles and registered dynamic role resolvers, inducing performance loss and extra calls to db.\r\n\r\nMeanwhile, the exact same course of action is performed right when the `Model.checkAccess()` method is called to verify if a principal is allowed to access a protected resource : \r\n\r\n`Model.checkAccess(context)` -> `ACL.checkAccessForContext(context)` -> `acls.forEach(acl, ...)` ->`roleModel.isInRole(acl.principalId, context)` \r\n\r\nThis PR proposes to add a new param (`Array`) in remoting context (name proposed: `resolvedRoles`, to be discussed) which is filled during **Model Access Permission Checking** phase with the **roles** for which the user is allowed to run the remote method.\r\n\r\nan example of `resolvedRoles` is: `['admin', '$owner']` where admin is a custom role statically mapped to a principal, and $owner is a built-in smart role\r\n\r\n`resolvedRoles` param can then be accessed in remote method and remote method hooks as `ctx.req.remotingContext.resolvedRoles`\r\n\r\n_To be noted: the `resolvedRoles` param is set in a way that the calling user cannot temper the value to fool the additional access control policies added by user in remote methods_ \r\n\r\n**Reviewers:** please review/discuss the general idea before i provide the required tests  \r\n\r\n#### Related issues\r\n\r\n<!--\r\nPlease use the following link syntaxes:\r\n\r\n- #49 (to reference issues in the current repository)\r\n- strongloop/loopback#49 (to reference issues in another repository)\r\n-->\r\n\r\n- None\r\n\r\n### Checklist\r\n\r\n<!--\r\nPlease mark your choice with an \"x\" (i.e. [x], see\r\nhttps://github.com/blog/1375-task-lists-in-gfm-issues-pulls-comments)\r\n-->\r\n\r\n- [x] Code conforms with the [style\r\n  guide](http://loopback.io/doc/en/contrib/style-guide.html)\n- [ ] New tests added or existing tests modified to cover all changes\r\n","created_at":"2016-11-19T00:33:54Z","updated_at":"2017-03-20T10:13:01Z","closed_at":null,"merged_at":null,"merge_commit_sha":"3bd0678792cb3b964375df6afe1b42100109aab9","assignee":{"login":"raymondfeng","id":540892,"avatar_url":"https://avatars3.githubusercontent.com/u/540892?v=3","gravatar_id":"","url":"https://api.github.com/users/raymondfeng","html_url":"https://github.com/raymondfeng","followers_url":"https://api.github.com/users/raymondfeng/followers","following_url":"https://api.github.com/users/raymondfeng/following{/other_user}","gists_url":"https://api.github.com/users/raymondfeng/gists{/gist_id}","starred_url":"https://api.github.com/users/raymondfeng/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/raymondfeng/subscriptions","organizations_url":"https://api.github.com/users/raymondfeng/orgs","repos_url":"https://api.github.com/users/raymondfeng/repos","events_url":"https://api.github.com/users/raymondfeng/events{/privacy}","received_events_url":"https://api.github.com/users/raymondfeng/received_events","type":"User","site_admin":false},"assignees":[{"login":"raymondfeng","id":540892,"avatar_url":"https://avatars3.githubusercontent.com/u/540892?v=3","gravatar_id":"","url":"https://api.github.com/users/raymondfeng","html_url":"https://github.com/raymondfeng","followers_url":"https://api.github.com/users/raymondfeng/followers","following_url":"https://api.github.com/users/raymondfeng/following{/other_user}","gists_url":"https://api.github.com/users/raymondfeng/gists{/gist_id}","starred_url":"https://api.github.com/users/raymondfeng/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/raymondfeng/subscriptions","organizations_url":"https://api.github.com/users/raymondfeng/orgs","repos_url":"https://api.github.com/users/raymondfeng/repos","events_url":"https://api.github.com/users/raymondfeng/events{/privacy}","received_events_url":"https://api.github.com/users/raymondfeng/received_events","type":"User","site_admin":false},{"login":"bajtos","id":1140553,"avatar_url":"https://avatars2.githubusercontent.com/u/1140553?v=3","gravatar_id":"","url":"https://api.github.com/users/bajtos","html_url":"https://github.com/bajtos","followers_url":"https://api.github.com/users/bajtos/followers","following_url":"https://api.github.com/users/bajtos/following{/other_user}","gists_url":"https://api.github.com/users/bajtos/gists{/gist_id}","starred_url":"https://api.github.com/users/bajtos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bajtos/subscriptions","organizations_url":"https://api.github.com/users/bajtos/orgs","repos_url":"https://api.github.com/users/bajtos/repos","events_url":"https://api.github.com/users/bajtos/events{/privacy}","received_events_url":"https://api.github.com/users/bajtos/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/strongloop/loopback/pulls/2957/commits","review_comments_url":"https://api.github.com/repos/strongloop/loopback/pulls/2957/comments","review_comment_url":"https://api.github.com/repos/strongloop/loopback/pulls/comments{/number}","comments_url":"https://api.github.com/repos/strongloop/loopback/issues/2957/comments","statuses_url":"https://api.github.com/repos/strongloop/loopback/statuses/8a34495debee9dc615de484c0dd73833644e4367","head":{"label":"ebarault:propagate-resolved-roles-in-context","ref":"propagate-resolved-roles-in-context","sha":"8a34495debee9dc615de484c0dd73833644e4367","user":{"login":"ebarault","id":12000935,"avatar_url":"https://avatars0.githubusercontent.com/u/12000935?v=3","gravatar_id":"","url":"https://api.github.com/users/ebarault","html_url":"https://github.com/ebarault","followers_url":"https://api.github.com/users/ebarault/followers","following_url":"https://api.github.com/users/ebarault/following{/other_user}","gists_url":"https://api.github.com/users/ebarault/gists{/gist_id}","starred_url":"https://api.github.com/users/ebarault/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ebarault/subscriptions","organizations_url":"https://api.github.com/users/ebarault/orgs","repos_url":"https://api.github.com/users/ebarault/repos","events_url":"https://api.github.com/users/ebarault/events{/privacy}","received_events_url":"https://api.github.com/users/ebarault/received_events","type":"User","site_admin":false},"repo":{"id":74170363,"name":"loopback","full_name":"ebarault/loopback","owner":{"login":"ebarault","id":12000935,"avatar_url":"https://avatars0.githubusercontent.com/u/12000935?v=3","gravatar_id":"","url":"https://api.github.com/users/ebarault","html_url":"https://github.com/ebarault","followers_url":"https://api.github.com/users/ebarault/followers","following_url":"https://api.github.com/users/ebarault/following{/other_user}","gists_url":"https://api.github.com/users/ebarault/gists{/gist_id}","starred_url":"https://api.github.com/users/ebarault/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ebarault/subscriptions","organizations_url":"https://api.github.com/users/ebarault/orgs","repos_url":"https://api.github.com/users/ebarault/repos","events_url":"https://api.github.com/users/ebarault/events{/privacy}","received_events_url":"https://api.github.com/users/ebarault/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ebarault/loopback","description":"LoopBack is an open source Node.js framework built on top of Express optimized for building APIs for mobile, web, and other devices. Connect to multiple data sources, write business logic in Node.js, glue on top of your existing services and data, connect using JS, iOS & Android SDKs.","fork":true,"url":"https://api.github.com/repos/ebarault/loopback","forks_url":"https://api.github.com/repos/ebarault/loopback/forks","keys_url":"https://api.github.com/repos/ebarault/loopback/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ebarault/loopback/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ebarault/loopback/teams","hooks_url":"https://api.github.com/repos/ebarault/loopback/hooks","issue_events_url":"https://api.github.com/repos/ebarault/loopback/issues/events{/number}","events_url":"https://api.github.com/repos/ebarault/loopback/events","assignees_url":"https://api.github.com/repos/ebarault/loopback/assignees{/user}","branches_url":"https://api.github.com/repos/ebarault/loopback/branches{/branch}","tags_url":"https://api.github.com/repos/ebarault/loopback/tags","blobs_url":"https://api.github.com/repos/ebarault/loopback/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ebarault/loopback/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ebarault/loopback/git/refs{/sha}","trees_url":"https://api.github.com/repos/ebarault/loopback/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ebarault/loopback/statuses/{sha}","languages_url":"https://api.github.com/repos/ebarault/loopback/languages","stargazers_url":"https://api.github.com/repos/ebarault/loopback/stargazers","contributors_url":"https://api.github.com/repos/ebarault/loopback/contributors","subscribers_url":"https://api.github.com/repos/ebarault/loopback/subscribers","subscription_url":"https://api.github.com/repos/ebarault/loopback/subscription","commits_url":"https://api.github.com/repos/ebarault/loopback/commits{/sha}","git_commits_url":"https://api.github.com/repos/ebarault/loopback/git/commits{/sha}","comments_url":"https://api.github.com/repos/ebarault/loopback/comments{/number}","issue_comment_url":"https://api.github.com/repos/ebarault/loopback/issues/comments{/number}","contents_url":"https://api.github.com/repos/ebarault/loopback/contents/{+path}","compare_url":"https://api.github.com/repos/ebarault/loopback/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ebarault/loopback/merges","archive_url":"https://api.github.com/repos/ebarault/loopback/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ebarault/loopback/downloads","issues_url":"https://api.github.com/repos/ebarault/loopback/issues{/number}","pulls_url":"https://api.github.com/repos/ebarault/loopback/pulls{/number}","milestones_url":"https://api.github.com/repos/ebarault/loopback/milestones{/number}","notifications_url":"https://api.github.com/repos/ebarault/loopback/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ebarault/loopback/labels{/name}","releases_url":"https://api.github.com/repos/ebarault/loopback/releases{/id}","deployments_url":"https://api.github.com/repos/ebarault/loopback/deployments","created_at":"2016-11-18T22:12:51Z","updated_at":"2016-11-18T22:12:53Z","pushed_at":"2017-03-20T08:22:42Z","git_url":"git://github.com/ebarault/loopback.git","ssh_url":"git@github.com:ebarault/loopback.git","clone_url":"https://github.com/ebarault/loopback.git","svn_url":"https://github.com/ebarault/loopback","homepage":"http://loopback.io","size":7672,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"strongloop:master","ref":"master","sha":"960e118c4eb8cd40b3b2acb0953191849c8b940e","user":{"login":"strongloop","id":3020012,"avatar_url":"https://avatars2.githubusercontent.com/u/3020012?v=3","gravatar_id":"","url":"https://api.github.com/users/strongloop","html_url":"https://github.com/strongloop","followers_url":"https://api.github.com/users/strongloop/followers","following_url":"https://api.github.com/users/strongloop/following{/other_user}","gists_url":"https://api.github.com/users/strongloop/gists{/gist_id}","starred_url":"https://api.github.com/users/strongloop/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/strongloop/subscriptions","organizations_url":"https://api.github.com/users/strongloop/orgs","repos_url":"https://api.github.com/users/strongloop/repos","events_url":"https://api.github.com/users/strongloop/events{/privacy}","received_events_url":"https://api.github.com/users/strongloop/received_events","type":"Organization","site_admin":false},"repo":{"id":9325315,"name":"loopback","full_name":"strongloop/loopback","owner":{"login":"strongloop","id":3020012,"avatar_url":"https://avatars2.githubusercontent.com/u/3020012?v=3","gravatar_id":"","url":"https://api.github.com/users/strongloop","html_url":"https://github.com/strongloop","followers_url":"https://api.github.com/users/strongloop/followers","following_url":"https://api.github.com/users/strongloop/following{/other_user}","gists_url":"https://api.github.com/users/strongloop/gists{/gist_id}","starred_url":"https://api.github.com/users/strongloop/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/strongloop/subscriptions","organizations_url":"https://api.github.com/users/strongloop/orgs","repos_url":"https://api.github.com/users/strongloop/repos","events_url":"https://api.github.com/users/strongloop/events{/privacy}","received_events_url":"https://api.github.com/users/strongloop/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/strongloop/loopback","description":"LoopBack is an open source Node.js framework built on top of Express optimized for building APIs for mobile, web, and other devices. Connect to multiple data sources, write business logic in Node.js, glue on top of your existing services and data, connect using JS, iOS & Android SDKs.","fork":false,"url":"https://api.github.com/repos/strongloop/loopback","forks_url":"https://api.github.com/repos/strongloop/loopback/forks","keys_url":"https://api.github.com/repos/strongloop/loopback/keys{/key_id}","collaborators_url":"https://api.github.com/repos/strongloop/loopback/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/strongloop/loopback/teams","hooks_url":"https://api.github.com/repos/strongloop/loopback/hooks","issue_events_url":"https://api.github.com/repos/strongloop/loopback/issues/events{/number}","events_url":"https://api.github.com/repos/strongloop/loopback/events","assignees_url":"https://api.github.com/repos/strongloop/loopback/assignees{/user}","branches_url":"https://api.github.com/repos/strongloop/loopback/branches{/branch}","tags_url":"https://api.github.com/repos/strongloop/loopback/tags","blobs_url":"https://api.github.com/repos/strongloop/loopback/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/strongloop/loopback/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/strongloop/loopback/git/refs{/sha}","trees_url":"https://api.github.com/repos/strongloop/loopback/git/trees{/sha}","statuses_url":"https://api.github.com/repos/strongloop/loopback/statuses/{sha}","languages_url":"https://api.github.com/repos/strongloop/loopback/languages","stargazers_url":"https://api.github.com/repos/strongloop/loopback/stargazers","contributors_url":"https://api.github.com/repos/strongloop/loopback/contributors","subscribers_url":"https://api.github.com/repos/strongloop/loopback/subscribers","subscription_url":"https://api.github.com/repos/strongloop/loopback/subscription","commits_url":"https://api.github.com/repos/strongloop/loopback/commits{/sha}","git_commits_url":"https://api.github.com/repos/strongloop/loopback/git/commits{/sha}","comments_url":"https://api.github.com/repos/strongloop/loopback/comments{/number}","issue_comment_url":"https://api.github.com/repos/strongloop/loopback/issues/comments{/number}","contents_url":"https://api.github.com/repos/strongloop/loopback/contents/{+path}","compare_url":"https://api.github.com/repos/strongloop/loopback/compare/{base}...{head}","merges_url":"https://api.github.com/repos/strongloop/loopback/merges","archive_url":"https://api.github.com/repos/strongloop/loopback/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/strongloop/loopback/downloads","issues_url":"https://api.github.com/repos/strongloop/loopback/issues{/number}","pulls_url":"https://api.github.com/repos/strongloop/loopback/pulls{/number}","milestones_url":"https://api.github.com/repos/strongloop/loopback/milestones{/number}","notifications_url":"https://api.github.com/repos/strongloop/loopback/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/strongloop/loopback/labels{/name}","releases_url":"https://api.github.com/repos/strongloop/loopback/releases{/id}","deployments_url":"https://api.github.com/repos/strongloop/loopback/deployments","created_at":"2013-04-09T16:02:18Z","updated_at":"2017-03-20T01:57:08Z","pushed_at":"2017-03-20T08:22:44Z","git_url":"git://github.com/strongloop/loopback.git","ssh_url":"git@github.com:strongloop/loopback.git","clone_url":"https://github.com/strongloop/loopback.git","svn_url":"https://github.com/strongloop/loopback","homepage":"http://loopback.io","size":7641,"stargazers_count":8521,"watchers_count":8521,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":829,"mirror_url":null,"open_issues_count":533,"forks":829,"open_issues":533,"watchers":8521,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/strongloop/loopback/pulls/2957"},"html":{"href":"https://github.com/strongloop/loopback/pull/2957"},"issue":{"href":"https://api.github.com/repos/strongloop/loopback/issues/2957"},"comments":{"href":"https://api.github.com/repos/strongloop/loopback/issues/2957/comments"},"review_comments":{"href":"https://api.github.com/repos/strongloop/loopback/pulls/2957/comments"},"review_comment":{"href":"https://api.github.com/repos/strongloop/loopback/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/strongloop/loopback/pulls/2957/commits"},"statuses":{"href":"https://api.github.com/repos/strongloop/loopback/statuses/8a34495debee9dc615de484c0dd73833644e4367"}}}}
{"actor":{"display_login":"bajtos"}}