{"action":"closed","number":633,"pull_request":{"url":"https://api.github.com/repos/esl/MongooseIM/pulls/633","id":55452540,"html_url":"https://github.com/esl/MongooseIM/pull/633","diff_url":"https://github.com/esl/MongooseIM/pull/633.diff","patch_url":"https://github.com/esl/MongooseIM/pull/633.patch","issue_url":"https://api.github.com/repos/esl/MongooseIM/issues/633","number":633,"state":"closed","locked":false,"title":"OAuth-like token support","user":{"login":"erszcz","id":112145,"avatar_url":"https://avatars.githubusercontent.com/u/112145?v=3","gravatar_id":"","url":"https://api.github.com/users/erszcz","html_url":"https://github.com/erszcz","followers_url":"https://api.github.com/users/erszcz/followers","following_url":"https://api.github.com/users/erszcz/following{/other_user}","gists_url":"https://api.github.com/users/erszcz/gists{/gist_id}","starred_url":"https://api.github.com/users/erszcz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/erszcz/subscriptions","organizations_url":"https://api.github.com/users/erszcz/orgs","repos_url":"https://api.github.com/users/erszcz/repos","events_url":"https://api.github.com/users/erszcz/events{/privacy}","received_events_url":"https://api.github.com/users/erszcz/received_events","type":"User","site_admin":false},"body":"This PR implements a token authentication feature similar to [OAuth][1] which allows for secure access to the system not requiring a user to provide password on each login or storage of username / password or any other vulnerable data on a user's device.\r\n\r\nThe main simplification in comparison with OAuth is that MongooseIM is both the authorization (it generates tokens) and resource (it allows for access to the XMPP network) server.\r\n\r\nChanges mainly affect `cyrsasl` and introduce new modules: `mod_auth_token` responsible for token generation and verification, and `mod_keystore`, which provides access to on-disk as a well as RAM-only keys. There's no key format expected for persistent keys - arbitrary binary data will be accepted as of now. RAM keys are generated on cluster startup and are lost on shutdown of the last cluster member. All tokens become invalid after their expiry date is reached. `refresh` tokens can also be revoked through the command line interface. `access` tokens can't be revoked, as the server doesn't track the `access` tokens it generates.\r\n\r\nA new CYRSASL mechanism, X-OAUTH, is introduced. When a user connecting to the system chooses this mechanism, then the only challenge required by the system is a Base64 encoded token of type `access`, `refresh` or `provision`. Token types are further described in `mod_auth_token` documentation. In order to obtain an `access` or `refresh` token the user has to login with another CYRSASL mechanism at least once - requesting a token from the server is only possible once an XMPP session is established; `provision` tokens ought to be obtained from an external authorization server. Once the user is in possession of a token, (s)he can use X-OAUTH. Successful authentication results in a new set of tokens being returned with the `<success/>` element. During an XMPP session, a token is obtained with a new kind of IQ (see `mod_auth_token` doc).\r\n\r\n**Caveat:** when a user is logged into the system and his/her token gets compromised, the operator can revoke the `refresh` token. However, **the `access` token can't be revoked and will be valid until expiration**, therefore will allow the user to login again to the system even if he/she is kicked by the operator. \r\n\r\n[1]: http://tools.ietf.org/html/rfc6749\r\n[2]: https://developers.google.com/talk/jep_extensions/oauth","created_at":"2016-01-08T11:39:52Z","updated_at":"2016-01-29T09:14:00Z","closed_at":"2016-01-29T09:14:00Z","merged_at":"2016-01-29T09:14:00Z","merge_commit_sha":"0626d05a92fa475228e376039b7a1eaee55cb1d4","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/esl/MongooseIM/pulls/633/commits","review_comments_url":"https://api.github.com/repos/esl/MongooseIM/pulls/633/comments","review_comment_url":"https://api.github.com/repos/esl/MongooseIM/pulls/comments{/number}","comments_url":"https://api.github.com/repos/esl/MongooseIM/issues/633/comments","statuses_url":"https://api.github.com/repos/esl/MongooseIM/statuses/decc474c2ecb49eba3dc4effb5495eebcde6f1fb","head":{"label":"esl:rel-1.7-token-support","ref":"rel-1.7-token-support","sha":"decc474c2ecb49eba3dc4effb5495eebcde6f1fb","user":{"login":"esl","id":283412,"avatar_url":"https://avatars.githubusercontent.com/u/283412?v=3","gravatar_id":"","url":"https://api.github.com/users/esl","html_url":"https://github.com/esl","followers_url":"https://api.github.com/users/esl/followers","following_url":"https://api.github.com/users/esl/following{/other_user}","gists_url":"https://api.github.com/users/esl/gists{/gist_id}","starred_url":"https://api.github.com/users/esl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/esl/subscriptions","organizations_url":"https://api.github.com/users/esl/orgs","repos_url":"https://api.github.com/users/esl/repos","events_url":"https://api.github.com/users/esl/events{/privacy}","received_events_url":"https://api.github.com/users/esl/received_events","type":"Organization","site_admin":false},"repo":{"id":2354240,"name":"MongooseIM","full_name":"esl/MongooseIM","owner":{"login":"esl","id":283412,"avatar_url":"https://avatars.githubusercontent.com/u/283412?v=3","gravatar_id":"","url":"https://api.github.com/users/esl","html_url":"https://github.com/esl","followers_url":"https://api.github.com/users/esl/followers","following_url":"https://api.github.com/users/esl/following{/other_user}","gists_url":"https://api.github.com/users/esl/gists{/gist_id}","starred_url":"https://api.github.com/users/esl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/esl/subscriptions","organizations_url":"https://api.github.com/users/esl/orgs","repos_url":"https://api.github.com/users/esl/repos","events_url":"https://api.github.com/users/esl/events{/privacy}","received_events_url":"https://api.github.com/users/esl/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/esl/MongooseIM","description":"Jabber / XMPP server with focus on performance and scalability, by Erlang Solutions","fork":false,"url":"https://api.github.com/repos/esl/MongooseIM","forks_url":"https://api.github.com/repos/esl/MongooseIM/forks","keys_url":"https://api.github.com/repos/esl/MongooseIM/keys{/key_id}","collaborators_url":"https://api.github.com/repos/esl/MongooseIM/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/esl/MongooseIM/teams","hooks_url":"https://api.github.com/repos/esl/MongooseIM/hooks","issue_events_url":"https://api.github.com/repos/esl/MongooseIM/issues/events{/number}","events_url":"https://api.github.com/repos/esl/MongooseIM/events","assignees_url":"https://api.github.com/repos/esl/MongooseIM/assignees{/user}","branches_url":"https://api.github.com/repos/esl/MongooseIM/branches{/branch}","tags_url":"https://api.github.com/repos/esl/MongooseIM/tags","blobs_url":"https://api.github.com/repos/esl/MongooseIM/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/esl/MongooseIM/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/esl/MongooseIM/git/refs{/sha}","trees_url":"https://api.github.com/repos/esl/MongooseIM/git/trees{/sha}","statuses_url":"https://api.github.com/repos/esl/MongooseIM/statuses/{sha}","languages_url":"https://api.github.com/repos/esl/MongooseIM/languages","stargazers_url":"https://api.github.com/repos/esl/MongooseIM/stargazers","contributors_url":"https://api.github.com/repos/esl/MongooseIM/contributors","subscribers_url":"https://api.github.com/repos/esl/MongooseIM/subscribers","subscription_url":"https://api.github.com/repos/esl/MongooseIM/subscription","commits_url":"https://api.github.com/repos/esl/MongooseIM/commits{/sha}","git_commits_url":"https://api.github.com/repos/esl/MongooseIM/git/commits{/sha}","comments_url":"https://api.github.com/repos/esl/MongooseIM/comments{/number}","issue_comment_url":"https://api.github.com/repos/esl/MongooseIM/issues/comments{/number}","contents_url":"https://api.github.com/repos/esl/MongooseIM/contents/{+path}","compare_url":"https://api.github.com/repos/esl/MongooseIM/compare/{base}...{head}","merges_url":"https://api.github.com/repos/esl/MongooseIM/merges","archive_url":"https://api.github.com/repos/esl/MongooseIM/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/esl/MongooseIM/downloads","issues_url":"https://api.github.com/repos/esl/MongooseIM/issues{/number}","pulls_url":"https://api.github.com/repos/esl/MongooseIM/pulls{/number}","milestones_url":"https://api.github.com/repos/esl/MongooseIM/milestones{/number}","notifications_url":"https://api.github.com/repos/esl/MongooseIM/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/esl/MongooseIM/labels{/name}","releases_url":"https://api.github.com/repos/esl/MongooseIM/releases{/id}","deployments_url":"https://api.github.com/repos/esl/MongooseIM/deployments","created_at":"2011-09-09T08:19:18Z","updated_at":"2016-01-28T16:56:12Z","pushed_at":"2016-01-29T09:14:00Z","git_url":"git://github.com/esl/MongooseIM.git","ssh_url":"git@github.com:esl/MongooseIM.git","clone_url":"https://github.com/esl/MongooseIM.git","svn_url":"https://github.com/esl/MongooseIM","homepage":"https://www.erlang-solutions.com/products/mongooseim.html","size":16114,"stargazers_count":466,"watchers_count":466,"language":"Erlang","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":188,"mirror_url":null,"open_issues_count":58,"forks":188,"open_issues":58,"watchers":466,"default_branch":"master"}},"base":{"label":"esl:rel-1.7","ref":"rel-1.7","sha":"7af6230243645ee055ed485350f3f70b7632f26c","user":{"login":"esl","id":283412,"avatar_url":"https://avatars.githubusercontent.com/u/283412?v=3","gravatar_id":"","url":"https://api.github.com/users/esl","html_url":"https://github.com/esl","followers_url":"https://api.github.com/users/esl/followers","following_url":"https://api.github.com/users/esl/following{/other_user}","gists_url":"https://api.github.com/users/esl/gists{/gist_id}","starred_url":"https://api.github.com/users/esl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/esl/subscriptions","organizations_url":"https://api.github.com/users/esl/orgs","repos_url":"https://api.github.com/users/esl/repos","events_url":"https://api.github.com/users/esl/events{/privacy}","received_events_url":"https://api.github.com/users/esl/received_events","type":"Organization","site_admin":false},"repo":{"id":2354240,"name":"MongooseIM","full_name":"esl/MongooseIM","owner":{"login":"esl","id":283412,"avatar_url":"https://avatars.githubusercontent.com/u/283412?v=3","gravatar_id":"","url":"https://api.github.com/users/esl","html_url":"https://github.com/esl","followers_url":"https://api.github.com/users/esl/followers","following_url":"https://api.github.com/users/esl/following{/other_user}","gists_url":"https://api.github.com/users/esl/gists{/gist_id}","starred_url":"https://api.github.com/users/esl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/esl/subscriptions","organizations_url":"https://api.github.com/users/esl/orgs","repos_url":"https://api.github.com/users/esl/repos","events_url":"https://api.github.com/users/esl/events{/privacy}","received_events_url":"https://api.github.com/users/esl/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/esl/MongooseIM","description":"Jabber / XMPP server with focus on performance and scalability, by Erlang Solutions","fork":false,"url":"https://api.github.com/repos/esl/MongooseIM","forks_url":"https://api.github.com/repos/esl/MongooseIM/forks","keys_url":"https://api.github.com/repos/esl/MongooseIM/keys{/key_id}","collaborators_url":"https://api.github.com/repos/esl/MongooseIM/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/esl/MongooseIM/teams","hooks_url":"https://api.github.com/repos/esl/MongooseIM/hooks","issue_events_url":"https://api.github.com/repos/esl/MongooseIM/issues/events{/number}","events_url":"https://api.github.com/repos/esl/MongooseIM/events","assignees_url":"https://api.github.com/repos/esl/MongooseIM/assignees{/user}","branches_url":"https://api.github.com/repos/esl/MongooseIM/branches{/branch}","tags_url":"https://api.github.com/repos/esl/MongooseIM/tags","blobs_url":"https://api.github.com/repos/esl/MongooseIM/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/esl/MongooseIM/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/esl/MongooseIM/git/refs{/sha}","trees_url":"https://api.github.com/repos/esl/MongooseIM/git/trees{/sha}","statuses_url":"https://api.github.com/repos/esl/MongooseIM/statuses/{sha}","languages_url":"https://api.github.com/repos/esl/MongooseIM/languages","stargazers_url":"https://api.github.com/repos/esl/MongooseIM/stargazers","contributors_url":"https://api.github.com/repos/esl/MongooseIM/contributors","subscribers_url":"https://api.github.com/repos/esl/MongooseIM/subscribers","subscription_url":"https://api.github.com/repos/esl/MongooseIM/subscription","commits_url":"https://api.github.com/repos/esl/MongooseIM/commits{/sha}","git_commits_url":"https://api.github.com/repos/esl/MongooseIM/git/commits{/sha}","comments_url":"https://api.github.com/repos/esl/MongooseIM/comments{/number}","issue_comment_url":"https://api.github.com/repos/esl/MongooseIM/issues/comments{/number}","contents_url":"https://api.github.com/repos/esl/MongooseIM/contents/{+path}","compare_url":"https://api.github.com/repos/esl/MongooseIM/compare/{base}...{head}","merges_url":"https://api.github.com/repos/esl/MongooseIM/merges","archive_url":"https://api.github.com/repos/esl/MongooseIM/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/esl/MongooseIM/downloads","issues_url":"https://api.github.com/repos/esl/MongooseIM/issues{/number}","pulls_url":"https://api.github.com/repos/esl/MongooseIM/pulls{/number}","milestones_url":"https://api.github.com/repos/esl/MongooseIM/milestones{/number}","notifications_url":"https://api.github.com/repos/esl/MongooseIM/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/esl/MongooseIM/labels{/name}","releases_url":"https://api.github.com/repos/esl/MongooseIM/releases{/id}","deployments_url":"https://api.github.com/repos/esl/MongooseIM/deployments","created_at":"2011-09-09T08:19:18Z","updated_at":"2016-01-28T16:56:12Z","pushed_at":"2016-01-29T09:14:00Z","git_url":"git://github.com/esl/MongooseIM.git","ssh_url":"git@github.com:esl/MongooseIM.git","clone_url":"https://github.com/esl/MongooseIM.git","svn_url":"https://github.com/esl/MongooseIM","homepage":"https://www.erlang-solutions.com/products/mongooseim.html","size":16114,"stargazers_count":466,"watchers_count":466,"language":"Erlang","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":188,"mirror_url":null,"open_issues_count":58,"forks":188,"open_issues":58,"watchers":466,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/esl/MongooseIM/pulls/633"},"html":{"href":"https://github.com/esl/MongooseIM/pull/633"},"issue":{"href":"https://api.github.com/repos/esl/MongooseIM/issues/633"},"comments":{"href":"https://api.github.com/repos/esl/MongooseIM/issues/633/comments"},"review_comments":{"href":"https://api.github.com/repos/esl/MongooseIM/pulls/633/comments"},"review_comment":{"href":"https://api.github.com/repos/esl/MongooseIM/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/esl/MongooseIM/pulls/633/commits"},"statuses":{"href":"https://api.github.com/repos/esl/MongooseIM/statuses/decc474c2ecb49eba3dc4effb5495eebcde6f1fb"}},"merged":true,"mergeable":null,"mergeable_state":"unknown","merged_by":{"login":"erszcz","id":112145,"avatar_url":"https://avatars.githubusercontent.com/u/112145?v=3","gravatar_id":"","url":"https://api.github.com/users/erszcz","html_url":"https://github.com/erszcz","followers_url":"https://api.github.com/users/erszcz/followers","following_url":"https://api.github.com/users/erszcz/following{/other_user}","gists_url":"https://api.github.com/users/erszcz/gists{/gist_id}","starred_url":"https://api.github.com/users/erszcz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/erszcz/subscriptions","organizations_url":"https://api.github.com/users/erszcz/orgs","repos_url":"https://api.github.com/users/erszcz/repos","events_url":"https://api.github.com/users/erszcz/events{/privacy}","received_events_url":"https://api.github.com/users/erszcz/received_events","type":"User","site_admin":false},"comments":4,"review_comments":2,"commits":165,"additions":3186,"deletions":213,"changed_files":37}}