{"action":"created","comment":{"url":"https://api.github.com/repos/wikimedia/authoid/pulls/comments/78598490","id":78598490,"diff_hunk":"@@ -0,0 +1,238 @@\n+\"use strict\";\n+\n+const HyperSwitch = require('hyperswitch');\n+const URI = HyperSwitch.URI;\n+const HTTPError = HyperSwitch.HTTPError;\n+const authLib = require('../sys/AuthLibrary');\n+\n+const spec = HyperSwitch.utils.loadSpec(__dirname + '/auth.yaml');\n+\n+const passwordTable = {\n+    name: 'auth_passwords',\n+    uri: '/wikimedia.org/sys/table/auth_passwords',\n+    entryURI: new URI(['wikimedia.org', 'sys', 'table', 'auth_passwords', '']),\n+    schema: {\n+        table: 'auth_passwords',\n+        version: 1,\n+        attributes: {\n+            userid: 'string',\n+            pass_hash: 'string',\n+            deleted: 'boolean',\n+        },\n+        index: [\n+            { attribute: 'userid', type: 'hash' },\n+        ],\n+        revisionRetentionPolicy: {\n+            type: 'latest',\n+            count: 1,\n+            grace_ttl: 0\n+        }\n+    }\n+};\n+\n+const tokenTable = {\n+    name: 'auth_tokens',\n+    uri: '/wikimedia.org/sys/table/auth_tokens',\n+    entryURI: new URI(['wikimedia.org', 'sys', 'table', 'auth_tokens', '']),\n+    schema: {\n+        table: 'auth_tokens',\n+        version: 1,\n+        attributes: {\n+            userid: 'string',\n+            reset_token: 'string'\n+        },\n+        index: [\n+            { attribute: 'userid', type: 'hash' },\n+        ],\n+        revisionRetentionPolicy: {\n+            type: 'latest',\n+            count: 1,\n+            grace_ttl: 0\n+        }\n+    }\n+};\n+\n+\n+const tfaTable = {\n+    name: 'auth_tfa',\n+    uri: '/wikimedia.org/sys/table/auth_tfa',\n+    entryURI: new URI(['wikimedia.org', 'sys', 'table', 'auth_tfa', '']),\n+    schema: {\n+        table: 'auth_tfa',\n+        version: 1,\n+        attributes: {\n+            userid: 'string',\n+            key: 'string',\n+            tokens: 'set<string>'\n+        },\n+        index: [\n+            { attribute: 'userid', type: 'hash' },\n+        ],\n+        revisionRetentionPolicy: {\n+            type: 'latest',\n+            count: 1,\n+            grace_ttl: 0\n+        }\n+    }\n+};\n+\n+function getFromTable(hyper, req, table) {\n+    return hyper.get({\n+        uri: table.entryURI,\n+        body: {\n+            table: table.name,\n+            attributes: {\n+                userid: req.params.userid\n+            }\n+        }\n+    })\n+    .then(function(res) {\n+        if (res && res.body && res.body.items && res.body.items.length) {\n+            return res.body.items[0];\n+        }\n+    })\n+    .catchReturn({ status: 404 }, undefined);\n+}\n+\n+class Auth {\n+    constructor(options) {\n+        this.options = options;\n+    }\n+\n+    verifyPassword(hyper, req) {\n+        return getFromTable(hyper, req, passwordTable)\n+        .then((res) => {\n+            if (res && res.pass_hash && res.pass_hash === authLib.hashPass(req.body.password)) {\n+                return { status: 200 }\n+            }\n+            throw new HTTPError({ status: 401 });\n+        });\n+    }\n+\n+    resetPassword(hyper, req) {\n+        const token = authLib.genToken();\n+        return hyper.put({\n+            uri: tokenTable.entryURI,\n+            body: {\n+                table: tokenTable.name,\n+                attributes: {\n+                    userid: req.params.userid,\n+                    reset_token: token\n+                }\n+            }\n+        })\n+        .thenReturn({\n+            status: 201,\n+            body: {\n+                token: token\n+            }\n+        });\n+    }\n+\n+    createPassword(hyper, req) {\n+        function storePass() {\n+            return hyper.put({\n+                uri: passwordTable.entryURI,\n+                body: {\n+                    table: passwordTable.name,\n+                    attributes: {\n+                        userid: req.params.userid,\n+                        pass_hash: authLib.hashPass(req.body.new_password)\n+                    }\n+                }\n+            });\n+        }\n+\n+        function reportError() {\n+            throw new HTTPError({ status: 401 });\n+        }\n+\n+        return getFromTable(hyper, req, passwordTable)\n+        .then((res) => {\n+            if (res === undefined) {\n+                // Now user with this userid, allow to set the password\n+                return storePass();\n+            } else {\n+                if (req.body.old_password && authLib.hashPass(req.body.old_password) === res.pass_hash) {\n+                    // Allow to store the password because old_password matched\n+                    return storePass();\n+                } else if (req.body.token) {\n+                    return getFromTable(hyper, req, tokenTable)\n+                    .then((res) => {","path":"v1/auth.js","position":161,"original_position":161,"commit_id":"fd82d625539179bc2c38ea61ea6f21fcb69ed270","original_commit_id":"fd82d625539179bc2c38ea61ea6f21fcb69ed270","user":{"login":"Pchelolo","id":814754,"avatar_url":"https://avatars.githubusercontent.com/u/814754?v=3","gravatar_id":"","url":"https://api.github.com/users/Pchelolo","html_url":"https://github.com/Pchelolo","followers_url":"https://api.github.com/users/Pchelolo/followers","following_url":"https://api.github.com/users/Pchelolo/following{/other_user}","gists_url":"https://api.github.com/users/Pchelolo/gists{/gist_id}","starred_url":"https://api.github.com/users/Pchelolo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Pchelolo/subscriptions","organizations_url":"https://api.github.com/users/Pchelolo/orgs","repos_url":"https://api.github.com/users/Pchelolo/repos","events_url":"https://api.github.com/users/Pchelolo/events{/privacy}","received_events_url":"https://api.github.com/users/Pchelolo/received_events","type":"User","site_admin":false},"body":"If we've used a password reset token - should we delete it from storage (invalidate)","created_at":"2016-09-13T16:47:32Z","updated_at":"2016-09-13T16:47:32Z","html_url":"https://github.com/wikimedia/authoid/pull/1#discussion_r78598490","pull_request_url":"https://api.github.com/repos/wikimedia/authoid/pulls/1","_links":{"self":{"href":"https://api.github.com/repos/wikimedia/authoid/pulls/comments/78598490"},"html":{"href":"https://github.com/wikimedia/authoid/pull/1#discussion_r78598490"},"pull_request":{"href":"https://api.github.com/repos/wikimedia/authoid/pulls/1"}}},"pull_request":{"url":"https://api.github.com/repos/wikimedia/authoid/pulls/1","id":78901138,"html_url":"https://github.com/wikimedia/authoid/pull/1","diff_url":"https://github.com/wikimedia/authoid/pull/1.diff","patch_url":"https://github.com/wikimedia/authoid/pull/1.patch","issue_url":"https://api.github.com/repos/wikimedia/authoid/issues/1","number":1,"state":"open","locked":false,"title":"Prototype spec for the authentication service API","user":{"login":"Pchelolo","id":814754,"avatar_url":"https://avatars.githubusercontent.com/u/814754?v=3","gravatar_id":"","url":"https://api.github.com/users/Pchelolo","html_url":"https://github.com/Pchelolo","followers_url":"https://api.github.com/users/Pchelolo/followers","following_url":"https://api.github.com/users/Pchelolo/following{/other_user}","gists_url":"https://api.github.com/users/Pchelolo/gists{/gist_id}","starred_url":"https://api.github.com/users/Pchelolo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Pchelolo/subscriptions","organizations_url":"https://api.github.com/users/Pchelolo/orgs","repos_url":"https://api.github.com/users/Pchelolo/repos","events_url":"https://api.github.com/users/Pchelolo/events{/privacy}","received_events_url":"https://api.github.com/users/Pchelolo/received_events","type":"User","site_admin":false},"body":"Rough prototype for the API spec for the authentication service.\r\n\r\nHere's a live instance with this spec: https://auth-service.wmflabs.org/wikimedia.org/v1/?doc\r\nIt's not returning anything yet, just a mock. And it's running in a screen session on labs, so might go down.\r\n\r\ncc @wikimedia/services @dap ","created_at":"2016-07-26T18:27:46Z","updated_at":"2016-09-13T16:47:32Z","closed_at":null,"merged_at":null,"merge_commit_sha":"6b68e9ff55bf0bd23cde66079ea2eb839b5ee277","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/wikimedia/authoid/pulls/1/commits","review_comments_url":"https://api.github.com/repos/wikimedia/authoid/pulls/1/comments","review_comment_url":"https://api.github.com/repos/wikimedia/authoid/pulls/comments{/number}","comments_url":"https://api.github.com/repos/wikimedia/authoid/issues/1/comments","statuses_url":"https://api.github.com/repos/wikimedia/authoid/statuses/fd82d625539179bc2c38ea61ea6f21fcb69ed270","head":{"label":"Pchelolo:auth_spec","ref":"auth_spec","sha":"fd82d625539179bc2c38ea61ea6f21fcb69ed270","user":{"login":"Pchelolo","id":814754,"avatar_url":"https://avatars.githubusercontent.com/u/814754?v=3","gravatar_id":"","url":"https://api.github.com/users/Pchelolo","html_url":"https://github.com/Pchelolo","followers_url":"https://api.github.com/users/Pchelolo/followers","following_url":"https://api.github.com/users/Pchelolo/following{/other_user}","gists_url":"https://api.github.com/users/Pchelolo/gists{/gist_id}","starred_url":"https://api.github.com/users/Pchelolo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Pchelolo/subscriptions","organizations_url":"https://api.github.com/users/Pchelolo/orgs","repos_url":"https://api.github.com/users/Pchelolo/repos","events_url":"https://api.github.com/users/Pchelolo/events{/privacy}","received_events_url":"https://api.github.com/users/Pchelolo/received_events","type":"User","site_admin":false},"repo":{"id":64244746,"name":"authoid","full_name":"Pchelolo/authoid","owner":{"login":"Pchelolo","id":814754,"avatar_url":"https://avatars.githubusercontent.com/u/814754?v=3","gravatar_id":"","url":"https://api.github.com/users/Pchelolo","html_url":"https://github.com/Pchelolo","followers_url":"https://api.github.com/users/Pchelolo/followers","following_url":"https://api.github.com/users/Pchelolo/following{/other_user}","gists_url":"https://api.github.com/users/Pchelolo/gists{/gist_id}","starred_url":"https://api.github.com/users/Pchelolo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Pchelolo/subscriptions","organizations_url":"https://api.github.com/users/Pchelolo/orgs","repos_url":"https://api.github.com/users/Pchelolo/repos","events_url":"https://api.github.com/users/Pchelolo/events{/privacy}","received_events_url":"https://api.github.com/users/Pchelolo/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Pchelolo/authoid","description":"Auth & session backend service prototype","fork":true,"url":"https://api.github.com/repos/Pchelolo/authoid","forks_url":"https://api.github.com/repos/Pchelolo/authoid/forks","keys_url":"https://api.github.com/repos/Pchelolo/authoid/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Pchelolo/authoid/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Pchelolo/authoid/teams","hooks_url":"https://api.github.com/repos/Pchelolo/authoid/hooks","issue_events_url":"https://api.github.com/repos/Pchelolo/authoid/issues/events{/number}","events_url":"https://api.github.com/repos/Pchelolo/authoid/events","assignees_url":"https://api.github.com/repos/Pchelolo/authoid/assignees{/user}","branches_url":"https://api.github.com/repos/Pchelolo/authoid/branches{/branch}","tags_url":"https://api.github.com/repos/Pchelolo/authoid/tags","blobs_url":"https://api.github.com/repos/Pchelolo/authoid/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Pchelolo/authoid/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Pchelolo/authoid/git/refs{/sha}","trees_url":"https://api.github.com/repos/Pchelolo/authoid/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Pchelolo/authoid/statuses/{sha}","languages_url":"https://api.github.com/repos/Pchelolo/authoid/languages","stargazers_url":"https://api.github.com/repos/Pchelolo/authoid/stargazers","contributors_url":"https://api.github.com/repos/Pchelolo/authoid/contributors","subscribers_url":"https://api.github.com/repos/Pchelolo/authoid/subscribers","subscription_url":"https://api.github.com/repos/Pchelolo/authoid/subscription","commits_url":"https://api.github.com/repos/Pchelolo/authoid/commits{/sha}","git_commits_url":"https://api.github.com/repos/Pchelolo/authoid/git/commits{/sha}","comments_url":"https://api.github.com/repos/Pchelolo/authoid/comments{/number}","issue_comment_url":"https://api.github.com/repos/Pchelolo/authoid/issues/comments{/number}","contents_url":"https://api.github.com/repos/Pchelolo/authoid/contents/{+path}","compare_url":"https://api.github.com/repos/Pchelolo/authoid/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Pchelolo/authoid/merges","archive_url":"https://api.github.com/repos/Pchelolo/authoid/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Pchelolo/authoid/downloads","issues_url":"https://api.github.com/repos/Pchelolo/authoid/issues{/number}","pulls_url":"https://api.github.com/repos/Pchelolo/authoid/pulls{/number}","milestones_url":"https://api.github.com/repos/Pchelolo/authoid/milestones{/number}","notifications_url":"https://api.github.com/repos/Pchelolo/authoid/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Pchelolo/authoid/labels{/name}","releases_url":"https://api.github.com/repos/Pchelolo/authoid/releases{/id}","deployments_url":"https://api.github.com/repos/Pchelolo/authoid/deployments","created_at":"2016-07-26T18:26:01Z","updated_at":"2016-07-26T18:26:02Z","pushed_at":"2016-09-06T22:58:48Z","git_url":"git://github.com/Pchelolo/authoid.git","ssh_url":"git@github.com:Pchelolo/authoid.git","clone_url":"https://github.com/Pchelolo/authoid.git","svn_url":"https://github.com/Pchelolo/authoid","homepage":null,"size":14,"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":"wikimedia:master","ref":"master","sha":"6ab610ff197ebf05fa38881d95ad705343c9074a","user":{"login":"wikimedia","id":56668,"avatar_url":"https://avatars.githubusercontent.com/u/56668?v=3","gravatar_id":"","url":"https://api.github.com/users/wikimedia","html_url":"https://github.com/wikimedia","followers_url":"https://api.github.com/users/wikimedia/followers","following_url":"https://api.github.com/users/wikimedia/following{/other_user}","gists_url":"https://api.github.com/users/wikimedia/gists{/gist_id}","starred_url":"https://api.github.com/users/wikimedia/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wikimedia/subscriptions","organizations_url":"https://api.github.com/users/wikimedia/orgs","repos_url":"https://api.github.com/users/wikimedia/repos","events_url":"https://api.github.com/users/wikimedia/events{/privacy}","received_events_url":"https://api.github.com/users/wikimedia/received_events","type":"Organization","site_admin":false},"repo":{"id":60804043,"name":"authoid","full_name":"wikimedia/authoid","owner":{"login":"wikimedia","id":56668,"avatar_url":"https://avatars.githubusercontent.com/u/56668?v=3","gravatar_id":"","url":"https://api.github.com/users/wikimedia","html_url":"https://github.com/wikimedia","followers_url":"https://api.github.com/users/wikimedia/followers","following_url":"https://api.github.com/users/wikimedia/following{/other_user}","gists_url":"https://api.github.com/users/wikimedia/gists{/gist_id}","starred_url":"https://api.github.com/users/wikimedia/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wikimedia/subscriptions","organizations_url":"https://api.github.com/users/wikimedia/orgs","repos_url":"https://api.github.com/users/wikimedia/repos","events_url":"https://api.github.com/users/wikimedia/events{/privacy}","received_events_url":"https://api.github.com/users/wikimedia/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/wikimedia/authoid","description":"Auth & session backend service prototype","fork":false,"url":"https://api.github.com/repos/wikimedia/authoid","forks_url":"https://api.github.com/repos/wikimedia/authoid/forks","keys_url":"https://api.github.com/repos/wikimedia/authoid/keys{/key_id}","collaborators_url":"https://api.github.com/repos/wikimedia/authoid/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/wikimedia/authoid/teams","hooks_url":"https://api.github.com/repos/wikimedia/authoid/hooks","issue_events_url":"https://api.github.com/repos/wikimedia/authoid/issues/events{/number}","events_url":"https://api.github.com/repos/wikimedia/authoid/events","assignees_url":"https://api.github.com/repos/wikimedia/authoid/assignees{/user}","branches_url":"https://api.github.com/repos/wikimedia/authoid/branches{/branch}","tags_url":"https://api.github.com/repos/wikimedia/authoid/tags","blobs_url":"https://api.github.com/repos/wikimedia/authoid/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/wikimedia/authoid/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/wikimedia/authoid/git/refs{/sha}","trees_url":"https://api.github.com/repos/wikimedia/authoid/git/trees{/sha}","statuses_url":"https://api.github.com/repos/wikimedia/authoid/statuses/{sha}","languages_url":"https://api.github.com/repos/wikimedia/authoid/languages","stargazers_url":"https://api.github.com/repos/wikimedia/authoid/stargazers","contributors_url":"https://api.github.com/repos/wikimedia/authoid/contributors","subscribers_url":"https://api.github.com/repos/wikimedia/authoid/subscribers","subscription_url":"https://api.github.com/repos/wikimedia/authoid/subscription","commits_url":"https://api.github.com/repos/wikimedia/authoid/commits{/sha}","git_commits_url":"https://api.github.com/repos/wikimedia/authoid/git/commits{/sha}","comments_url":"https://api.github.com/repos/wikimedia/authoid/comments{/number}","issue_comment_url":"https://api.github.com/repos/wikimedia/authoid/issues/comments{/number}","contents_url":"https://api.github.com/repos/wikimedia/authoid/contents/{+path}","compare_url":"https://api.github.com/repos/wikimedia/authoid/compare/{base}...{head}","merges_url":"https://api.github.com/repos/wikimedia/authoid/merges","archive_url":"https://api.github.com/repos/wikimedia/authoid/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/wikimedia/authoid/downloads","issues_url":"https://api.github.com/repos/wikimedia/authoid/issues{/number}","pulls_url":"https://api.github.com/repos/wikimedia/authoid/pulls{/number}","milestones_url":"https://api.github.com/repos/wikimedia/authoid/milestones{/number}","notifications_url":"https://api.github.com/repos/wikimedia/authoid/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/wikimedia/authoid/labels{/name}","releases_url":"https://api.github.com/repos/wikimedia/authoid/releases{/id}","deployments_url":"https://api.github.com/repos/wikimedia/authoid/deployments","created_at":"2016-06-09T20:12:54Z","updated_at":"2016-07-26T18:47:22Z","pushed_at":"2016-09-06T22:58:48Z","git_url":"git://github.com/wikimedia/authoid.git","ssh_url":"git@github.com:wikimedia/authoid.git","clone_url":"https://github.com/wikimedia/authoid.git","svn_url":"https://github.com/wikimedia/authoid","homepage":null,"size":11,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":1,"forks":1,"open_issues":1,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/wikimedia/authoid/pulls/1"},"html":{"href":"https://github.com/wikimedia/authoid/pull/1"},"issue":{"href":"https://api.github.com/repos/wikimedia/authoid/issues/1"},"comments":{"href":"https://api.github.com/repos/wikimedia/authoid/issues/1/comments"},"review_comments":{"href":"https://api.github.com/repos/wikimedia/authoid/pulls/1/comments"},"review_comment":{"href":"https://api.github.com/repos/wikimedia/authoid/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/wikimedia/authoid/pulls/1/commits"},"statuses":{"href":"https://api.github.com/repos/wikimedia/authoid/statuses/fd82d625539179bc2c38ea61ea6f21fcb69ed270"}}}}
{"actor":{"display_login":"Pchelolo"}}