{"action":"created","comment":{"url":"https://api.github.com/repos/restx/restx/pulls/comments/44569722","id":44569722,"diff_hunk":"@@ -38,6 +36,8 @@\n })\n @SupportedOptions({ \"debug\" })\n public class RestxAnnotationProcessor extends RestxAbstractProcessor {\n+    private static final Pattern ROLE_PARAM_INTERPOLATOR_REGEX = Pattern.compile(\"\\\\{([^}]+)\\\\}\");","path":"restx-core-annotation-processor/src/main/java/restx/annotations/processor/RestxAnnotationProcessor.java","position":14,"original_position":14,"commit_id":"d6576e7d8ac7ad26320a8993085903154c9ec244","original_commit_id":"d6576e7d8ac7ad26320a8993085903154c9ec244","user":{"login":"a-peyrard","id":6125316,"avatar_url":"https://avatars.githubusercontent.com/u/6125316?v=3","gravatar_id":"","url":"https://api.github.com/users/a-peyrard","html_url":"https://github.com/a-peyrard","followers_url":"https://api.github.com/users/a-peyrard/followers","following_url":"https://api.github.com/users/a-peyrard/following{/other_user}","gists_url":"https://api.github.com/users/a-peyrard/gists{/gist_id}","starred_url":"https://api.github.com/users/a-peyrard/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/a-peyrard/subscriptions","organizations_url":"https://api.github.com/users/a-peyrard/orgs","repos_url":"https://api.github.com/users/a-peyrard/repos","events_url":"https://api.github.com/users/a-peyrard/events{/privacy}","received_events_url":"https://api.github.com/users/a-peyrard/received_events","type":"User","site_admin":false},"body":"Isn't `\"\\\\{(.+?)\\\\}\"` more easy to read ? ","created_at":"2015-11-11T18:51:41Z","updated_at":"2015-11-11T18:51:41Z","html_url":"https://github.com/restx/restx/pull/223#discussion_r44569722","pull_request_url":"https://api.github.com/repos/restx/restx/pulls/223","_links":{"self":{"href":"https://api.github.com/repos/restx/restx/pulls/comments/44569722"},"html":{"href":"https://github.com/restx/restx/pull/223#discussion_r44569722"},"pull_request":{"href":"https://api.github.com/repos/restx/restx/pulls/223"}}},"pull_request":{"url":"https://api.github.com/repos/restx/restx/pulls/223","id":48915295,"html_url":"https://github.com/restx/restx/pull/223","diff_url":"https://github.com/restx/restx/pull/223.diff","patch_url":"https://github.com/restx/restx/pull/223.patch","issue_url":"https://api.github.com/repos/restx/restx/issues/223","number":223,"state":"open","locked":false,"title":"Variabilized security roles","user":{"login":"fcamblor","id":603815,"avatar_url":"https://avatars.githubusercontent.com/u/603815?v=3","gravatar_id":"","url":"https://api.github.com/users/fcamblor","html_url":"https://github.com/fcamblor","followers_url":"https://api.github.com/users/fcamblor/followers","following_url":"https://api.github.com/users/fcamblor/following{/other_user}","gists_url":"https://api.github.com/users/fcamblor/gists{/gist_id}","starred_url":"https://api.github.com/users/fcamblor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fcamblor/subscriptions","organizations_url":"https://api.github.com/users/fcamblor/orgs","repos_url":"https://api.github.com/users/fcamblor/repos","events_url":"https://api.github.com/users/fcamblor/events{/privacy}","received_events_url":"https://api.github.com/users/fcamblor/received_events","type":"User","site_admin":false},"body":"This PR allows to define \"variabilized\" security roles based on what we have in `query params` or `path param` for a dedicated endpoint.\r\n\r\nIt will allow to typically have such endpoint checks :\r\n```\r\n    @GET(\"/security/{companyId}/{subCompanyId}\")\r\n    @RolesAllowed(\"EDIT_COMPANY_{companyId}_{subCompanyId}\")\r\n    public String editSubCompany(String companyId, String subCompanyId){\r\n        // ....\r\n    }\r\n```\r\n\r\nChanges have been made to `StdRestxSecurityManager` in order to generate a `role interpolation map`, basically with `query` & `path` parameters (but which may be overwritten with specific stuff if wanted on every project .. you'll only need to `@Provide` another `StdRestxSecurityManager`)\r\n\r\nBy introducing variabilized roles, I added a support for wildcards on roles located in `RestxPrincipal`\r\nThat is to say, if current user has role named `EDIT_COMPANY_1234_*` he will be able to call every urls like `/security/1234/*` without having any `403 Forbidden` response.\r\nThe `wildcard roles` checks are generated at compilation time through `RestxAnnotationProcessor` (because variable cartesian product may take some time to generate, which we would like to avoid at runtime).\r\n\r\nThat is to say, corresponding generated code for endpoint above will be :\r\n```\r\n        new StdEntityRoute<Void, java.lang.String>(\"default#SecuredResource#editSubCompany\",\r\n                readerRegistry.<Void>build(Void.class, Optional.<String>absent()),\r\n                writerRegistry.<java.lang.String>build(java.lang.String.class, Optional.<String>absent()),\r\n                new StdRestxRequestMatcher(\"GET\", \"/security/{companyId}/{subCompanyId}\"),\r\n                HttpStatus.OK, RestxLogLevel.DEFAULT) {\r\n            @Override\r\n            protected Optional<java.lang.String> doRoute(RestxRequest request, RestxRequestMatch match, Void body) throws IOException {\r\n                securityManager.check(request, match, anyOf(hasRole(\"EDIT_COMPANY_*_*\"), hasRole(\"EDIT_COMPANY_*_{subCompanyId}\"), hasRole(\"EDIT_COMPANY_{companyId}_*\"), hasRole(\"EDIT_COMPANY_{companyId}_{subCompanyId}\")));\r\n                return Optional.of(resource.editSubCompany(\r\n                        /* [PATH] companyId */ match.getPathParam(\"companyId\"),\r\n                        /* [PATH] subCompanyId */ match.getPathParam(\"subCompanyId\")\r\n                ));\r\n            }\r\n            // ....\r\n`\r\n``","created_at":"2015-10-27T18:50:20Z","updated_at":"2015-11-11T18:51:41Z","closed_at":null,"merged_at":null,"merge_commit_sha":"1bf374a74aab45d56d83cb566361bcd22765329d","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/restx/restx/pulls/223/commits","review_comments_url":"https://api.github.com/repos/restx/restx/pulls/223/comments","review_comment_url":"https://api.github.com/repos/restx/restx/pulls/comments{/number}","comments_url":"https://api.github.com/repos/restx/restx/issues/223/comments","statuses_url":"https://api.github.com/repos/restx/restx/statuses/d6576e7d8ac7ad26320a8993085903154c9ec244","head":{"label":"fcamblor:dynamic-security-roles","ref":"dynamic-security-roles","sha":"d6576e7d8ac7ad26320a8993085903154c9ec244","user":{"login":"fcamblor","id":603815,"avatar_url":"https://avatars.githubusercontent.com/u/603815?v=3","gravatar_id":"","url":"https://api.github.com/users/fcamblor","html_url":"https://github.com/fcamblor","followers_url":"https://api.github.com/users/fcamblor/followers","following_url":"https://api.github.com/users/fcamblor/following{/other_user}","gists_url":"https://api.github.com/users/fcamblor/gists{/gist_id}","starred_url":"https://api.github.com/users/fcamblor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fcamblor/subscriptions","organizations_url":"https://api.github.com/users/fcamblor/orgs","repos_url":"https://api.github.com/users/fcamblor/repos","events_url":"https://api.github.com/users/fcamblor/events{/privacy}","received_events_url":"https://api.github.com/users/fcamblor/received_events","type":"User","site_admin":false},"repo":{"id":10027271,"name":"restx","full_name":"fcamblor/restx","owner":{"login":"fcamblor","id":603815,"avatar_url":"https://avatars.githubusercontent.com/u/603815?v=3","gravatar_id":"","url":"https://api.github.com/users/fcamblor","html_url":"https://github.com/fcamblor","followers_url":"https://api.github.com/users/fcamblor/followers","following_url":"https://api.github.com/users/fcamblor/following{/other_user}","gists_url":"https://api.github.com/users/fcamblor/gists{/gist_id}","starred_url":"https://api.github.com/users/fcamblor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fcamblor/subscriptions","organizations_url":"https://api.github.com/users/fcamblor/orgs","repos_url":"https://api.github.com/users/fcamblor/repos","events_url":"https://api.github.com/users/fcamblor/events{/privacy}","received_events_url":"https://api.github.com/users/fcamblor/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/fcamblor/restx","description":"RESTX, the lightweight Java REST framework","fork":true,"url":"https://api.github.com/repos/fcamblor/restx","forks_url":"https://api.github.com/repos/fcamblor/restx/forks","keys_url":"https://api.github.com/repos/fcamblor/restx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/fcamblor/restx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/fcamblor/restx/teams","hooks_url":"https://api.github.com/repos/fcamblor/restx/hooks","issue_events_url":"https://api.github.com/repos/fcamblor/restx/issues/events{/number}","events_url":"https://api.github.com/repos/fcamblor/restx/events","assignees_url":"https://api.github.com/repos/fcamblor/restx/assignees{/user}","branches_url":"https://api.github.com/repos/fcamblor/restx/branches{/branch}","tags_url":"https://api.github.com/repos/fcamblor/restx/tags","blobs_url":"https://api.github.com/repos/fcamblor/restx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/fcamblor/restx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/fcamblor/restx/git/refs{/sha}","trees_url":"https://api.github.com/repos/fcamblor/restx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/fcamblor/restx/statuses/{sha}","languages_url":"https://api.github.com/repos/fcamblor/restx/languages","stargazers_url":"https://api.github.com/repos/fcamblor/restx/stargazers","contributors_url":"https://api.github.com/repos/fcamblor/restx/contributors","subscribers_url":"https://api.github.com/repos/fcamblor/restx/subscribers","subscription_url":"https://api.github.com/repos/fcamblor/restx/subscription","commits_url":"https://api.github.com/repos/fcamblor/restx/commits{/sha}","git_commits_url":"https://api.github.com/repos/fcamblor/restx/git/commits{/sha}","comments_url":"https://api.github.com/repos/fcamblor/restx/comments{/number}","issue_comment_url":"https://api.github.com/repos/fcamblor/restx/issues/comments{/number}","contents_url":"https://api.github.com/repos/fcamblor/restx/contents/{+path}","compare_url":"https://api.github.com/repos/fcamblor/restx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/fcamblor/restx/merges","archive_url":"https://api.github.com/repos/fcamblor/restx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/fcamblor/restx/downloads","issues_url":"https://api.github.com/repos/fcamblor/restx/issues{/number}","pulls_url":"https://api.github.com/repos/fcamblor/restx/pulls{/number}","milestones_url":"https://api.github.com/repos/fcamblor/restx/milestones{/number}","notifications_url":"https://api.github.com/repos/fcamblor/restx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/fcamblor/restx/labels{/name}","releases_url":"https://api.github.com/repos/fcamblor/restx/releases{/id}","created_at":"2013-05-13T08:16:16Z","updated_at":"2015-02-20T17:51:02Z","pushed_at":"2015-10-30T14:29:55Z","git_url":"git://github.com/fcamblor/restx.git","ssh_url":"git@github.com:fcamblor/restx.git","clone_url":"https://github.com/fcamblor/restx.git","svn_url":"https://github.com/fcamblor/restx","homepage":"http://restx.io","size":10633,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"restx:master","ref":"master","sha":"3689c6b0da6d27dfd3d17c874e6e29a2e317a4a2","user":{"login":"restx","id":4331719,"avatar_url":"https://avatars.githubusercontent.com/u/4331719?v=3","gravatar_id":"","url":"https://api.github.com/users/restx","html_url":"https://github.com/restx","followers_url":"https://api.github.com/users/restx/followers","following_url":"https://api.github.com/users/restx/following{/other_user}","gists_url":"https://api.github.com/users/restx/gists{/gist_id}","starred_url":"https://api.github.com/users/restx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/restx/subscriptions","organizations_url":"https://api.github.com/users/restx/orgs","repos_url":"https://api.github.com/users/restx/repos","events_url":"https://api.github.com/users/restx/events{/privacy}","received_events_url":"https://api.github.com/users/restx/received_events","type":"Organization","site_admin":false},"repo":{"id":9836833,"name":"restx","full_name":"restx/restx","owner":{"login":"restx","id":4331719,"avatar_url":"https://avatars.githubusercontent.com/u/4331719?v=3","gravatar_id":"","url":"https://api.github.com/users/restx","html_url":"https://github.com/restx","followers_url":"https://api.github.com/users/restx/followers","following_url":"https://api.github.com/users/restx/following{/other_user}","gists_url":"https://api.github.com/users/restx/gists{/gist_id}","starred_url":"https://api.github.com/users/restx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/restx/subscriptions","organizations_url":"https://api.github.com/users/restx/orgs","repos_url":"https://api.github.com/users/restx/repos","events_url":"https://api.github.com/users/restx/events{/privacy}","received_events_url":"https://api.github.com/users/restx/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/restx/restx","description":"RESTX, the lightweight Java REST framework","fork":false,"url":"https://api.github.com/repos/restx/restx","forks_url":"https://api.github.com/repos/restx/restx/forks","keys_url":"https://api.github.com/repos/restx/restx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/restx/restx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/restx/restx/teams","hooks_url":"https://api.github.com/repos/restx/restx/hooks","issue_events_url":"https://api.github.com/repos/restx/restx/issues/events{/number}","events_url":"https://api.github.com/repos/restx/restx/events","assignees_url":"https://api.github.com/repos/restx/restx/assignees{/user}","branches_url":"https://api.github.com/repos/restx/restx/branches{/branch}","tags_url":"https://api.github.com/repos/restx/restx/tags","blobs_url":"https://api.github.com/repos/restx/restx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/restx/restx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/restx/restx/git/refs{/sha}","trees_url":"https://api.github.com/repos/restx/restx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/restx/restx/statuses/{sha}","languages_url":"https://api.github.com/repos/restx/restx/languages","stargazers_url":"https://api.github.com/repos/restx/restx/stargazers","contributors_url":"https://api.github.com/repos/restx/restx/contributors","subscribers_url":"https://api.github.com/repos/restx/restx/subscribers","subscription_url":"https://api.github.com/repos/restx/restx/subscription","commits_url":"https://api.github.com/repos/restx/restx/commits{/sha}","git_commits_url":"https://api.github.com/repos/restx/restx/git/commits{/sha}","comments_url":"https://api.github.com/repos/restx/restx/comments{/number}","issue_comment_url":"https://api.github.com/repos/restx/restx/issues/comments{/number}","contents_url":"https://api.github.com/repos/restx/restx/contents/{+path}","compare_url":"https://api.github.com/repos/restx/restx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/restx/restx/merges","archive_url":"https://api.github.com/repos/restx/restx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/restx/restx/downloads","issues_url":"https://api.github.com/repos/restx/restx/issues{/number}","pulls_url":"https://api.github.com/repos/restx/restx/pulls{/number}","milestones_url":"https://api.github.com/repos/restx/restx/milestones{/number}","notifications_url":"https://api.github.com/repos/restx/restx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/restx/restx/labels{/name}","releases_url":"https://api.github.com/repos/restx/restx/releases{/id}","created_at":"2013-05-03T13:49:40Z","updated_at":"2015-11-11T02:44:55Z","pushed_at":"2015-11-11T17:41:25Z","git_url":"git://github.com/restx/restx.git","ssh_url":"git@github.com:restx/restx.git","clone_url":"https://github.com/restx/restx.git","svn_url":"https://github.com/restx/restx","homepage":"http://restx.io","size":13497,"stargazers_count":303,"watchers_count":303,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":64,"mirror_url":null,"open_issues_count":66,"forks":64,"open_issues":66,"watchers":303,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/restx/restx/pulls/223"},"html":{"href":"https://github.com/restx/restx/pull/223"},"issue":{"href":"https://api.github.com/repos/restx/restx/issues/223"},"comments":{"href":"https://api.github.com/repos/restx/restx/issues/223/comments"},"review_comments":{"href":"https://api.github.com/repos/restx/restx/pulls/223/comments"},"review_comment":{"href":"https://api.github.com/repos/restx/restx/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/restx/restx/pulls/223/commits"},"statuses":{"href":"https://api.github.com/repos/restx/restx/statuses/d6576e7d8ac7ad26320a8993085903154c9ec244"}}}}