{"action":"created","comment":{"url":"https://api.github.com/repos/uclapi/uclapi/pulls/comments/131995134","pull_request_review_id":55029431,"id":131995134,"diff_hunk":"@@ -0,0 +1,72 @@\n+import base64\n+import hashlib\n+import hmac\n+import redis\n+\n+from django.core.exceptions import ObjectDoesNotExist\n+\n+from roombookings.helpers import PrettyJsonResponse as JsonResponse\n+from uclapi.settings import REDIS_UCLAPI_HOST\n+\n+from .models import OAuthToken\n+from .scoping import Scopes\n+\n+\n+def oauth_token_check(required_scopes=None):\n+    def oauth_token_and_scope(view_func):\n+        def wrapped(request, *args, **kwargs):\n+            try:\n+                client_secret = request.GET['client_secret']\n+            except KeyError:\n+                response = JsonResponse({\n+                    \"ok\": False,\n+                    \"error\": \"No Client Secret provided\"\n+                })\n+                response.status_code = 400\n+                return response\n+\n+            try:\n+                token_code = request.GET[\"token\"]\n+            except KeyError:\n+                response = JsonResponse({\n+                    \"ok\": False,\n+                    \"error\": \"No token provided via GET.\"\n+                })\n+                response.status_code = 400\n+                return response\n+\n+            try:\n+                token = OAuthToken.objects.get(token=token_code)\n+            except Token.DoesNotExist:","path":"backend/uclapi/oauth/decorators.py","position":40,"original_position":40,"commit_id":"1efa7d86ae5bfb04a67f7e36bdbbf628cc211cf2","original_commit_id":"1efa7d86ae5bfb04a67f7e36bdbbf628cc211cf2","user":{"login":"houndci-bot","id":6697940,"avatar_url":"https://avatars0.githubusercontent.com/u/6697940?v=4","gravatar_id":"","url":"https://api.github.com/users/houndci-bot","html_url":"https://github.com/houndci-bot","followers_url":"https://api.github.com/users/houndci-bot/followers","following_url":"https://api.github.com/users/houndci-bot/following{/other_user}","gists_url":"https://api.github.com/users/houndci-bot/gists{/gist_id}","starred_url":"https://api.github.com/users/houndci-bot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/houndci-bot/subscriptions","organizations_url":"https://api.github.com/users/houndci-bot/orgs","repos_url":"https://api.github.com/users/houndci-bot/repos","events_url":"https://api.github.com/users/houndci-bot/events{/privacy}","received_events_url":"https://api.github.com/users/houndci-bot/received_events","type":"User","site_admin":false},"body":"undefined name 'Token'","created_at":"2017-08-08T18:31:14Z","updated_at":"2017-08-08T18:31:15Z","html_url":"https://github.com/uclapi/uclapi/pull/84#discussion_r131995134","pull_request_url":"https://api.github.com/repos/uclapi/uclapi/pulls/84","_links":{"self":{"href":"https://api.github.com/repos/uclapi/uclapi/pulls/comments/131995134"},"html":{"href":"https://github.com/uclapi/uclapi/pull/84#discussion_r131995134"},"pull_request":{"href":"https://api.github.com/repos/uclapi/uclapi/pulls/84"}}},"pull_request":{"url":"https://api.github.com/repos/uclapi/uclapi/pulls/84","id":123960831,"html_url":"https://github.com/uclapi/uclapi/pull/84","diff_url":"https://github.com/uclapi/uclapi/pull/84.diff","patch_url":"https://github.com/uclapi/uclapi/pull/84.patch","issue_url":"https://api.github.com/repos/uclapi/uclapi/issues/84","number":84,"state":"open","locked":false,"title":"OAuth Support","user":{"login":"ChristopherHammond13","id":295396,"avatar_url":"https://avatars0.githubusercontent.com/u/295396?v=4","gravatar_id":"","url":"https://api.github.com/users/ChristopherHammond13","html_url":"https://github.com/ChristopherHammond13","followers_url":"https://api.github.com/users/ChristopherHammond13/followers","following_url":"https://api.github.com/users/ChristopherHammond13/following{/other_user}","gists_url":"https://api.github.com/users/ChristopherHammond13/gists{/gist_id}","starred_url":"https://api.github.com/users/ChristopherHammond13/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ChristopherHammond13/subscriptions","organizations_url":"https://api.github.com/users/ChristopherHammond13/orgs","repos_url":"https://api.github.com/users/ChristopherHammond13/repos","events_url":"https://api.github.com/users/ChristopherHammond13/events{/privacy}","received_events_url":"https://api.github.com/users/ChristopherHammond13/received_events","type":"User","site_admin":false},"body":"## What does this PR do?\r\nIt is a work in progress implementation of OAuth built on top of UCL's Shibboleth SSO system.\r\n\r\nIt is currently a Work in Progress and fails to adhere to a lot of the OAuth standard at the moment, but now that we have redis it will be much easier to cache away codes, for example, in order to bring us closer to the OAuth 2.0: [RFC6749](https://tools.ietf.org/html/rfc6749).\r\n\r\nThe specification defined in this code at this time is both undocumented and subject to change, so developers should not yet attempt to build client libraries on top of this. When the code is complete we will release it into production and also announce a number of libraries written for you.\r\n\r\n## ✅ Pull Request checklist\r\n\r\n- [x] Is this code complete?\r\n- [x] Are tests done/modified?\r\n\r\n## 🚨 Is this a breaking change for API clients?\r\nNo\r\n\r\n## :squirrel: Deploy notes\r\nFor example: Need to run migrations as part of deployment\r\nInstall requirements, run migrations, ???, Profit.\r\n\r\n## Anything else\r\nAs noted, this is currently a _work in progress_ and the specification is not yet adhered to. Suggestions are, of course, welcome, as are tests and code review.","created_at":"2017-06-05T11:34:13Z","updated_at":"2017-08-08T18:31:15Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ea7ab1c3ba9d515fef72b4d80f382f1bbcb67083","assignee":{"login":"ChristopherHammond13","id":295396,"avatar_url":"https://avatars0.githubusercontent.com/u/295396?v=4","gravatar_id":"","url":"https://api.github.com/users/ChristopherHammond13","html_url":"https://github.com/ChristopherHammond13","followers_url":"https://api.github.com/users/ChristopherHammond13/followers","following_url":"https://api.github.com/users/ChristopherHammond13/following{/other_user}","gists_url":"https://api.github.com/users/ChristopherHammond13/gists{/gist_id}","starred_url":"https://api.github.com/users/ChristopherHammond13/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ChristopherHammond13/subscriptions","organizations_url":"https://api.github.com/users/ChristopherHammond13/orgs","repos_url":"https://api.github.com/users/ChristopherHammond13/repos","events_url":"https://api.github.com/users/ChristopherHammond13/events{/privacy}","received_events_url":"https://api.github.com/users/ChristopherHammond13/received_events","type":"User","site_admin":false},"assignees":[{"login":"ChristopherHammond13","id":295396,"avatar_url":"https://avatars0.githubusercontent.com/u/295396?v=4","gravatar_id":"","url":"https://api.github.com/users/ChristopherHammond13","html_url":"https://github.com/ChristopherHammond13","followers_url":"https://api.github.com/users/ChristopherHammond13/followers","following_url":"https://api.github.com/users/ChristopherHammond13/following{/other_user}","gists_url":"https://api.github.com/users/ChristopherHammond13/gists{/gist_id}","starred_url":"https://api.github.com/users/ChristopherHammond13/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ChristopherHammond13/subscriptions","organizations_url":"https://api.github.com/users/ChristopherHammond13/orgs","repos_url":"https://api.github.com/users/ChristopherHammond13/repos","events_url":"https://api.github.com/users/ChristopherHammond13/events{/privacy}","received_events_url":"https://api.github.com/users/ChristopherHammond13/received_events","type":"User","site_admin":false},{"login":"jermenkoo","id":1312709,"avatar_url":"https://avatars1.githubusercontent.com/u/1312709?v=4","gravatar_id":"","url":"https://api.github.com/users/jermenkoo","html_url":"https://github.com/jermenkoo","followers_url":"https://api.github.com/users/jermenkoo/followers","following_url":"https://api.github.com/users/jermenkoo/following{/other_user}","gists_url":"https://api.github.com/users/jermenkoo/gists{/gist_id}","starred_url":"https://api.github.com/users/jermenkoo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jermenkoo/subscriptions","organizations_url":"https://api.github.com/users/jermenkoo/orgs","repos_url":"https://api.github.com/users/jermenkoo/repos","events_url":"https://api.github.com/users/jermenkoo/events{/privacy}","received_events_url":"https://api.github.com/users/jermenkoo/received_events","type":"User","site_admin":false},{"login":"Faiz","id":11671977,"avatar_url":"https://avatars0.githubusercontent.com/u/11671977?v=4","gravatar_id":"","url":"https://api.github.com/users/Faiz","html_url":"https://github.com/Faiz","followers_url":"https://api.github.com/users/Faiz/followers","following_url":"https://api.github.com/users/Faiz/following{/other_user}","gists_url":"https://api.github.com/users/Faiz/gists{/gist_id}","starred_url":"https://api.github.com/users/Faiz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Faiz/subscriptions","organizations_url":"https://api.github.com/users/Faiz/orgs","repos_url":"https://api.github.com/users/Faiz/repos","events_url":"https://api.github.com/users/Faiz/events{/privacy}","received_events_url":"https://api.github.com/users/Faiz/received_events","type":"User","site_admin":false}],"requested_reviewers":[{"login":"Faiz","id":11671977,"avatar_url":"https://avatars0.githubusercontent.com/u/11671977?v=4","gravatar_id":"","url":"https://api.github.com/users/Faiz","html_url":"https://github.com/Faiz","followers_url":"https://api.github.com/users/Faiz/followers","following_url":"https://api.github.com/users/Faiz/following{/other_user}","gists_url":"https://api.github.com/users/Faiz/gists{/gist_id}","starred_url":"https://api.github.com/users/Faiz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Faiz/subscriptions","organizations_url":"https://api.github.com/users/Faiz/orgs","repos_url":"https://api.github.com/users/Faiz/repos","events_url":"https://api.github.com/users/Faiz/events{/privacy}","received_events_url":"https://api.github.com/users/Faiz/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/uclapi/uclapi/pulls/84/commits","review_comments_url":"https://api.github.com/repos/uclapi/uclapi/pulls/84/comments","review_comment_url":"https://api.github.com/repos/uclapi/uclapi/pulls/comments{/number}","comments_url":"https://api.github.com/repos/uclapi/uclapi/issues/84/comments","statuses_url":"https://api.github.com/repos/uclapi/uclapi/statuses/1efa7d86ae5bfb04a67f7e36bdbbf628cc211cf2","head":{"label":"uclapi:OAuth","ref":"OAuth","sha":"1efa7d86ae5bfb04a67f7e36bdbbf628cc211cf2","user":{"login":"uclapi","id":21985736,"avatar_url":"https://avatars1.githubusercontent.com/u/21985736?v=4","gravatar_id":"","url":"https://api.github.com/users/uclapi","html_url":"https://github.com/uclapi","followers_url":"https://api.github.com/users/uclapi/followers","following_url":"https://api.github.com/users/uclapi/following{/other_user}","gists_url":"https://api.github.com/users/uclapi/gists{/gist_id}","starred_url":"https://api.github.com/users/uclapi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uclapi/subscriptions","organizations_url":"https://api.github.com/users/uclapi/orgs","repos_url":"https://api.github.com/users/uclapi/repos","events_url":"https://api.github.com/users/uclapi/events{/privacy}","received_events_url":"https://api.github.com/users/uclapi/received_events","type":"Organization","site_admin":false},"repo":{"id":76891826,"name":"uclapi","full_name":"uclapi/uclapi","owner":{"login":"uclapi","id":21985736,"avatar_url":"https://avatars1.githubusercontent.com/u/21985736?v=4","gravatar_id":"","url":"https://api.github.com/users/uclapi","html_url":"https://github.com/uclapi","followers_url":"https://api.github.com/users/uclapi/followers","following_url":"https://api.github.com/users/uclapi/following{/other_user}","gists_url":"https://api.github.com/users/uclapi/gists{/gist_id}","starred_url":"https://api.github.com/users/uclapi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uclapi/subscriptions","organizations_url":"https://api.github.com/users/uclapi/orgs","repos_url":"https://api.github.com/users/uclapi/repos","events_url":"https://api.github.com/users/uclapi/events{/privacy}","received_events_url":"https://api.github.com/users/uclapi/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/uclapi/uclapi","description":"UCL API Main Repository","fork":false,"url":"https://api.github.com/repos/uclapi/uclapi","forks_url":"https://api.github.com/repos/uclapi/uclapi/forks","keys_url":"https://api.github.com/repos/uclapi/uclapi/keys{/key_id}","collaborators_url":"https://api.github.com/repos/uclapi/uclapi/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/uclapi/uclapi/teams","hooks_url":"https://api.github.com/repos/uclapi/uclapi/hooks","issue_events_url":"https://api.github.com/repos/uclapi/uclapi/issues/events{/number}","events_url":"https://api.github.com/repos/uclapi/uclapi/events","assignees_url":"https://api.github.com/repos/uclapi/uclapi/assignees{/user}","branches_url":"https://api.github.com/repos/uclapi/uclapi/branches{/branch}","tags_url":"https://api.github.com/repos/uclapi/uclapi/tags","blobs_url":"https://api.github.com/repos/uclapi/uclapi/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/uclapi/uclapi/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/uclapi/uclapi/git/refs{/sha}","trees_url":"https://api.github.com/repos/uclapi/uclapi/git/trees{/sha}","statuses_url":"https://api.github.com/repos/uclapi/uclapi/statuses/{sha}","languages_url":"https://api.github.com/repos/uclapi/uclapi/languages","stargazers_url":"https://api.github.com/repos/uclapi/uclapi/stargazers","contributors_url":"https://api.github.com/repos/uclapi/uclapi/contributors","subscribers_url":"https://api.github.com/repos/uclapi/uclapi/subscribers","subscription_url":"https://api.github.com/repos/uclapi/uclapi/subscription","commits_url":"https://api.github.com/repos/uclapi/uclapi/commits{/sha}","git_commits_url":"https://api.github.com/repos/uclapi/uclapi/git/commits{/sha}","comments_url":"https://api.github.com/repos/uclapi/uclapi/comments{/number}","issue_comment_url":"https://api.github.com/repos/uclapi/uclapi/issues/comments{/number}","contents_url":"https://api.github.com/repos/uclapi/uclapi/contents/{+path}","compare_url":"https://api.github.com/repos/uclapi/uclapi/compare/{base}...{head}","merges_url":"https://api.github.com/repos/uclapi/uclapi/merges","archive_url":"https://api.github.com/repos/uclapi/uclapi/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/uclapi/uclapi/downloads","issues_url":"https://api.github.com/repos/uclapi/uclapi/issues{/number}","pulls_url":"https://api.github.com/repos/uclapi/uclapi/pulls{/number}","milestones_url":"https://api.github.com/repos/uclapi/uclapi/milestones{/number}","notifications_url":"https://api.github.com/repos/uclapi/uclapi/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/uclapi/uclapi/labels{/name}","releases_url":"https://api.github.com/repos/uclapi/uclapi/releases{/id}","deployments_url":"https://api.github.com/repos/uclapi/uclapi/deployments","created_at":"2016-12-19T19:41:08Z","updated_at":"2017-07-01T18:55:23Z","pushed_at":"2017-08-08T18:30:44Z","git_url":"git://github.com/uclapi/uclapi.git","ssh_url":"git@github.com:uclapi/uclapi.git","clone_url":"https://github.com/uclapi/uclapi.git","svn_url":"https://github.com/uclapi/uclapi","homepage":"https://uclapi.com","size":22758,"stargazers_count":7,"watchers_count":7,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"open_issues_count":5,"forks":3,"open_issues":5,"watchers":7,"default_branch":"master"}},"base":{"label":"uclapi:master","ref":"master","sha":"c19738b2290fc6b6e57efcae84d8e3cde88d3b58","user":{"login":"uclapi","id":21985736,"avatar_url":"https://avatars1.githubusercontent.com/u/21985736?v=4","gravatar_id":"","url":"https://api.github.com/users/uclapi","html_url":"https://github.com/uclapi","followers_url":"https://api.github.com/users/uclapi/followers","following_url":"https://api.github.com/users/uclapi/following{/other_user}","gists_url":"https://api.github.com/users/uclapi/gists{/gist_id}","starred_url":"https://api.github.com/users/uclapi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uclapi/subscriptions","organizations_url":"https://api.github.com/users/uclapi/orgs","repos_url":"https://api.github.com/users/uclapi/repos","events_url":"https://api.github.com/users/uclapi/events{/privacy}","received_events_url":"https://api.github.com/users/uclapi/received_events","type":"Organization","site_admin":false},"repo":{"id":76891826,"name":"uclapi","full_name":"uclapi/uclapi","owner":{"login":"uclapi","id":21985736,"avatar_url":"https://avatars1.githubusercontent.com/u/21985736?v=4","gravatar_id":"","url":"https://api.github.com/users/uclapi","html_url":"https://github.com/uclapi","followers_url":"https://api.github.com/users/uclapi/followers","following_url":"https://api.github.com/users/uclapi/following{/other_user}","gists_url":"https://api.github.com/users/uclapi/gists{/gist_id}","starred_url":"https://api.github.com/users/uclapi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uclapi/subscriptions","organizations_url":"https://api.github.com/users/uclapi/orgs","repos_url":"https://api.github.com/users/uclapi/repos","events_url":"https://api.github.com/users/uclapi/events{/privacy}","received_events_url":"https://api.github.com/users/uclapi/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/uclapi/uclapi","description":"UCL API Main Repository","fork":false,"url":"https://api.github.com/repos/uclapi/uclapi","forks_url":"https://api.github.com/repos/uclapi/uclapi/forks","keys_url":"https://api.github.com/repos/uclapi/uclapi/keys{/key_id}","collaborators_url":"https://api.github.com/repos/uclapi/uclapi/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/uclapi/uclapi/teams","hooks_url":"https://api.github.com/repos/uclapi/uclapi/hooks","issue_events_url":"https://api.github.com/repos/uclapi/uclapi/issues/events{/number}","events_url":"https://api.github.com/repos/uclapi/uclapi/events","assignees_url":"https://api.github.com/repos/uclapi/uclapi/assignees{/user}","branches_url":"https://api.github.com/repos/uclapi/uclapi/branches{/branch}","tags_url":"https://api.github.com/repos/uclapi/uclapi/tags","blobs_url":"https://api.github.com/repos/uclapi/uclapi/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/uclapi/uclapi/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/uclapi/uclapi/git/refs{/sha}","trees_url":"https://api.github.com/repos/uclapi/uclapi/git/trees{/sha}","statuses_url":"https://api.github.com/repos/uclapi/uclapi/statuses/{sha}","languages_url":"https://api.github.com/repos/uclapi/uclapi/languages","stargazers_url":"https://api.github.com/repos/uclapi/uclapi/stargazers","contributors_url":"https://api.github.com/repos/uclapi/uclapi/contributors","subscribers_url":"https://api.github.com/repos/uclapi/uclapi/subscribers","subscription_url":"https://api.github.com/repos/uclapi/uclapi/subscription","commits_url":"https://api.github.com/repos/uclapi/uclapi/commits{/sha}","git_commits_url":"https://api.github.com/repos/uclapi/uclapi/git/commits{/sha}","comments_url":"https://api.github.com/repos/uclapi/uclapi/comments{/number}","issue_comment_url":"https://api.github.com/repos/uclapi/uclapi/issues/comments{/number}","contents_url":"https://api.github.com/repos/uclapi/uclapi/contents/{+path}","compare_url":"https://api.github.com/repos/uclapi/uclapi/compare/{base}...{head}","merges_url":"https://api.github.com/repos/uclapi/uclapi/merges","archive_url":"https://api.github.com/repos/uclapi/uclapi/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/uclapi/uclapi/downloads","issues_url":"https://api.github.com/repos/uclapi/uclapi/issues{/number}","pulls_url":"https://api.github.com/repos/uclapi/uclapi/pulls{/number}","milestones_url":"https://api.github.com/repos/uclapi/uclapi/milestones{/number}","notifications_url":"https://api.github.com/repos/uclapi/uclapi/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/uclapi/uclapi/labels{/name}","releases_url":"https://api.github.com/repos/uclapi/uclapi/releases{/id}","deployments_url":"https://api.github.com/repos/uclapi/uclapi/deployments","created_at":"2016-12-19T19:41:08Z","updated_at":"2017-07-01T18:55:23Z","pushed_at":"2017-08-08T18:30:44Z","git_url":"git://github.com/uclapi/uclapi.git","ssh_url":"git@github.com:uclapi/uclapi.git","clone_url":"https://github.com/uclapi/uclapi.git","svn_url":"https://github.com/uclapi/uclapi","homepage":"https://uclapi.com","size":22758,"stargazers_count":7,"watchers_count":7,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"open_issues_count":5,"forks":3,"open_issues":5,"watchers":7,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/uclapi/uclapi/pulls/84"},"html":{"href":"https://github.com/uclapi/uclapi/pull/84"},"issue":{"href":"https://api.github.com/repos/uclapi/uclapi/issues/84"},"comments":{"href":"https://api.github.com/repos/uclapi/uclapi/issues/84/comments"},"review_comments":{"href":"https://api.github.com/repos/uclapi/uclapi/pulls/84/comments"},"review_comment":{"href":"https://api.github.com/repos/uclapi/uclapi/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/uclapi/uclapi/pulls/84/commits"},"statuses":{"href":"https://api.github.com/repos/uclapi/uclapi/statuses/1efa7d86ae5bfb04a67f7e36bdbbf628cc211cf2"}}}}
{"actor":{"display_login":"houndci-bot"}}