{"action":"created","comment":{"url":"https://api.github.com/repos/openshift/origin-web-console/pulls/comments/69021814","id":69021814,"diff_hunk":"@@ -0,0 +1,121 @@\n+'use strict';\n+\n+angular.module(\"openshiftConsole\")\n+  .factory(\"AuthorizationService\", function($q, Logger, $interval, DataService){\n+    function AuthorizationService() {\n+      this.currentProject = null;\n+      this.projects = {};\n+      this.MAX_PROJECTS = 10;\n+    }\n+\n+    var normalizeRules = function(rules) {\n+      var normalizedRules = {};\n+      var canAddToProject = null;\n+      _.each(rules, function(rule) {\n+        _.each(rule.resources, function(resource) {\n+          normalizedRules[resource] = {\n+            verbs: rule.verbs,\n+            apiGroups: rule.apiGroups\n+          };\n+        });\n+        if (_.contains(rule.verbs, \"create\") || _.contains(rule.verbs, \"update\")) {\n+          canAddToProject = true;\n+        }\n+      });\n+\n+      return [normalizedRules, canAddToProject];\n+    };\n+\n+    var getOldestProject = function(allProjectsRules) {\n+      var oldestProject = {\n+        name: null,\n+        timestamp: _.now()\n+      };\n+      _.each(allProjectsRules, function(projectData, projectName){\n+        if ((projectData.cacheTimestamp - oldestProject.timestamp) < 0) {\n+          oldestProject.name = projectName;\n+          oldestProject.timestamp = projectData.cacheTimestamp;\n+        }\n+      });\n+      return oldestProject.name;\n+    };\n+\n+    AuthorizationService.prototype.getProjectRules = function(projectName) {\n+      var self = this;\n+      var deferred = $q.defer();\n+      this.currentProject = projectName;\n+      if (!_.has(self.projects, projectName)) {\n+        Logger.log(\"AuthorizationService, loading user rules for \" + projectName + \" project\");\n+\n+        // Remove oldest project rules that we cache\n+        if (_.size(self.projects) === self.MAX_PROJECTS) {\n+          // Switch for `_.minBy` when we start to use Lodash 4.x.x\n+          delete self.projects[getOldestProject(self.projects)];\n+        }\n+\n+        var object = {kind: \"SelfSubjectRulesReview\",\n+                      apiVersion: \"v1\"\n+                    };\n+        DataService.create('selfsubjectrulesreviews', null, object, {namespace: projectName}).then(\n+          function(data) {\n+            var normalizedData = normalizeRules(data.status.rules);\n+            self.projects[projectName] = {\n+              rules: normalizedData[0],\n+              canAddToProject: normalizedData[1],\n+              intervalTimer: $interval(function() {\n+                                delete self.projects[projectName];\n+                              }, 600000),\n+              cacheTimestamp: _.now()\n+            };\n+\n+            deferred.resolve(true);\n+          }, function() {\n+            deferred.reject(false);\n+        });\n+      } else {\n+        // Using cached data.\n+        // Just refresh the cacheTimestamp value to a current time. Not the interval.\n+        Logger.log(\"AuthorizationService, using cached rules for \" + projectName + \" project\");\n+        self.projects[projectName].cacheTimestamp = _.now();\n+        deferred.resolve(true);\n+      }\n+      return deferred.promise;\n+    };\n+\n+    AuthorizationService.prototype.canI = function(verb, resource, projectName) {\n+      projectName = projectName || this.currentProject;\n+      var rules = this.getRules(projectName);\n+      if (rules) {\n+        if (rules[resource]) {\n+          return _.contains(rules[resource].verbs, verb) || _.contains(rules[resource].verbs, '*');\n+        } else if (rules['*']) {\n+          return _.contains(rules['*'].verbs, verb) || _.contains(rules['*'].verbs, '*');\n+        } else {\n+          return false;\n+        }    \n+      } else {\n+        return false;\n+      }\n+    };\n+\n+    AuthorizationService.prototype.getCanIAddToProject = function(projectName) {\n+      projectName = projectName || this.currentProject;\n+      if (_.has(this.projects, projectName)) {","path":"app/scripts/services/authorization.js","position":103,"original_position":103,"commit_id":"33e4aba13deac1a8be8f1bd4b52e67465db7bd99","original_commit_id":"33e4aba13deac1a8be8f1bd4b52e67465db7bd99","user":{"login":"jwforres","id":1467629,"avatar_url":"https://avatars.githubusercontent.com/u/1467629?v=3","gravatar_id":"","url":"https://api.github.com/users/jwforres","html_url":"https://github.com/jwforres","followers_url":"https://api.github.com/users/jwforres/followers","following_url":"https://api.github.com/users/jwforres/following{/other_user}","gists_url":"https://api.github.com/users/jwforres/gists{/gist_id}","starred_url":"https://api.github.com/users/jwforres/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jwforres/subscriptions","organizations_url":"https://api.github.com/users/jwforres/orgs","repos_url":"https://api.github.com/users/jwforres/repos","events_url":"https://api.github.com/users/jwforres/events{/privacy}","received_events_url":"https://api.github.com/users/jwforres/received_events","type":"User","site_admin":false},"body":"Make this whole thing a one liner, remember !! forces a boolean return value\r\n```\r\nreturn !!_.get(this.projects, [projectName || this.currentProject, 'canAddToProject']);\r\n```","created_at":"2016-06-29T20:33:25Z","updated_at":"2016-06-29T20:33:25Z","html_url":"https://github.com/openshift/origin-web-console/pull/82#discussion_r69021814","pull_request_url":"https://api.github.com/repos/openshift/origin-web-console/pulls/82","_links":{"self":{"href":"https://api.github.com/repos/openshift/origin-web-console/pulls/comments/69021814"},"html":{"href":"https://github.com/openshift/origin-web-console/pull/82#discussion_r69021814"},"pull_request":{"href":"https://api.github.com/repos/openshift/origin-web-console/pulls/82"}}},"pull_request":{"url":"https://api.github.com/repos/openshift/origin-web-console/pulls/82","id":74496841,"html_url":"https://github.com/openshift/origin-web-console/pull/82","diff_url":"https://github.com/openshift/origin-web-console/pull/82.diff","patch_url":"https://github.com/openshift/origin-web-console/pull/82.patch","issue_url":"https://api.github.com/repos/openshift/origin-web-console/issues/82","number":82,"state":"open","locked":false,"title":"What can user do","user":{"login":"jhadvig","id":1668218,"avatar_url":"https://avatars.githubusercontent.com/u/1668218?v=3","gravatar_id":"","url":"https://api.github.com/users/jhadvig","html_url":"https://github.com/jhadvig","followers_url":"https://api.github.com/users/jhadvig/followers","following_url":"https://api.github.com/users/jhadvig/following{/other_user}","gists_url":"https://api.github.com/users/jhadvig/gists{/gist_id}","starred_url":"https://api.github.com/users/jhadvig/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jhadvig/subscriptions","organizations_url":"https://api.github.com/users/jhadvig/orgs","repos_url":"https://api.github.com/users/jhadvig/repos","events_url":"https://api.github.com/users/jhadvig/events{/privacy}","received_events_url":"https://api.github.com/users/jhadvig/received_events","type":"User","site_admin":false},"body":"Created a new `AuthorizationService` to determine actions that user can/can't do.\r\nThe new service consists from two main methods:\r\n- `reviewUserRules` \r\n - which serves for reviewing multiple resource/verb pairs (namespaced and also non-namespaced)\r\n - resource/verb pair combinations are listed in the `$scope.canI` variable which should be set in each controller which will call this method.\r\n - obtained rules will be cached, until refreshing the page,changing projects, when 3 minute interval passes\r\n- `canI`\r\n - lightweight version of the first method (response only takes info if user is allowed to perform action on the ressource)\r\n - servers for reviewing single resource/verb pair (namespaced and also non-namespaced)\r\n - does not need `$scope.canI` variable, will create one if not present in controller and adds the  result of the resource/verb review to it.\r\n\r\n@jwforres PTAL","created_at":"2016-06-20T19:13:52Z","updated_at":"2016-06-29T20:33:25Z","closed_at":null,"merged_at":null,"merge_commit_sha":"b6278ef1f1088faaa05850a2025c82aa4791b6dd","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/openshift/origin-web-console/pulls/82/commits","review_comments_url":"https://api.github.com/repos/openshift/origin-web-console/pulls/82/comments","review_comment_url":"https://api.github.com/repos/openshift/origin-web-console/pulls/comments{/number}","comments_url":"https://api.github.com/repos/openshift/origin-web-console/issues/82/comments","statuses_url":"https://api.github.com/repos/openshift/origin-web-console/statuses/33e4aba13deac1a8be8f1bd4b52e67465db7bd99","head":{"label":"jhadvig:can_i","ref":"can_i","sha":"33e4aba13deac1a8be8f1bd4b52e67465db7bd99","user":{"login":"jhadvig","id":1668218,"avatar_url":"https://avatars.githubusercontent.com/u/1668218?v=3","gravatar_id":"","url":"https://api.github.com/users/jhadvig","html_url":"https://github.com/jhadvig","followers_url":"https://api.github.com/users/jhadvig/followers","following_url":"https://api.github.com/users/jhadvig/following{/other_user}","gists_url":"https://api.github.com/users/jhadvig/gists{/gist_id}","starred_url":"https://api.github.com/users/jhadvig/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jhadvig/subscriptions","organizations_url":"https://api.github.com/users/jhadvig/orgs","repos_url":"https://api.github.com/users/jhadvig/repos","events_url":"https://api.github.com/users/jhadvig/events{/privacy}","received_events_url":"https://api.github.com/users/jhadvig/received_events","type":"User","site_admin":false},"repo":{"id":58534077,"name":"origin-web-console","full_name":"jhadvig/origin-web-console","owner":{"login":"jhadvig","id":1668218,"avatar_url":"https://avatars.githubusercontent.com/u/1668218?v=3","gravatar_id":"","url":"https://api.github.com/users/jhadvig","html_url":"https://github.com/jhadvig","followers_url":"https://api.github.com/users/jhadvig/followers","following_url":"https://api.github.com/users/jhadvig/following{/other_user}","gists_url":"https://api.github.com/users/jhadvig/gists{/gist_id}","starred_url":"https://api.github.com/users/jhadvig/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jhadvig/subscriptions","organizations_url":"https://api.github.com/users/jhadvig/orgs","repos_url":"https://api.github.com/users/jhadvig/repos","events_url":"https://api.github.com/users/jhadvig/events{/privacy}","received_events_url":"https://api.github.com/users/jhadvig/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jhadvig/origin-web-console","description":"","fork":true,"url":"https://api.github.com/repos/jhadvig/origin-web-console","forks_url":"https://api.github.com/repos/jhadvig/origin-web-console/forks","keys_url":"https://api.github.com/repos/jhadvig/origin-web-console/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jhadvig/origin-web-console/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jhadvig/origin-web-console/teams","hooks_url":"https://api.github.com/repos/jhadvig/origin-web-console/hooks","issue_events_url":"https://api.github.com/repos/jhadvig/origin-web-console/issues/events{/number}","events_url":"https://api.github.com/repos/jhadvig/origin-web-console/events","assignees_url":"https://api.github.com/repos/jhadvig/origin-web-console/assignees{/user}","branches_url":"https://api.github.com/repos/jhadvig/origin-web-console/branches{/branch}","tags_url":"https://api.github.com/repos/jhadvig/origin-web-console/tags","blobs_url":"https://api.github.com/repos/jhadvig/origin-web-console/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jhadvig/origin-web-console/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jhadvig/origin-web-console/git/refs{/sha}","trees_url":"https://api.github.com/repos/jhadvig/origin-web-console/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jhadvig/origin-web-console/statuses/{sha}","languages_url":"https://api.github.com/repos/jhadvig/origin-web-console/languages","stargazers_url":"https://api.github.com/repos/jhadvig/origin-web-console/stargazers","contributors_url":"https://api.github.com/repos/jhadvig/origin-web-console/contributors","subscribers_url":"https://api.github.com/repos/jhadvig/origin-web-console/subscribers","subscription_url":"https://api.github.com/repos/jhadvig/origin-web-console/subscription","commits_url":"https://api.github.com/repos/jhadvig/origin-web-console/commits{/sha}","git_commits_url":"https://api.github.com/repos/jhadvig/origin-web-console/git/commits{/sha}","comments_url":"https://api.github.com/repos/jhadvig/origin-web-console/comments{/number}","issue_comment_url":"https://api.github.com/repos/jhadvig/origin-web-console/issues/comments{/number}","contents_url":"https://api.github.com/repos/jhadvig/origin-web-console/contents/{+path}","compare_url":"https://api.github.com/repos/jhadvig/origin-web-console/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jhadvig/origin-web-console/merges","archive_url":"https://api.github.com/repos/jhadvig/origin-web-console/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jhadvig/origin-web-console/downloads","issues_url":"https://api.github.com/repos/jhadvig/origin-web-console/issues{/number}","pulls_url":"https://api.github.com/repos/jhadvig/origin-web-console/pulls{/number}","milestones_url":"https://api.github.com/repos/jhadvig/origin-web-console/milestones{/number}","notifications_url":"https://api.github.com/repos/jhadvig/origin-web-console/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jhadvig/origin-web-console/labels{/name}","releases_url":"https://api.github.com/repos/jhadvig/origin-web-console/releases{/id}","deployments_url":"https://api.github.com/repos/jhadvig/origin-web-console/deployments","created_at":"2016-05-11T10:03:41Z","updated_at":"2016-05-11T10:03:42Z","pushed_at":"2016-06-29T16:18:26Z","git_url":"git://github.com/jhadvig/origin-web-console.git","ssh_url":"git@github.com:jhadvig/origin-web-console.git","clone_url":"https://github.com/jhadvig/origin-web-console.git","svn_url":"https://github.com/jhadvig/origin-web-console","homepage":null,"size":6767,"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":"openshift:master","ref":"master","sha":"c777c36c433ea16c8ea2d1d96f0b9882e1e87d82","user":{"login":"openshift","id":792337,"avatar_url":"https://avatars.githubusercontent.com/u/792337?v=3","gravatar_id":"","url":"https://api.github.com/users/openshift","html_url":"https://github.com/openshift","followers_url":"https://api.github.com/users/openshift/followers","following_url":"https://api.github.com/users/openshift/following{/other_user}","gists_url":"https://api.github.com/users/openshift/gists{/gist_id}","starred_url":"https://api.github.com/users/openshift/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openshift/subscriptions","organizations_url":"https://api.github.com/users/openshift/orgs","repos_url":"https://api.github.com/users/openshift/repos","events_url":"https://api.github.com/users/openshift/events{/privacy}","received_events_url":"https://api.github.com/users/openshift/received_events","type":"Organization","site_admin":false},"repo":{"id":58488264,"name":"origin-web-console","full_name":"openshift/origin-web-console","owner":{"login":"openshift","id":792337,"avatar_url":"https://avatars.githubusercontent.com/u/792337?v=3","gravatar_id":"","url":"https://api.github.com/users/openshift","html_url":"https://github.com/openshift","followers_url":"https://api.github.com/users/openshift/followers","following_url":"https://api.github.com/users/openshift/following{/other_user}","gists_url":"https://api.github.com/users/openshift/gists{/gist_id}","starred_url":"https://api.github.com/users/openshift/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openshift/subscriptions","organizations_url":"https://api.github.com/users/openshift/orgs","repos_url":"https://api.github.com/users/openshift/repos","events_url":"https://api.github.com/users/openshift/events{/privacy}","received_events_url":"https://api.github.com/users/openshift/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/openshift/origin-web-console","description":"","fork":false,"url":"https://api.github.com/repos/openshift/origin-web-console","forks_url":"https://api.github.com/repos/openshift/origin-web-console/forks","keys_url":"https://api.github.com/repos/openshift/origin-web-console/keys{/key_id}","collaborators_url":"https://api.github.com/repos/openshift/origin-web-console/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/openshift/origin-web-console/teams","hooks_url":"https://api.github.com/repos/openshift/origin-web-console/hooks","issue_events_url":"https://api.github.com/repos/openshift/origin-web-console/issues/events{/number}","events_url":"https://api.github.com/repos/openshift/origin-web-console/events","assignees_url":"https://api.github.com/repos/openshift/origin-web-console/assignees{/user}","branches_url":"https://api.github.com/repos/openshift/origin-web-console/branches{/branch}","tags_url":"https://api.github.com/repos/openshift/origin-web-console/tags","blobs_url":"https://api.github.com/repos/openshift/origin-web-console/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/openshift/origin-web-console/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/openshift/origin-web-console/git/refs{/sha}","trees_url":"https://api.github.com/repos/openshift/origin-web-console/git/trees{/sha}","statuses_url":"https://api.github.com/repos/openshift/origin-web-console/statuses/{sha}","languages_url":"https://api.github.com/repos/openshift/origin-web-console/languages","stargazers_url":"https://api.github.com/repos/openshift/origin-web-console/stargazers","contributors_url":"https://api.github.com/repos/openshift/origin-web-console/contributors","subscribers_url":"https://api.github.com/repos/openshift/origin-web-console/subscribers","subscription_url":"https://api.github.com/repos/openshift/origin-web-console/subscription","commits_url":"https://api.github.com/repos/openshift/origin-web-console/commits{/sha}","git_commits_url":"https://api.github.com/repos/openshift/origin-web-console/git/commits{/sha}","comments_url":"https://api.github.com/repos/openshift/origin-web-console/comments{/number}","issue_comment_url":"https://api.github.com/repos/openshift/origin-web-console/issues/comments{/number}","contents_url":"https://api.github.com/repos/openshift/origin-web-console/contents/{+path}","compare_url":"https://api.github.com/repos/openshift/origin-web-console/compare/{base}...{head}","merges_url":"https://api.github.com/repos/openshift/origin-web-console/merges","archive_url":"https://api.github.com/repos/openshift/origin-web-console/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/openshift/origin-web-console/downloads","issues_url":"https://api.github.com/repos/openshift/origin-web-console/issues{/number}","pulls_url":"https://api.github.com/repos/openshift/origin-web-console/pulls{/number}","milestones_url":"https://api.github.com/repos/openshift/origin-web-console/milestones{/number}","notifications_url":"https://api.github.com/repos/openshift/origin-web-console/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/openshift/origin-web-console/labels{/name}","releases_url":"https://api.github.com/repos/openshift/origin-web-console/releases{/id}","deployments_url":"https://api.github.com/repos/openshift/origin-web-console/deployments","created_at":"2016-05-10T19:31:50Z","updated_at":"2016-06-20T16:37:07Z","pushed_at":"2016-06-29T20:06:14Z","git_url":"git://github.com/openshift/origin-web-console.git","ssh_url":"git@github.com:openshift/origin-web-console.git","clone_url":"https://github.com/openshift/origin-web-console.git","svn_url":"https://github.com/openshift/origin-web-console","homepage":null,"size":6867,"stargazers_count":13,"watchers_count":13,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":22,"mirror_url":null,"open_issues_count":30,"forks":22,"open_issues":30,"watchers":13,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/openshift/origin-web-console/pulls/82"},"html":{"href":"https://github.com/openshift/origin-web-console/pull/82"},"issue":{"href":"https://api.github.com/repos/openshift/origin-web-console/issues/82"},"comments":{"href":"https://api.github.com/repos/openshift/origin-web-console/issues/82/comments"},"review_comments":{"href":"https://api.github.com/repos/openshift/origin-web-console/pulls/82/comments"},"review_comment":{"href":"https://api.github.com/repos/openshift/origin-web-console/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/openshift/origin-web-console/pulls/82/commits"},"statuses":{"href":"https://api.github.com/repos/openshift/origin-web-console/statuses/33e4aba13deac1a8be8f1bd4b52e67465db7bd99"}}}}
{"actor":{"display_login":"jwforres"}}