{"action":"created","comment":{"url":"https://api.github.com/repos/codenvy/codenvy/pulls/comments/62049198","id":62049198,"diff_hunk":"@@ -0,0 +1,135 @@\n+/*\n+ *  [2012] - [2016] Codenvy, S.A.\n+ *  All Rights Reserved.\n+ *\n+ * NOTICE:  All information contained herein is, and remains\n+ * the property of Codenvy S.A. and its suppliers,\n+ * if any.  The intellectual and technical concepts contained\n+ * herein are proprietary to Codenvy S.A.\n+ * and its suppliers and may be covered by U.S. and Foreign Patents,\n+ * patents in process, and are protected by trade secret or copyright law.\n+ * Dissemination of this information or reproduction of this material\n+ * is strictly forbidden unless prior written permission is obtained\n+ * from Codenvy S.A..\n+ */\n+package com.codenvy.api.workspace.server.stack;\n+\n+import com.codenvy.api.permission.server.PermissionsDomain;\n+import com.codenvy.api.permission.server.PermissionsImpl;\n+import com.codenvy.api.permission.server.dao.PermissionsStorage;\n+import com.codenvy.api.permission.shared.Permissions;\n+import com.google.common.collect.ImmutableSet;\n+\n+import org.eclipse.che.api.core.NotFoundException;\n+import org.eclipse.che.api.core.ServerException;\n+import org.eclipse.che.api.core.acl.AclEntry;\n+import org.eclipse.che.api.core.acl.AclEntryImpl;\n+import org.eclipse.che.api.workspace.server.model.impl.stack.StackImpl;\n+import org.eclipse.che.api.workspace.server.spi.StackDao;\n+\n+import javax.inject.Inject;\n+import javax.inject.Singleton;\n+import java.util.List;\n+import java.util.Optional;\n+import java.util.Set;\n+import java.util.stream.Collectors;\n+\n+/**\n+ * Implementation of {@link PermissionsStorage} for storing permissions of {@link StackDomain}\n+ *\n+ * <p>This implementation adapts {@link Permissions} and {@link AclEntry} and use\n+ * {@link StackDao} as storage of permissions\n+ *\n+ * @author Sergii Leschenko\n+ */\n+@Singleton\n+public class StackPermissionStorage implements PermissionsStorage {\n+    private final StackDao stackDao;\n+\n+    @Inject\n+    public StackPermissionStorage(StackDao stackDao) {\n+        this.stackDao = stackDao;\n+    }\n+\n+    @Override\n+    public Set<PermissionsDomain> getDomains() {\n+        return ImmutableSet.of(new StackDomain());\n+    }\n+\n+    @Override\n+    public void store(PermissionsImpl permissions) throws ServerException, NotFoundException {\n+        final StackImpl stack = stackDao.getById(permissions.getInstance());\n+        stack.getAcl().removeIf(aclEntry -> aclEntry.getUser().equals(permissions.getUser()));\n+        stack.getAcl().add(new AclEntryImpl(permissions.getUser(),\n+                                            permissions.getActions()));\n+        stackDao.update(stack);\n+    }\n+\n+    @Override\n+    public PermissionsImpl get(String user, String domain, String instance) throws ServerException, NotFoundException {\n+        final StackImpl recipe = stackDao.getById(instance);\n+        final Optional<AclEntryImpl> result = recipe.getAcl()\n+                                                    .stream()\n+                                                    .filter(aclEntry -> aclEntry.getUser().equals(user))\n+                                                    .findAny();\n+\n+        if (!result.isPresent()) {\n+            throw new NotFoundException(String.format(\"Permissions for user '%s' and instance '%s' of domain '%s' was not found\",\n+                                                      user, instance, domain));\n+        }\n+\n+        return toPermission(instance, result.get());\n+    }\n+\n+    @Override\n+    public List<PermissionsImpl> getByInstance(String domain, String instance) throws ServerException, NotFoundException {\n+        final StackImpl recipe = stackDao.getById(instance);\n+        return toPermissions(instance, recipe.getAcl());\n+    }\n+\n+    @Override\n+    public boolean exists(String user, String domain, String instance, String action) throws ServerException {\n+        StackImpl recipe;\n+        try {\n+            recipe = stackDao.getById(instance);\n+        } catch (NotFoundException e) {\n+            return false;\n+        }\n+\n+        final Set<String> allowedActions = recipe.getAcl()\n+                                                 .stream()\n+                                                 .filter(entry -> entry.getUser().equals(user) || entry.getUser().equals(\"*\"))\n+                                                 .flatMap(entry -> entry.getActions().stream())\n+                                                 .collect(Collectors.toSet());\n+        return allowedActions.contains(action);","path":"core/codenvy-hosted-api-workspace/src/main/java/com/codenvy/api/workspace/server/stack/StackPermissionStorage.java","position":104,"original_position":104,"commit_id":"65145a2804bf85cc96619f5a3963c3c633393a45","original_commit_id":"65145a2804bf85cc96619f5a3963c3c633393a45","user":{"login":"sleshchenko","id":5887312,"avatar_url":"https://avatars.githubusercontent.com/u/5887312?v=3","gravatar_id":"","url":"https://api.github.com/users/sleshchenko","html_url":"https://github.com/sleshchenko","followers_url":"https://api.github.com/users/sleshchenko/followers","following_url":"https://api.github.com/users/sleshchenko/following{/other_user}","gists_url":"https://api.github.com/users/sleshchenko/gists{/gist_id}","starred_url":"https://api.github.com/users/sleshchenko/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sleshchenko/subscriptions","organizations_url":"https://api.github.com/users/sleshchenko/orgs","repos_url":"https://api.github.com/users/sleshchenko/repos","events_url":"https://api.github.com/users/sleshchenko/events{/privacy}","received_events_url":"https://api.github.com/users/sleshchenko/received_events","type":"User","site_admin":false},"body":"+1 thx","created_at":"2016-05-04T14:33:45Z","updated_at":"2016-05-04T14:33:45Z","html_url":"https://github.com/codenvy/codenvy/pull/163#discussion_r62049198","pull_request_url":"https://api.github.com/repos/codenvy/codenvy/pulls/163","_links":{"self":{"href":"https://api.github.com/repos/codenvy/codenvy/pulls/comments/62049198"},"html":{"href":"https://github.com/codenvy/codenvy/pull/163#discussion_r62049198"},"pull_request":{"href":"https://api.github.com/repos/codenvy/codenvy/pulls/163"}}},"pull_request":{"url":"https://api.github.com/repos/codenvy/codenvy/pulls/163","id":68862468,"html_url":"https://github.com/codenvy/codenvy/pull/163","diff_url":"https://github.com/codenvy/codenvy/pull/163.diff","patch_url":"https://github.com/codenvy/codenvy/pull/163.patch","issue_url":"https://api.github.com/repos/codenvy/codenvy/issues/163","number":163,"state":"open","locked":false,"title":"CODENVY-433 Implement permissions base authorization for Recipe and Stack APIs","user":{"login":"sleshchenko","id":5887312,"avatar_url":"https://avatars.githubusercontent.com/u/5887312?v=3","gravatar_id":"","url":"https://api.github.com/users/sleshchenko","html_url":"https://github.com/sleshchenko","followers_url":"https://api.github.com/users/sleshchenko/followers","following_url":"https://api.github.com/users/sleshchenko/following{/other_user}","gists_url":"https://api.github.com/users/sleshchenko/gists{/gist_id}","starred_url":"https://api.github.com/users/sleshchenko/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sleshchenko/subscriptions","organizations_url":"https://api.github.com/users/sleshchenko/orgs","repos_url":"https://api.github.com/users/sleshchenko/repos","events_url":"https://api.github.com/users/sleshchenko/events{/privacy}","received_events_url":"https://api.github.com/users/sleshchenko/received_events","type":"User","site_admin":false},"body":"@gazarenkov @skabashnyuk @evoevodin Please review my changes","created_at":"2016-05-04T13:33:54Z","updated_at":"2016-05-04T14:33:45Z","closed_at":null,"merged_at":null,"merge_commit_sha":"31f51ce5579d69fcc7056a399458c767e655c700","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/codenvy/codenvy/pulls/163/commits","review_comments_url":"https://api.github.com/repos/codenvy/codenvy/pulls/163/comments","review_comment_url":"https://api.github.com/repos/codenvy/codenvy/pulls/comments{/number}","comments_url":"https://api.github.com/repos/codenvy/codenvy/issues/163/comments","statuses_url":"https://api.github.com/repos/codenvy/codenvy/statuses/65145a2804bf85cc96619f5a3963c3c633393a45","head":{"label":"codenvy:acls","ref":"acls","sha":"65145a2804bf85cc96619f5a3963c3c633393a45","user":{"login":"codenvy","id":2736247,"avatar_url":"https://avatars.githubusercontent.com/u/2736247?v=3","gravatar_id":"","url":"https://api.github.com/users/codenvy","html_url":"https://github.com/codenvy","followers_url":"https://api.github.com/users/codenvy/followers","following_url":"https://api.github.com/users/codenvy/following{/other_user}","gists_url":"https://api.github.com/users/codenvy/gists{/gist_id}","starred_url":"https://api.github.com/users/codenvy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codenvy/subscriptions","organizations_url":"https://api.github.com/users/codenvy/orgs","repos_url":"https://api.github.com/users/codenvy/repos","events_url":"https://api.github.com/users/codenvy/events{/privacy}","received_events_url":"https://api.github.com/users/codenvy/received_events","type":"Organization","site_admin":false},"repo":{"id":54102761,"name":"codenvy","full_name":"codenvy/codenvy","owner":{"login":"codenvy","id":2736247,"avatar_url":"https://avatars.githubusercontent.com/u/2736247?v=3","gravatar_id":"","url":"https://api.github.com/users/codenvy","html_url":"https://github.com/codenvy","followers_url":"https://api.github.com/users/codenvy/followers","following_url":"https://api.github.com/users/codenvy/following{/other_user}","gists_url":"https://api.github.com/users/codenvy/gists{/gist_id}","starred_url":"https://api.github.com/users/codenvy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codenvy/subscriptions","organizations_url":"https://api.github.com/users/codenvy/orgs","repos_url":"https://api.github.com/users/codenvy/repos","events_url":"https://api.github.com/users/codenvy/events{/privacy}","received_events_url":"https://api.github.com/users/codenvy/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/codenvy/codenvy","description":"Codenvy","fork":false,"url":"https://api.github.com/repos/codenvy/codenvy","forks_url":"https://api.github.com/repos/codenvy/codenvy/forks","keys_url":"https://api.github.com/repos/codenvy/codenvy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/codenvy/codenvy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/codenvy/codenvy/teams","hooks_url":"https://api.github.com/repos/codenvy/codenvy/hooks","issue_events_url":"https://api.github.com/repos/codenvy/codenvy/issues/events{/number}","events_url":"https://api.github.com/repos/codenvy/codenvy/events","assignees_url":"https://api.github.com/repos/codenvy/codenvy/assignees{/user}","branches_url":"https://api.github.com/repos/codenvy/codenvy/branches{/branch}","tags_url":"https://api.github.com/repos/codenvy/codenvy/tags","blobs_url":"https://api.github.com/repos/codenvy/codenvy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/codenvy/codenvy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/codenvy/codenvy/git/refs{/sha}","trees_url":"https://api.github.com/repos/codenvy/codenvy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/codenvy/codenvy/statuses/{sha}","languages_url":"https://api.github.com/repos/codenvy/codenvy/languages","stargazers_url":"https://api.github.com/repos/codenvy/codenvy/stargazers","contributors_url":"https://api.github.com/repos/codenvy/codenvy/contributors","subscribers_url":"https://api.github.com/repos/codenvy/codenvy/subscribers","subscription_url":"https://api.github.com/repos/codenvy/codenvy/subscription","commits_url":"https://api.github.com/repos/codenvy/codenvy/commits{/sha}","git_commits_url":"https://api.github.com/repos/codenvy/codenvy/git/commits{/sha}","comments_url":"https://api.github.com/repos/codenvy/codenvy/comments{/number}","issue_comment_url":"https://api.github.com/repos/codenvy/codenvy/issues/comments{/number}","contents_url":"https://api.github.com/repos/codenvy/codenvy/contents/{+path}","compare_url":"https://api.github.com/repos/codenvy/codenvy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/codenvy/codenvy/merges","archive_url":"https://api.github.com/repos/codenvy/codenvy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/codenvy/codenvy/downloads","issues_url":"https://api.github.com/repos/codenvy/codenvy/issues{/number}","pulls_url":"https://api.github.com/repos/codenvy/codenvy/pulls{/number}","milestones_url":"https://api.github.com/repos/codenvy/codenvy/milestones{/number}","notifications_url":"https://api.github.com/repos/codenvy/codenvy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/codenvy/codenvy/labels{/name}","releases_url":"https://api.github.com/repos/codenvy/codenvy/releases{/id}","deployments_url":"https://api.github.com/repos/codenvy/codenvy/deployments","created_at":"2016-03-17T08:51:27Z","updated_at":"2016-04-25T11:16:05Z","pushed_at":"2016-05-04T14:24:52Z","git_url":"git://github.com/codenvy/codenvy.git","ssh_url":"git@github.com:codenvy/codenvy.git","clone_url":"https://github.com/codenvy/codenvy.git","svn_url":"https://github.com/codenvy/codenvy","homepage":null,"size":67987,"stargazers_count":6,"watchers_count":6,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":5,"mirror_url":null,"open_issues_count":6,"forks":5,"open_issues":6,"watchers":6,"default_branch":"master"}},"base":{"label":"codenvy:master","ref":"master","sha":"91f40e117c561c65f427d1a97608e5f9b5c8105b","user":{"login":"codenvy","id":2736247,"avatar_url":"https://avatars.githubusercontent.com/u/2736247?v=3","gravatar_id":"","url":"https://api.github.com/users/codenvy","html_url":"https://github.com/codenvy","followers_url":"https://api.github.com/users/codenvy/followers","following_url":"https://api.github.com/users/codenvy/following{/other_user}","gists_url":"https://api.github.com/users/codenvy/gists{/gist_id}","starred_url":"https://api.github.com/users/codenvy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codenvy/subscriptions","organizations_url":"https://api.github.com/users/codenvy/orgs","repos_url":"https://api.github.com/users/codenvy/repos","events_url":"https://api.github.com/users/codenvy/events{/privacy}","received_events_url":"https://api.github.com/users/codenvy/received_events","type":"Organization","site_admin":false},"repo":{"id":54102761,"name":"codenvy","full_name":"codenvy/codenvy","owner":{"login":"codenvy","id":2736247,"avatar_url":"https://avatars.githubusercontent.com/u/2736247?v=3","gravatar_id":"","url":"https://api.github.com/users/codenvy","html_url":"https://github.com/codenvy","followers_url":"https://api.github.com/users/codenvy/followers","following_url":"https://api.github.com/users/codenvy/following{/other_user}","gists_url":"https://api.github.com/users/codenvy/gists{/gist_id}","starred_url":"https://api.github.com/users/codenvy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codenvy/subscriptions","organizations_url":"https://api.github.com/users/codenvy/orgs","repos_url":"https://api.github.com/users/codenvy/repos","events_url":"https://api.github.com/users/codenvy/events{/privacy}","received_events_url":"https://api.github.com/users/codenvy/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/codenvy/codenvy","description":"Codenvy","fork":false,"url":"https://api.github.com/repos/codenvy/codenvy","forks_url":"https://api.github.com/repos/codenvy/codenvy/forks","keys_url":"https://api.github.com/repos/codenvy/codenvy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/codenvy/codenvy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/codenvy/codenvy/teams","hooks_url":"https://api.github.com/repos/codenvy/codenvy/hooks","issue_events_url":"https://api.github.com/repos/codenvy/codenvy/issues/events{/number}","events_url":"https://api.github.com/repos/codenvy/codenvy/events","assignees_url":"https://api.github.com/repos/codenvy/codenvy/assignees{/user}","branches_url":"https://api.github.com/repos/codenvy/codenvy/branches{/branch}","tags_url":"https://api.github.com/repos/codenvy/codenvy/tags","blobs_url":"https://api.github.com/repos/codenvy/codenvy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/codenvy/codenvy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/codenvy/codenvy/git/refs{/sha}","trees_url":"https://api.github.com/repos/codenvy/codenvy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/codenvy/codenvy/statuses/{sha}","languages_url":"https://api.github.com/repos/codenvy/codenvy/languages","stargazers_url":"https://api.github.com/repos/codenvy/codenvy/stargazers","contributors_url":"https://api.github.com/repos/codenvy/codenvy/contributors","subscribers_url":"https://api.github.com/repos/codenvy/codenvy/subscribers","subscription_url":"https://api.github.com/repos/codenvy/codenvy/subscription","commits_url":"https://api.github.com/repos/codenvy/codenvy/commits{/sha}","git_commits_url":"https://api.github.com/repos/codenvy/codenvy/git/commits{/sha}","comments_url":"https://api.github.com/repos/codenvy/codenvy/comments{/number}","issue_comment_url":"https://api.github.com/repos/codenvy/codenvy/issues/comments{/number}","contents_url":"https://api.github.com/repos/codenvy/codenvy/contents/{+path}","compare_url":"https://api.github.com/repos/codenvy/codenvy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/codenvy/codenvy/merges","archive_url":"https://api.github.com/repos/codenvy/codenvy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/codenvy/codenvy/downloads","issues_url":"https://api.github.com/repos/codenvy/codenvy/issues{/number}","pulls_url":"https://api.github.com/repos/codenvy/codenvy/pulls{/number}","milestones_url":"https://api.github.com/repos/codenvy/codenvy/milestones{/number}","notifications_url":"https://api.github.com/repos/codenvy/codenvy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/codenvy/codenvy/labels{/name}","releases_url":"https://api.github.com/repos/codenvy/codenvy/releases{/id}","deployments_url":"https://api.github.com/repos/codenvy/codenvy/deployments","created_at":"2016-03-17T08:51:27Z","updated_at":"2016-04-25T11:16:05Z","pushed_at":"2016-05-04T14:24:52Z","git_url":"git://github.com/codenvy/codenvy.git","ssh_url":"git@github.com:codenvy/codenvy.git","clone_url":"https://github.com/codenvy/codenvy.git","svn_url":"https://github.com/codenvy/codenvy","homepage":null,"size":67987,"stargazers_count":6,"watchers_count":6,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":5,"mirror_url":null,"open_issues_count":6,"forks":5,"open_issues":6,"watchers":6,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/codenvy/codenvy/pulls/163"},"html":{"href":"https://github.com/codenvy/codenvy/pull/163"},"issue":{"href":"https://api.github.com/repos/codenvy/codenvy/issues/163"},"comments":{"href":"https://api.github.com/repos/codenvy/codenvy/issues/163/comments"},"review_comments":{"href":"https://api.github.com/repos/codenvy/codenvy/pulls/163/comments"},"review_comment":{"href":"https://api.github.com/repos/codenvy/codenvy/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/codenvy/codenvy/pulls/163/commits"},"statuses":{"href":"https://api.github.com/repos/codenvy/codenvy/statuses/65145a2804bf85cc96619f5a3963c3c633393a45"}}}}