{"action":"created","comment":{"url":"https://api.github.com/repos/sparkphp/auth/pulls/comments/41418870","id":41418870,"diff_hunk":"@@ -0,0 +1,63 @@\n+<?php\n+namespace Spark\\Auth\\Jwt;\n+\n+use DateTime;\n+use Firebase\\JWT\\JWT;\n+use Psr\\Http\\Message\\RequestInterface;\n+\n+/**\n+ * Generator for JWT authentication token strings that uses the\n+ * firebase/php-jwt library.\n+ */\n+class FirebaseGenerator implements GeneratorInterface\n+{\n+    /**\n+     * @var RequestInterface\n+     */\n+    protected $request;\n+\n+    /**\n+     * @var Configuration\n+     */\n+    protected $config;\n+\n+    /**\n+     * @var string\n+     */\n+    protected $algorithm;\n+\n+    /**\n+     * @param RequestInterface $request\n+     * @param Configuration $config\n+     * @param string $algorithm Optional algorithm, defaults to 'HS256'\n+     */\n+    public function __construct(\n+        RequestInterface $request,\n+        Configuration $config,\n+        $algorithm = 'HS256'\n+    ) {\n+        $this->request = $request;\n+        $this->config = $config;\n+        $this->algorithm = $algorithm;\n+    }\n+\n+    /**\n+     * @param string $subject\n+     * @return string\n+     */\n+    public function getToken($subject)\n+    {\n+        $issuer = (string) $this->request->getUri();\n+        $issued_at = $this->config->getTimestamp()->format('U');","path":"src/Jwt/FirebaseGenerator.php","position":51,"original_position":51,"commit_id":"42a49fafe0bcd8baa061fc9dd5153e1bde1be052","original_commit_id":"42a49fafe0bcd8baa061fc9dd5153e1bde1be052","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":"Especially since the `iat` is going to be timestamp anyways... why even bother with DateTime objects at all?","created_at":"2015-10-07T17:22:24Z","updated_at":"2015-10-07T17:22:24Z","html_url":"https://github.com/sparkphp/auth/pull/2#discussion_r41418870","pull_request_url":"https://api.github.com/repos/sparkphp/auth/pulls/2","_links":{"self":{"href":"https://api.github.com/repos/sparkphp/auth/pulls/comments/41418870"},"html":{"href":"https://github.com/sparkphp/auth/pull/2#discussion_r41418870"},"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* Add [`RequestFilterInterface`](https://github.com/sparkphp/auth/blob/feature/refactor/src/RequestFilterInterface.php) for determining whether authentication\r\n  should be applied to a request\r\n* Modify [`AuthHandler`](https://github.com/sparkphp/auth/blob/feature/refactor/src/AuthHandler.php) to use authentication adapter, token extractor, user credentials extractor, request filter, 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* 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-07T17:22:24Z","closed_at":null,"merged_at":null,"merge_commit_sha":"7f21d07ca0141c2b58feebf6ab40ac638d26ce6d","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/42a49fafe0bcd8baa061fc9dd5153e1bde1be052","head":{"label":"sparkphp:feature/refactor","ref":"feature/refactor","sha":"42a49fafe0bcd8baa061fc9dd5153e1bde1be052","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-07T17:16:32Z","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":"c5f5909327df99e5f1df502288be28b78c0fe3ce","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-07T17:16:32Z","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/42a49fafe0bcd8baa061fc9dd5153e1bde1be052"}}}}