{"action":"created","comment":{"url":"https://api.github.com/repos/ballerina-lang/ballerina/pulls/comments/171232941","pull_request_review_id":100048096,"id":171232941,"diff_hunk":"@@ -0,0 +1,102 @@\n+// Copyright (c) 2018 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.\n+//\n+// WSO2 Inc. licenses this file to you under the Apache License,\n+// Version 2.0 (the \"License\"); you may not use this file except\n+// in compliance with the License.\n+// You may obtain a copy of the License at\n+//\n+// http://www.apache.org/licenses/LICENSE-2.0\n+//\n+// Unless required by applicable law or agreed to in writing,\n+// software distributed under the License is distributed on an\n+// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n+// KIND, either express or implied.  See the License for the\n+// specific language governing permissions and limitations\n+// under the License.\n+\n+package ballerina.auth.authz;\n+\n+import ballerina.net.http;\n+import ballerina.auth.utils;\n+import ballerina.auth.authz.permissionstore;\n+import ballerina.log;\n+\n+@Description {value:\"Authorization cache name\"}\n+const string AUTHZ_CACHE = \"authz_cache\";\n+@Description {value:\"Authentication header name\"}\n+const string AUTH_HEADER = \"Authorization\";\n+@Description {value:\"Basic authentication scheme\"}\n+const string AUTH_SCHEME = \"Basic\";\n+\n+@Description {value:\"AuthorizationChecker instance\"}\n+AuthzChecker authzChecker;\n+\n+@Description {value:\"Representation of Authorization Handler\"}\n+public struct HttpAuthzHandler {\n+    // TODO\n+}\n+\n+@Description {value:\"Performs a authorization check, by comparing the groups of the user and the groups of the scope\"}\n+@Param {value:\"req: InRequest instance\"}\n+@Param {value:\"scopeName: name of the scope\"}\n+@Param {value:\"resourceName: name of the resource which is being accessed\"}\n+@Return {value:\"boolean: true if authorization check is a success, else false\"}\n+public function <HttpAuthzHandler httpAuthzHandler> handle (http:InRequest req,\n+                                                                    string scopeName, string resourceName) (boolean) {\n+\n+    // TODO: extracting username and passwords are not required once the Ballerina SecurityContext is available\n+    // extract the header value\n+    var basicAuthHeaderValue, err = utils:extractBasicAuthHeaderValue(req);\n+    if (err != null) {\n+        log:printErrorCause(\"Error in extracting basic authentication header\", err);\n+        return false;\n+    }\n+\n+    string username;\n+    username, _, err = utils:extractBasicAuthCredentials(basicAuthHeaderValue);\n+    if (err != null) {\n+        log:printErrorCause(\"Error in decoding basic authentication header\", err);\n+        return false;\n+    }\n+    if (authzChecker == null) {\n+        permissionstore:FileBasedPermissionStore fileBasedPermissionstore = {};\n+        authzChecker = createChecker((permissionstore:PermissionStore)fileBasedPermissionstore,\n+                                     utils:createCache(AUTHZ_CACHE));\n+    }\n+\n+    // check in the cache. cache key is <username>-<resource>,\n+    // since different resources can have different scopes\n+    string authzCacheKey = username + \"-\" + resourceName;\n+    any cachedAuthzResult = authzChecker.getCachedAuthzResult(authzCacheKey);\n+    if (cachedAuthzResult != null) {\n+        log:printDebug(\"Authz cache hit for user: \" + username + \", request URL: \" + resourceName);\n+        var isAuthorized, typeCastErr = (boolean)cachedAuthzResult;\n+        if (typeCastErr == null) {\n+            // no type cast error, return cached result.\n+            return isAuthorized;\n+        }\n+        // if a casting error occurs, clear the cache entry\n+        authzChecker.clearCachedAuthzResult(authzCacheKey);\n+    }\n+    log:printDebug(\"Authz cache miss for user: \" + username + \", request URL: \" + resourceName);\n+\n+    boolean isAuthorized = authzChecker.check(username, scopeName);\n+    if (isAuthorized) {\n+        log:printInfo(\"Successfully authorized user: \" + username + \" for resource: \" + resourceName);\n+    } else {\n+        log:printInfo(\"Insufficient permission for user: \" + username + \" to access resource: \" + resourceName);","path":"stdlib/ballerina-builtin/src/main/ballerina/ballerina/auth/authz/authz-handler.bal","position":87,"original_position":87,"commit_id":"821afad3b431a16345b3d096fb12f365f194ac8b","original_commit_id":"821afad3b431a16345b3d096fb12f365f194ac8b","user":{"login":"nuwand","id":6469654,"avatar_url":"https://avatars2.githubusercontent.com/u/6469654?v=4","gravatar_id":"","url":"https://api.github.com/users/nuwand","html_url":"https://github.com/nuwand","followers_url":"https://api.github.com/users/nuwand/followers","following_url":"https://api.github.com/users/nuwand/following{/other_user}","gists_url":"https://api.github.com/users/nuwand/gists{/gist_id}","starred_url":"https://api.github.com/users/nuwand/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nuwand/subscriptions","organizations_url":"https://api.github.com/users/nuwand/orgs","repos_url":"https://api.github.com/users/nuwand/repos","events_url":"https://api.github.com/users/nuwand/events{/privacy}","received_events_url":"https://api.github.com/users/nuwand/received_events","type":"User","site_admin":false},"body":"Shouldn't this be an error log? Please note that we shouldn't log the username since it violates GDPR requirements.","created_at":"2018-02-28T12:46:13Z","updated_at":"2018-02-28T12:50:31Z","html_url":"https://github.com/ballerina-lang/ballerina/pull/4895#discussion_r171232941","pull_request_url":"https://api.github.com/repos/ballerina-lang/ballerina/pulls/4895","author_association":"NONE","_links":{"self":{"href":"https://api.github.com/repos/ballerina-lang/ballerina/pulls/comments/171232941"},"html":{"href":"https://github.com/ballerina-lang/ballerina/pull/4895#discussion_r171232941"},"pull_request":{"href":"https://api.github.com/repos/ballerina-lang/ballerina/pulls/4895"}}},"pull_request":{"url":"https://api.github.com/repos/ballerina-lang/ballerina/pulls/4895","id":171599177,"html_url":"https://github.com/ballerina-lang/ballerina/pull/4895","diff_url":"https://github.com/ballerina-lang/ballerina/pull/4895.diff","patch_url":"https://github.com/ballerina-lang/ballerina/pull/4895.patch","issue_url":"https://api.github.com/repos/ballerina-lang/ballerina/issues/4895","number":4895,"state":"open","locked":false,"title":"Add basic authenticator and file based userstore","user":{"login":"isurulucky","id":2777052,"avatar_url":"https://avatars0.githubusercontent.com/u/2777052?v=4","gravatar_id":"","url":"https://api.github.com/users/isurulucky","html_url":"https://github.com/isurulucky","followers_url":"https://api.github.com/users/isurulucky/followers","following_url":"https://api.github.com/users/isurulucky/following{/other_user}","gists_url":"https://api.github.com/users/isurulucky/gists{/gist_id}","starred_url":"https://api.github.com/users/isurulucky/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/isurulucky/subscriptions","organizations_url":"https://api.github.com/users/isurulucky/orgs","repos_url":"https://api.github.com/users/isurulucky/repos","events_url":"https://api.github.com/users/isurulucky/events{/privacy}","received_events_url":"https://api.github.com/users/isurulucky/received_events","type":"User","site_admin":false},"body":"## Purpose\r\n> Provides a way to secure Services with basic authentication, with a simple file based userstore.\r\n\r\n## Approach\r\n> The API provided has two methods to authenticate and authorize the user. Currently, the Service developer needs to engage the security manually by calling the methods, as shown in the sample. The userstore is a file based one, which uses the ballerina.conf file format to store users, password hashes, scopes, groups and the mapping between these entities.\r\n\r\n## Samples\r\n> https://github.com/isurulucky/Ballerina-Secure-Helloworld","created_at":"2018-02-27T09:00:42Z","updated_at":"2018-02-28T12:50:31Z","closed_at":null,"merged_at":null,"merge_commit_sha":"80065bad53598140510ab6f82e6ce6c2d2364819","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/ballerina-lang/ballerina/pulls/4895/commits","review_comments_url":"https://api.github.com/repos/ballerina-lang/ballerina/pulls/4895/comments","review_comment_url":"https://api.github.com/repos/ballerina-lang/ballerina/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ballerina-lang/ballerina/issues/4895/comments","statuses_url":"https://api.github.com/repos/ballerina-lang/ballerina/statuses/821afad3b431a16345b3d096fb12f365f194ac8b","head":{"label":"isurulucky:master","ref":"master","sha":"821afad3b431a16345b3d096fb12f365f194ac8b","user":{"login":"isurulucky","id":2777052,"avatar_url":"https://avatars0.githubusercontent.com/u/2777052?v=4","gravatar_id":"","url":"https://api.github.com/users/isurulucky","html_url":"https://github.com/isurulucky","followers_url":"https://api.github.com/users/isurulucky/followers","following_url":"https://api.github.com/users/isurulucky/following{/other_user}","gists_url":"https://api.github.com/users/isurulucky/gists{/gist_id}","starred_url":"https://api.github.com/users/isurulucky/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/isurulucky/subscriptions","organizations_url":"https://api.github.com/users/isurulucky/orgs","repos_url":"https://api.github.com/users/isurulucky/repos","events_url":"https://api.github.com/users/isurulucky/events{/privacy}","received_events_url":"https://api.github.com/users/isurulucky/received_events","type":"User","site_admin":false},"repo":{"id":122618419,"name":"ballerina","full_name":"isurulucky/ballerina","owner":{"login":"isurulucky","id":2777052,"avatar_url":"https://avatars0.githubusercontent.com/u/2777052?v=4","gravatar_id":"","url":"https://api.github.com/users/isurulucky","html_url":"https://github.com/isurulucky","followers_url":"https://api.github.com/users/isurulucky/followers","following_url":"https://api.github.com/users/isurulucky/following{/other_user}","gists_url":"https://api.github.com/users/isurulucky/gists{/gist_id}","starred_url":"https://api.github.com/users/isurulucky/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/isurulucky/subscriptions","organizations_url":"https://api.github.com/users/isurulucky/orgs","repos_url":"https://api.github.com/users/isurulucky/repos","events_url":"https://api.github.com/users/isurulucky/events{/privacy}","received_events_url":"https://api.github.com/users/isurulucky/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/isurulucky/ballerina","description":"Ballerina is a new programming language for integration built on a sequence diagram metaphor.","fork":true,"url":"https://api.github.com/repos/isurulucky/ballerina","forks_url":"https://api.github.com/repos/isurulucky/ballerina/forks","keys_url":"https://api.github.com/repos/isurulucky/ballerina/keys{/key_id}","collaborators_url":"https://api.github.com/repos/isurulucky/ballerina/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/isurulucky/ballerina/teams","hooks_url":"https://api.github.com/repos/isurulucky/ballerina/hooks","issue_events_url":"https://api.github.com/repos/isurulucky/ballerina/issues/events{/number}","events_url":"https://api.github.com/repos/isurulucky/ballerina/events","assignees_url":"https://api.github.com/repos/isurulucky/ballerina/assignees{/user}","branches_url":"https://api.github.com/repos/isurulucky/ballerina/branches{/branch}","tags_url":"https://api.github.com/repos/isurulucky/ballerina/tags","blobs_url":"https://api.github.com/repos/isurulucky/ballerina/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/isurulucky/ballerina/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/isurulucky/ballerina/git/refs{/sha}","trees_url":"https://api.github.com/repos/isurulucky/ballerina/git/trees{/sha}","statuses_url":"https://api.github.com/repos/isurulucky/ballerina/statuses/{sha}","languages_url":"https://api.github.com/repos/isurulucky/ballerina/languages","stargazers_url":"https://api.github.com/repos/isurulucky/ballerina/stargazers","contributors_url":"https://api.github.com/repos/isurulucky/ballerina/contributors","subscribers_url":"https://api.github.com/repos/isurulucky/ballerina/subscribers","subscription_url":"https://api.github.com/repos/isurulucky/ballerina/subscription","commits_url":"https://api.github.com/repos/isurulucky/ballerina/commits{/sha}","git_commits_url":"https://api.github.com/repos/isurulucky/ballerina/git/commits{/sha}","comments_url":"https://api.github.com/repos/isurulucky/ballerina/comments{/number}","issue_comment_url":"https://api.github.com/repos/isurulucky/ballerina/issues/comments{/number}","contents_url":"https://api.github.com/repos/isurulucky/ballerina/contents/{+path}","compare_url":"https://api.github.com/repos/isurulucky/ballerina/compare/{base}...{head}","merges_url":"https://api.github.com/repos/isurulucky/ballerina/merges","archive_url":"https://api.github.com/repos/isurulucky/ballerina/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/isurulucky/ballerina/downloads","issues_url":"https://api.github.com/repos/isurulucky/ballerina/issues{/number}","pulls_url":"https://api.github.com/repos/isurulucky/ballerina/pulls{/number}","milestones_url":"https://api.github.com/repos/isurulucky/ballerina/milestones{/number}","notifications_url":"https://api.github.com/repos/isurulucky/ballerina/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/isurulucky/ballerina/labels{/name}","releases_url":"https://api.github.com/repos/isurulucky/ballerina/releases{/id}","deployments_url":"https://api.github.com/repos/isurulucky/ballerina/deployments","created_at":"2018-02-23T12:26:33Z","updated_at":"2018-02-23T12:26:47Z","pushed_at":"2018-02-28T04:26:14Z","git_url":"git://github.com/isurulucky/ballerina.git","ssh_url":"git@github.com:isurulucky/ballerina.git","clone_url":"https://github.com/isurulucky/ballerina.git","svn_url":"https://github.com/isurulucky/ballerina","homepage":"","size":155215,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"other","name":"Other","spdx_id":null,"url":null},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"ballerina-lang:master","ref":"master","sha":"397048202402d9b5390d3e8c86b1a520e3ea538c","user":{"login":"ballerina-lang","id":24777199,"avatar_url":"https://avatars1.githubusercontent.com/u/24777199?v=4","gravatar_id":"","url":"https://api.github.com/users/ballerina-lang","html_url":"https://github.com/ballerina-lang","followers_url":"https://api.github.com/users/ballerina-lang/followers","following_url":"https://api.github.com/users/ballerina-lang/following{/other_user}","gists_url":"https://api.github.com/users/ballerina-lang/gists{/gist_id}","starred_url":"https://api.github.com/users/ballerina-lang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ballerina-lang/subscriptions","organizations_url":"https://api.github.com/users/ballerina-lang/orgs","repos_url":"https://api.github.com/users/ballerina-lang/repos","events_url":"https://api.github.com/users/ballerina-lang/events{/privacy}","received_events_url":"https://api.github.com/users/ballerina-lang/received_events","type":"Organization","site_admin":false},"repo":{"id":73930305,"name":"ballerina","full_name":"ballerina-lang/ballerina","owner":{"login":"ballerina-lang","id":24777199,"avatar_url":"https://avatars1.githubusercontent.com/u/24777199?v=4","gravatar_id":"","url":"https://api.github.com/users/ballerina-lang","html_url":"https://github.com/ballerina-lang","followers_url":"https://api.github.com/users/ballerina-lang/followers","following_url":"https://api.github.com/users/ballerina-lang/following{/other_user}","gists_url":"https://api.github.com/users/ballerina-lang/gists{/gist_id}","starred_url":"https://api.github.com/users/ballerina-lang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ballerina-lang/subscriptions","organizations_url":"https://api.github.com/users/ballerina-lang/orgs","repos_url":"https://api.github.com/users/ballerina-lang/repos","events_url":"https://api.github.com/users/ballerina-lang/events{/privacy}","received_events_url":"https://api.github.com/users/ballerina-lang/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ballerina-lang/ballerina","description":"Ballerina is a new programming language for integration built on a sequence diagram metaphor.","fork":false,"url":"https://api.github.com/repos/ballerina-lang/ballerina","forks_url":"https://api.github.com/repos/ballerina-lang/ballerina/forks","keys_url":"https://api.github.com/repos/ballerina-lang/ballerina/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ballerina-lang/ballerina/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ballerina-lang/ballerina/teams","hooks_url":"https://api.github.com/repos/ballerina-lang/ballerina/hooks","issue_events_url":"https://api.github.com/repos/ballerina-lang/ballerina/issues/events{/number}","events_url":"https://api.github.com/repos/ballerina-lang/ballerina/events","assignees_url":"https://api.github.com/repos/ballerina-lang/ballerina/assignees{/user}","branches_url":"https://api.github.com/repos/ballerina-lang/ballerina/branches{/branch}","tags_url":"https://api.github.com/repos/ballerina-lang/ballerina/tags","blobs_url":"https://api.github.com/repos/ballerina-lang/ballerina/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ballerina-lang/ballerina/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ballerina-lang/ballerina/git/refs{/sha}","trees_url":"https://api.github.com/repos/ballerina-lang/ballerina/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ballerina-lang/ballerina/statuses/{sha}","languages_url":"https://api.github.com/repos/ballerina-lang/ballerina/languages","stargazers_url":"https://api.github.com/repos/ballerina-lang/ballerina/stargazers","contributors_url":"https://api.github.com/repos/ballerina-lang/ballerina/contributors","subscribers_url":"https://api.github.com/repos/ballerina-lang/ballerina/subscribers","subscription_url":"https://api.github.com/repos/ballerina-lang/ballerina/subscription","commits_url":"https://api.github.com/repos/ballerina-lang/ballerina/commits{/sha}","git_commits_url":"https://api.github.com/repos/ballerina-lang/ballerina/git/commits{/sha}","comments_url":"https://api.github.com/repos/ballerina-lang/ballerina/comments{/number}","issue_comment_url":"https://api.github.com/repos/ballerina-lang/ballerina/issues/comments{/number}","contents_url":"https://api.github.com/repos/ballerina-lang/ballerina/contents/{+path}","compare_url":"https://api.github.com/repos/ballerina-lang/ballerina/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ballerina-lang/ballerina/merges","archive_url":"https://api.github.com/repos/ballerina-lang/ballerina/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ballerina-lang/ballerina/downloads","issues_url":"https://api.github.com/repos/ballerina-lang/ballerina/issues{/number}","pulls_url":"https://api.github.com/repos/ballerina-lang/ballerina/pulls{/number}","milestones_url":"https://api.github.com/repos/ballerina-lang/ballerina/milestones{/number}","notifications_url":"https://api.github.com/repos/ballerina-lang/ballerina/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ballerina-lang/ballerina/labels{/name}","releases_url":"https://api.github.com/repos/ballerina-lang/ballerina/releases{/id}","deployments_url":"https://api.github.com/repos/ballerina-lang/ballerina/deployments","created_at":"2016-11-16T14:58:44Z","updated_at":"2018-02-26T16:32:50Z","pushed_at":"2018-02-28T12:15:33Z","git_url":"git://github.com/ballerina-lang/ballerina.git","ssh_url":"git@github.com:ballerina-lang/ballerina.git","clone_url":"https://github.com/ballerina-lang/ballerina.git","svn_url":"https://github.com/ballerina-lang/ballerina","homepage":"","size":155666,"stargazers_count":235,"watchers_count":235,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":224,"mirror_url":null,"archived":false,"open_issues_count":491,"license":{"key":"other","name":"Other","spdx_id":null,"url":null},"forks":224,"open_issues":491,"watchers":235,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ballerina-lang/ballerina/pulls/4895"},"html":{"href":"https://github.com/ballerina-lang/ballerina/pull/4895"},"issue":{"href":"https://api.github.com/repos/ballerina-lang/ballerina/issues/4895"},"comments":{"href":"https://api.github.com/repos/ballerina-lang/ballerina/issues/4895/comments"},"review_comments":{"href":"https://api.github.com/repos/ballerina-lang/ballerina/pulls/4895/comments"},"review_comment":{"href":"https://api.github.com/repos/ballerina-lang/ballerina/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ballerina-lang/ballerina/pulls/4895/commits"},"statuses":{"href":"https://api.github.com/repos/ballerina-lang/ballerina/statuses/821afad3b431a16345b3d096fb12f365f194ac8b"}},"author_association":"NONE"}}
{"actor":{"display_login":"nuwand"}}