{"action":"created","comment":{"url":"https://api.github.com/repos/sparkphp/auth/pulls/comments/41054737","id":41054737,"diff_hunk":"@@ -0,0 +1,45 @@\n+<?php\n+namespace Spark\\Auth;\n+\n+use Spark\\Auth\\Credentials;\n+\n+interface AdapterInterface\n+{\n+    /**\n+     * Validates a specified authentication token.\n+     *\n+     * - If the specified token is invalid, an InvalidException instance is\n+     *   thrown.\n+     * - If a valid token is present, a corresponding Token instance is\n+     *   returned.\n+     * - If for some reason the token cannot be validated, an AuthException\n+     *   instance is thrown.\n+     *\n+     * @param string $token\n+     * @return \\Spark\\Auth\\Token\n+     * @throws \\Spark\\Auth\\Exception\\InvalidException if an invalid auth token\n+     *         is specified\n+     * @throws \\Spark\\Auth\\Exception\\AuthException if another error occurs\n+     *         during authentication\n+     */\n+    public function validateToken($token);\n+\n+    /**\n+     * Validates a set of user credentials.\n+     *\n+     * - If the user credentials are valid, a new authentication token is\n+     *   created and a corresponding Token instance is returned.\n+     * - If the user credentials are invalid, an InvalidException instance is\n+     *   thrown.\n+     * - If for some reason the user credentials cannot be validated, an\n+     *   AuthException instance is thrown.\n+     *\n+     * @param \\Spark\\Auth\\Credentials $credentials","path":"src/AdapterInterface.php","position":37,"original_position":37,"commit_id":"54e1f6333954e9f6d243517ee2b4487eac06daad","original_commit_id":"54e1f6333954e9f6d243517ee2b4487eac06daad","user":{"login":"shadowhand","id":38203,"avatar_url":"https://avatars.githubusercontent.com/u/38203?v=3","gravatar_id":"","url":"https://api.github.com/users/shadowhand","html_url":"https://github.com/shadowhand","followers_url":"https://api.github.com/users/shadowhand/followers","following_url":"https://api.github.com/users/shadowhand/following{/other_user}","gists_url":"https://api.github.com/users/shadowhand/gists{/gist_id}","starred_url":"https://api.github.com/users/shadowhand/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/shadowhand/subscriptions","organizations_url":"https://api.github.com/users/shadowhand/orgs","repos_url":"https://api.github.com/users/shadowhand/repos","events_url":"https://api.github.com/users/shadowhand/events{/privacy}","received_events_url":"https://api.github.com/users/shadowhand/received_events","type":"User","site_admin":false},"body":"Why a leading `\\`?","created_at":"2015-10-02T18:50:32Z","updated_at":"2015-10-02T18:50:32Z","html_url":"https://github.com/sparkphp/auth/pull/2#discussion_r41054737","pull_request_url":"https://api.github.com/repos/sparkphp/auth/pulls/2","_links":{"self":{"href":"https://api.github.com/repos/sparkphp/auth/pulls/comments/41054737"},"html":{"href":"https://github.com/sparkphp/auth/pull/2#discussion_r41054737"},"pull_request":{"href":"https://api.github.com/repos/sparkphp/auth/pulls/2"}}},"pull_request":{"url":"https://api.github.com/repos/sparkphp/auth/pulls/2","id":46647207,"html_url":"https://github.com/sparkphp/auth/pull/2","diff_url":"https://github.com/sparkphp/auth/pull/2.diff","patch_url":"https://github.com/sparkphp/auth/pull/2.patch","issue_url":"https://api.github.com/repos/sparkphp/auth/issues/2","number":2,"state":"open","locked":false,"title":"Completely rearchitect how this library works","user":{"login":"elazar","id":15487,"avatar_url":"https://avatars.githubusercontent.com/u/15487?v=3","gravatar_id":"","url":"https://api.github.com/users/elazar","html_url":"https://github.com/elazar","followers_url":"https://api.github.com/users/elazar/followers","following_url":"https://api.github.com/users/elazar/following{/other_user}","gists_url":"https://api.github.com/users/elazar/gists{/gist_id}","starred_url":"https://api.github.com/users/elazar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elazar/subscriptions","organizations_url":"https://api.github.com/users/elazar/orgs","repos_url":"https://api.github.com/users/elazar/repos","events_url":"https://api.github.com/users/elazar/events{/privacy}","received_events_url":"https://api.github.com/users/elazar/received_events","type":"User","site_admin":false},"body":"And fix a few small things discovered in the process.\r\n\r\nFixes #1.\r\n\r\n**DO NOT MERGE THIS YET**. It will break [api-auth-jwt](https://github.com/wheniwork/api-auth-jwt) and by proxy [reporting-api](https://github.com/wheniwork/reporting-api) if merged right now. The current purpose of the PR is to make sure this implementation is sufficient to the satisfaction of the team. If so, other PRs will be opened in these repos to make related changesets to accommodate this one.\r\n\r\n**Changes**\r\n* Add [examples](https://github.com/sparkphp/auth/tree/feature/refactor#authentication-handler) to README -- review these for an overview of how these changes work\r\n* Remove [`AbstractAuthenticator`](https://github.com/sparkphp/auth/blob/master/src/AbstractAuthenticator.php), because it involves too many concerns -- see #1 for related discussion\r\n* Remove [`AbstractPermission`](https://github.com/sparkphp/auth/blob/master/src/AbstractPermissions.php) because it appears to be unused and relates to authorization rather than authentication\r\n* Add the [`Token`](https://github.com/sparkphp/auth/blob/feature/refactor/src/Token.php) and [`Credentials`](https://github.com/sparkphp/auth/blob/feature/refactor/src/Credentials.php) value object classes to encapsulate authentication token metadata and user credentials respectively\r\n* Add [`ExtractorInterface`](https://github.com/sparkphp/auth/blob/feature/refactor/src/Token/ExtractorInterface.php), [`HeaderExtractor`](https://github.com/sparkphp/auth/blob/feature/refactor/src/Token/HeaderExtractor.php), and [`QueryExtractor`](https://github.com/sparkphp/auth/blob/feature/refactor/src/Token/QueryExtractor.php) under the [`Token` subnamespace](https://github.com/sparkphp/auth/tree/feature/refactor/src/Token) for extracting authentication token strings from [`ServerRequestInterface`](https://github.com/php-fig/http-message/blob/master/src/ServerRequestInterface.php) instances\r\n* Add [`ExtractorInterface`](https://github.com/sparkphp/auth/blob/feature/refactor/src/Credentials/ExtractorInterface.php) and [`JsonExtractor`](https://github.com/sparkphp/auth/blob/feature/refactor/src/Credentials/JsonExtractor.php) under the [`Credentials` subnamespace](https://github.com/sparkphp/auth/tree/feature/refactor/src/Credentials) for extracting user credentials from [`ServerRequestInterface`](https://github.com/php-fig/http-message/blob/master/src/ServerRequestInterface.php) instances\r\n* Add [`AdapterInterface`](https://github.com/sparkphp/auth/blob/feature/refactor/src/AdapterInterface.php) to represent authentication adapters for validating authentication tokens and user credentials\r\n* Add [`UnauthorizedException`](https://github.com/sparkphp/auth/blob/feature/refactor/src/Exception/UnauthorizedException.php) for when authentication fails due to the request lacking an authentication token and user credentials\r\n* Modify [`AuthHandler`](https://github.com/sparkphp/auth/blob/feature/refactor/src/AuthHandler.php) to use authentication adapter, token extractor, user credentials extractor, and [`UnauthorizedException`](https://github.com/sparkphp/auth/blob/feature/refactor/src/Exception/UnauthorizedException.php) instances where appropriate\r\n* Remove [`FakeAuthenticator`](https://github.com/sparkphp/auth/blob/master/tests/Fake/FakeAuthenticator.php) from test suite, because mocking of [`AdapterInterface`](https://github.com/sparkphp/auth/blob/feature/refactor/src/AdapterInterface.php) in the [`AuthHandlerTest`](https://github.com/sparkphp/auth/blob/feature/refactor/tests/AuthHandlerTest.php) suite should cover the same use cases\r\n* Modify the test suite to use Phake for mocking\r\n\r\n**Fixes**\r\n* Update broken badges in README\r\n* Tweak Composer dependency versions to use the carot operator\r\n* Make [`AuthHandler`](https://github.com/sparkphp/auth/blob/feature/refactor/src/AuthHandler.php) explicitly implement [`MiddlewareInterface`](https://github.com/sparkphp/adr/blob/master/src/MiddlewareInterface.php)\r\n* Modify `getStatusCode()` return values for [`AuthException`](https://github.com/sparkphp/auth/blob/feature/refactor/src/Exception/AuthException.php) and [`InvalidException`](https://github.com/sparkphp/auth/blob/feature/refactor/src/Exception/InvalidException.php) to be appropriate for their use cases\r\n\r\n/cc @dolfelt @shadowhand @ameech ","created_at":"2015-10-02T15:20:13Z","updated_at":"2015-10-02T18:50:32Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c6753b4ad8b13e481e03ff4fb11892347816d103","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/sparkphp/auth/pulls/2/commits","review_comments_url":"https://api.github.com/repos/sparkphp/auth/pulls/2/comments","review_comment_url":"https://api.github.com/repos/sparkphp/auth/pulls/comments{/number}","comments_url":"https://api.github.com/repos/sparkphp/auth/issues/2/comments","statuses_url":"https://api.github.com/repos/sparkphp/auth/statuses/54e1f6333954e9f6d243517ee2b4487eac06daad","head":{"label":"sparkphp:feature/refactor","ref":"feature/refactor","sha":"54e1f6333954e9f6d243517ee2b4487eac06daad","user":{"login":"sparkphp","id":12573848,"avatar_url":"https://avatars.githubusercontent.com/u/12573848?v=3","gravatar_id":"","url":"https://api.github.com/users/sparkphp","html_url":"https://github.com/sparkphp","followers_url":"https://api.github.com/users/sparkphp/followers","following_url":"https://api.github.com/users/sparkphp/following{/other_user}","gists_url":"https://api.github.com/users/sparkphp/gists{/gist_id}","starred_url":"https://api.github.com/users/sparkphp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sparkphp/subscriptions","organizations_url":"https://api.github.com/users/sparkphp/orgs","repos_url":"https://api.github.com/users/sparkphp/repos","events_url":"https://api.github.com/users/sparkphp/events{/privacy}","received_events_url":"https://api.github.com/users/sparkphp/received_events","type":"Organization","site_admin":false},"repo":{"id":39100682,"name":"auth","full_name":"sparkphp/auth","owner":{"login":"sparkphp","id":12573848,"avatar_url":"https://avatars.githubusercontent.com/u/12573848?v=3","gravatar_id":"","url":"https://api.github.com/users/sparkphp","html_url":"https://github.com/sparkphp","followers_url":"https://api.github.com/users/sparkphp/followers","following_url":"https://api.github.com/users/sparkphp/following{/other_user}","gists_url":"https://api.github.com/users/sparkphp/gists{/gist_id}","starred_url":"https://api.github.com/users/sparkphp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sparkphp/subscriptions","organizations_url":"https://api.github.com/users/sparkphp/orgs","repos_url":"https://api.github.com/users/sparkphp/repos","events_url":"https://api.github.com/users/sparkphp/events{/privacy}","received_events_url":"https://api.github.com/users/sparkphp/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/sparkphp/auth","description":"Simple middleware for custom authentication.","fork":false,"url":"https://api.github.com/repos/sparkphp/auth","forks_url":"https://api.github.com/repos/sparkphp/auth/forks","keys_url":"https://api.github.com/repos/sparkphp/auth/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sparkphp/auth/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sparkphp/auth/teams","hooks_url":"https://api.github.com/repos/sparkphp/auth/hooks","issue_events_url":"https://api.github.com/repos/sparkphp/auth/issues/events{/number}","events_url":"https://api.github.com/repos/sparkphp/auth/events","assignees_url":"https://api.github.com/repos/sparkphp/auth/assignees{/user}","branches_url":"https://api.github.com/repos/sparkphp/auth/branches{/branch}","tags_url":"https://api.github.com/repos/sparkphp/auth/tags","blobs_url":"https://api.github.com/repos/sparkphp/auth/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sparkphp/auth/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sparkphp/auth/git/refs{/sha}","trees_url":"https://api.github.com/repos/sparkphp/auth/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sparkphp/auth/statuses/{sha}","languages_url":"https://api.github.com/repos/sparkphp/auth/languages","stargazers_url":"https://api.github.com/repos/sparkphp/auth/stargazers","contributors_url":"https://api.github.com/repos/sparkphp/auth/contributors","subscribers_url":"https://api.github.com/repos/sparkphp/auth/subscribers","subscription_url":"https://api.github.com/repos/sparkphp/auth/subscription","commits_url":"https://api.github.com/repos/sparkphp/auth/commits{/sha}","git_commits_url":"https://api.github.com/repos/sparkphp/auth/git/commits{/sha}","comments_url":"https://api.github.com/repos/sparkphp/auth/comments{/number}","issue_comment_url":"https://api.github.com/repos/sparkphp/auth/issues/comments{/number}","contents_url":"https://api.github.com/repos/sparkphp/auth/contents/{+path}","compare_url":"https://api.github.com/repos/sparkphp/auth/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sparkphp/auth/merges","archive_url":"https://api.github.com/repos/sparkphp/auth/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sparkphp/auth/downloads","issues_url":"https://api.github.com/repos/sparkphp/auth/issues{/number}","pulls_url":"https://api.github.com/repos/sparkphp/auth/pulls{/number}","milestones_url":"https://api.github.com/repos/sparkphp/auth/milestones{/number}","notifications_url":"https://api.github.com/repos/sparkphp/auth/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sparkphp/auth/labels{/name}","releases_url":"https://api.github.com/repos/sparkphp/auth/releases{/id}","created_at":"2015-07-14T21:15:53Z","updated_at":"2015-08-16T20:51:56Z","pushed_at":"2015-10-02T16:33:04Z","git_url":"git://github.com/sparkphp/auth.git","ssh_url":"git@github.com:sparkphp/auth.git","clone_url":"https://github.com/sparkphp/auth.git","svn_url":"https://github.com/sparkphp/auth","homepage":null,"size":156,"stargazers_count":0,"watchers_count":0,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":2,"forks":0,"open_issues":2,"watchers":0,"default_branch":"master"}},"base":{"label":"sparkphp:master","ref":"master","sha":"78663a539f5695473b5d195ff6626ceb36a4f05f","user":{"login":"sparkphp","id":12573848,"avatar_url":"https://avatars.githubusercontent.com/u/12573848?v=3","gravatar_id":"","url":"https://api.github.com/users/sparkphp","html_url":"https://github.com/sparkphp","followers_url":"https://api.github.com/users/sparkphp/followers","following_url":"https://api.github.com/users/sparkphp/following{/other_user}","gists_url":"https://api.github.com/users/sparkphp/gists{/gist_id}","starred_url":"https://api.github.com/users/sparkphp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sparkphp/subscriptions","organizations_url":"https://api.github.com/users/sparkphp/orgs","repos_url":"https://api.github.com/users/sparkphp/repos","events_url":"https://api.github.com/users/sparkphp/events{/privacy}","received_events_url":"https://api.github.com/users/sparkphp/received_events","type":"Organization","site_admin":false},"repo":{"id":39100682,"name":"auth","full_name":"sparkphp/auth","owner":{"login":"sparkphp","id":12573848,"avatar_url":"https://avatars.githubusercontent.com/u/12573848?v=3","gravatar_id":"","url":"https://api.github.com/users/sparkphp","html_url":"https://github.com/sparkphp","followers_url":"https://api.github.com/users/sparkphp/followers","following_url":"https://api.github.com/users/sparkphp/following{/other_user}","gists_url":"https://api.github.com/users/sparkphp/gists{/gist_id}","starred_url":"https://api.github.com/users/sparkphp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sparkphp/subscriptions","organizations_url":"https://api.github.com/users/sparkphp/orgs","repos_url":"https://api.github.com/users/sparkphp/repos","events_url":"https://api.github.com/users/sparkphp/events{/privacy}","received_events_url":"https://api.github.com/users/sparkphp/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/sparkphp/auth","description":"Simple middleware for custom authentication.","fork":false,"url":"https://api.github.com/repos/sparkphp/auth","forks_url":"https://api.github.com/repos/sparkphp/auth/forks","keys_url":"https://api.github.com/repos/sparkphp/auth/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sparkphp/auth/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sparkphp/auth/teams","hooks_url":"https://api.github.com/repos/sparkphp/auth/hooks","issue_events_url":"https://api.github.com/repos/sparkphp/auth/issues/events{/number}","events_url":"https://api.github.com/repos/sparkphp/auth/events","assignees_url":"https://api.github.com/repos/sparkphp/auth/assignees{/user}","branches_url":"https://api.github.com/repos/sparkphp/auth/branches{/branch}","tags_url":"https://api.github.com/repos/sparkphp/auth/tags","blobs_url":"https://api.github.com/repos/sparkphp/auth/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sparkphp/auth/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sparkphp/auth/git/refs{/sha}","trees_url":"https://api.github.com/repos/sparkphp/auth/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sparkphp/auth/statuses/{sha}","languages_url":"https://api.github.com/repos/sparkphp/auth/languages","stargazers_url":"https://api.github.com/repos/sparkphp/auth/stargazers","contributors_url":"https://api.github.com/repos/sparkphp/auth/contributors","subscribers_url":"https://api.github.com/repos/sparkphp/auth/subscribers","subscription_url":"https://api.github.com/repos/sparkphp/auth/subscription","commits_url":"https://api.github.com/repos/sparkphp/auth/commits{/sha}","git_commits_url":"https://api.github.com/repos/sparkphp/auth/git/commits{/sha}","comments_url":"https://api.github.com/repos/sparkphp/auth/comments{/number}","issue_comment_url":"https://api.github.com/repos/sparkphp/auth/issues/comments{/number}","contents_url":"https://api.github.com/repos/sparkphp/auth/contents/{+path}","compare_url":"https://api.github.com/repos/sparkphp/auth/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sparkphp/auth/merges","archive_url":"https://api.github.com/repos/sparkphp/auth/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sparkphp/auth/downloads","issues_url":"https://api.github.com/repos/sparkphp/auth/issues{/number}","pulls_url":"https://api.github.com/repos/sparkphp/auth/pulls{/number}","milestones_url":"https://api.github.com/repos/sparkphp/auth/milestones{/number}","notifications_url":"https://api.github.com/repos/sparkphp/auth/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sparkphp/auth/labels{/name}","releases_url":"https://api.github.com/repos/sparkphp/auth/releases{/id}","created_at":"2015-07-14T21:15:53Z","updated_at":"2015-08-16T20:51:56Z","pushed_at":"2015-10-02T16:33:04Z","git_url":"git://github.com/sparkphp/auth.git","ssh_url":"git@github.com:sparkphp/auth.git","clone_url":"https://github.com/sparkphp/auth.git","svn_url":"https://github.com/sparkphp/auth","homepage":null,"size":156,"stargazers_count":0,"watchers_count":0,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":2,"forks":0,"open_issues":2,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/sparkphp/auth/pulls/2"},"html":{"href":"https://github.com/sparkphp/auth/pull/2"},"issue":{"href":"https://api.github.com/repos/sparkphp/auth/issues/2"},"comments":{"href":"https://api.github.com/repos/sparkphp/auth/issues/2/comments"},"review_comments":{"href":"https://api.github.com/repos/sparkphp/auth/pulls/2/comments"},"review_comment":{"href":"https://api.github.com/repos/sparkphp/auth/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/sparkphp/auth/pulls/2/commits"},"statuses":{"href":"https://api.github.com/repos/sparkphp/auth/statuses/54e1f6333954e9f6d243517ee2b4487eac06daad"}}}}