{"action":"created","comment":{"url":"https://api.github.com/repos/Wikia/app/pulls/comments/25870760","id":25870760,"diff_hunk":"@@ -61,46 +63,148 @@ public static function newFromToken( \\WebRequest $request )\n \t}\n \n \t/**\n-\t * Called in ExternalUser_Wikia::authenticate() authenticates a user.\n+\t * Performs authentication request to Helios\n+\t *\n+\t * @throws ClientException\n \t *\n \t * @param string &$username string of the user name\n \t * @param string &$password string of the plaintext password the user entered\n \t *\n \t * @return boolean true on success, false otherwise\n \t */\n-\tpublic static function authenticate( $username, $password )\n-\t{\n+\tpublic static function authenticate( $username, $password ) {\n+\t\t// check the local cache\n+\t\tif ( @self::$authenticationCache[$username][$password] !== null ) {\n+\t\t\t$resultData = self::$authenticationCache[$username][$password];\n+\t\t\tif ( $resultData[ 'exception' ] ) {\n+\t\t\t\tthrow $resultData[ 'exception' ];\n+\t\t\t}\n+\t\t\treturn $resultData[ 'result' ];\n+\t\t}\n+\n \t\t$logger = \\Wikia\\Logger\\WikiaLogger::instance();\n-\t\t$logger->info( 'HELIOS_LOGIN', [ 'method' => __METHOD__, 'username' => $username ] );\n+\t\t$logger->info( 'HELIOS_LOGIN authenticate', [ 'method' => __METHOD__, 'username' => $username ] );\n \n \t\tself::debugLogin( $password, __METHOD__ );\n \n \t\tglobal $wgHeliosBaseUri, $wgHeliosClientId, $wgHeliosClientSecret;\n \t\t$heliosClient = new Client( $wgHeliosBaseUri, $wgHeliosClientId, $wgHeliosClientSecret );\n \n+\t\t$result = false;\n+\t\t$throwException = null;\n+\n \t\t// Authenticate with username and password.\n \t\ttry {\n \t\t\t$loginInfo = $heliosClient->login( $username, $password );\n \t\t\t$result = !empty( $loginInfo->access_token );\n-\t\n-\t\t\tif ( !empty( $loginInfo->error ) ) {\n-\t\t\t\t$logger->error(\n-\t\t\t\t\t'HELIOS_LOGIN',\n-\t\t\t\t\t[ 'response' => $loginInfo, 'username' => $username, 'method' => __METHOD__ ]\n-\t\t\t\t);\n-\t\t\t\t$result = false;\n-\t\t\t}\n \t\t}\n-\n-\t\tcatch ( \\Wikia\\Helios\\ClientException $e ) {\n-\t\t\t$logger->error(\n-\t\t\t\t'HELIOS_LOGIN',\n-\t\t\t\t[ 'exception' => $e, 'username' => $username, 'method' => __METHOD__ ]\n+\t\tcatch ( LoginFailureException $e )\n+\t\t{\n+\t\t\t// normal case: password incorrect, log it as info\n+\t\t\t$logger->info(\n+\t\t\t\t'HELIOS_LOGIN authentication_failed',\n+\t\t\t\t[ 'response' => $e->getResponse(), 'username' => $username, 'method' => __METHOD__ ]\n \t\t\t);\n \t\t\t$result = false;\n \t\t}\n+\t\tcatch ( ClientException $e )\n+\t\t{\n+\t\t\t$logger->error(\n+\t\t\t\t'HELIOS_LOGIN authentication_error',\n+\t\t\t\t[ 'exception' => $e, 'response' => $e->getResponse(), 'username' => $username, 'method' => __METHOD__ ]\n+\t\t\t);\n+\t\t\t$throwException = $e;\n+\t\t}\n+\n+\t\t// save in local cache\n+\t\tself::$authenticationCache[$username][$password] = [\n+\t\t\t'result'=> $result,\n+\t\t\t'exception' => $throwException\n+\t\t];\n+\n+\t\tif ( $throwException ) {\n+\t\t\tthrow $throwException;\n+\t\t}\n \n \t\treturn $result;\n \t}\n \n+\t/**\n+\t * Purge the authentication cache. If the username is specified only that username is affected.\n+\t *\n+\t * @param string $username (optional) Username\n+\t */\n+\tpublic static function purgeAuthenticationCache( $username = null ) {\n+\t\tif ( $username === null ) {\n+\t\t\tself::$authenticationCache = [];\n+\t\t} else {\n+\t\t\tunset( self::$authenticationCache[$username] );\n+\t\t}\n+\t}\n+\n+\n+\t/**\n+\t * Listens for any authentication attempts and uses Helios to determine the result\n+\t *\n+\t * @param int $id Id\n+\t * @param string $username Username\n+\t * @param string $hash Password hash\n+\t * @param string $password Password\n+\t * @param bool &$result (out) Authentication result\n+\t * @param string &$errorMessageKey (out) Error message\n+\t * @return bool true - hook handler\n+\t */\n+\tpublic static function onUserCheckPassword( $id, $username, $hash, $password, &$result, &$errorMessageKey ) {\n+\t\tglobal $wgHeliosLoginShadowMode;\n+\n+\t\t$heliosResult = null;\n+\t\t$heliosException = null;\n+\t\ttry {\n+\t\t\t$heliosResult = \\Wikia\\Helios\\User::authenticate( $username, $password );","path":"extensions/wikia/Helios/User.class.php","position":127,"original_position":127,"commit_id":"3f9ff96dd656a8dbdb2f22c4c79eb021c631d42b","original_commit_id":"3f9ff96dd656a8dbdb2f22c4c79eb021c631d42b","user":{"login":"wladekb","id":811686,"avatar_url":"https://avatars.githubusercontent.com/u/811686?v=3","gravatar_id":"","url":"https://api.github.com/users/wladekb","html_url":"https://github.com/wladekb","followers_url":"https://api.github.com/users/wladekb/followers","following_url":"https://api.github.com/users/wladekb/following{/other_user}","gists_url":"https://api.github.com/users/wladekb/gists{/gist_id}","starred_url":"https://api.github.com/users/wladekb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wladekb/subscriptions","organizations_url":"https://api.github.com/users/wladekb/orgs","repos_url":"https://api.github.com/users/wladekb/repos","events_url":"https://api.github.com/users/wladekb/events{/privacy}","received_events_url":"https://api.github.com/users/wladekb/received_events","type":"User","site_admin":false},"body":"Yeah... will fix it","created_at":"2015-03-05T15:21:19Z","updated_at":"2015-03-05T15:21:19Z","html_url":"https://github.com/Wikia/app/pull/6534#discussion_r25870760","pull_request_url":"https://api.github.com/repos/Wikia/app/pulls/6534","_links":{"self":{"href":"https://api.github.com/repos/Wikia/app/pulls/comments/25870760"},"html":{"href":"https://github.com/Wikia/app/pull/6534#discussion_r25870760"},"pull_request":{"href":"https://api.github.com/repos/Wikia/app/pulls/6534"}}},"pull_request":{"url":"https://api.github.com/repos/Wikia/app/pulls/6534","id":30457438,"html_url":"https://github.com/Wikia/app/pull/6534","diff_url":"https://github.com/Wikia/app/pull/6534.diff","patch_url":"https://github.com/Wikia/app/pull/6534.patch","issue_url":"https://api.github.com/repos/Wikia/app/issues/6534","number":6534,"state":"open","locked":false,"title":"Use Helios for login processing in all places","user":{"login":"wladekb","id":811686,"avatar_url":"https://avatars.githubusercontent.com/u/811686?v=3","gravatar_id":"","url":"https://api.github.com/users/wladekb","html_url":"https://github.com/wladekb","followers_url":"https://api.github.com/users/wladekb/followers","following_url":"https://api.github.com/users/wladekb/following{/other_user}","gists_url":"https://api.github.com/users/wladekb/gists{/gist_id}","starred_url":"https://api.github.com/users/wladekb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wladekb/subscriptions","organizations_url":"https://api.github.com/users/wladekb/orgs","repos_url":"https://api.github.com/users/wladekb/repos","events_url":"https://api.github.com/users/wladekb/events{/privacy}","received_events_url":"https://api.github.com/users/wladekb/received_events","type":"User","site_admin":false},"body":"This changeset aims to replace all comparisons of the user's main password and delegate it to Helios (temporary password comparison is still left up to MediaWiki). We'll then have a single source of truth for authentication.\r\n\r\nWork in progress.\r\n\r\n/cc @michalroszka ","created_at":"2015-03-04T11:29:19Z","updated_at":"2015-03-05T15:21:19Z","closed_at":null,"merged_at":null,"merge_commit_sha":"08ee513a731781260d92590b75fc02cb2b3cba69","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/Wikia/app/pulls/6534/commits","review_comments_url":"https://api.github.com/repos/Wikia/app/pulls/6534/comments","review_comment_url":"https://api.github.com/repos/Wikia/app/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Wikia/app/issues/6534/comments","statuses_url":"https://api.github.com/repos/Wikia/app/statuses/3f9ff96dd656a8dbdb2f22c4c79eb021c631d42b","head":{"label":"Wikia:helios-use-it-in-all-login-places","ref":"helios-use-it-in-all-login-places","sha":"3f9ff96dd656a8dbdb2f22c4c79eb021c631d42b","user":{"login":"Wikia","id":1171011,"avatar_url":"https://avatars.githubusercontent.com/u/1171011?v=3","gravatar_id":"","url":"https://api.github.com/users/Wikia","html_url":"https://github.com/Wikia","followers_url":"https://api.github.com/users/Wikia/followers","following_url":"https://api.github.com/users/Wikia/following{/other_user}","gists_url":"https://api.github.com/users/Wikia/gists{/gist_id}","starred_url":"https://api.github.com/users/Wikia/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Wikia/subscriptions","organizations_url":"https://api.github.com/users/Wikia/orgs","repos_url":"https://api.github.com/users/Wikia/repos","events_url":"https://api.github.com/users/Wikia/events{/privacy}","received_events_url":"https://api.github.com/users/Wikia/received_events","type":"Organization","site_admin":false},"repo":{"id":5532313,"name":"app","full_name":"Wikia/app","owner":{"login":"Wikia","id":1171011,"avatar_url":"https://avatars.githubusercontent.com/u/1171011?v=3","gravatar_id":"","url":"https://api.github.com/users/Wikia","html_url":"https://github.com/Wikia","followers_url":"https://api.github.com/users/Wikia/followers","following_url":"https://api.github.com/users/Wikia/following{/other_user}","gists_url":"https://api.github.com/users/Wikia/gists{/gist_id}","starred_url":"https://api.github.com/users/Wikia/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Wikia/subscriptions","organizations_url":"https://api.github.com/users/Wikia/orgs","repos_url":"https://api.github.com/users/Wikia/repos","events_url":"https://api.github.com/users/Wikia/events{/privacy}","received_events_url":"https://api.github.com/users/Wikia/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Wikia/app","description":"Wikia Application Code","fork":false,"url":"https://api.github.com/repos/Wikia/app","forks_url":"https://api.github.com/repos/Wikia/app/forks","keys_url":"https://api.github.com/repos/Wikia/app/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Wikia/app/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Wikia/app/teams","hooks_url":"https://api.github.com/repos/Wikia/app/hooks","issue_events_url":"https://api.github.com/repos/Wikia/app/issues/events{/number}","events_url":"https://api.github.com/repos/Wikia/app/events","assignees_url":"https://api.github.com/repos/Wikia/app/assignees{/user}","branches_url":"https://api.github.com/repos/Wikia/app/branches{/branch}","tags_url":"https://api.github.com/repos/Wikia/app/tags","blobs_url":"https://api.github.com/repos/Wikia/app/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Wikia/app/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Wikia/app/git/refs{/sha}","trees_url":"https://api.github.com/repos/Wikia/app/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Wikia/app/statuses/{sha}","languages_url":"https://api.github.com/repos/Wikia/app/languages","stargazers_url":"https://api.github.com/repos/Wikia/app/stargazers","contributors_url":"https://api.github.com/repos/Wikia/app/contributors","subscribers_url":"https://api.github.com/repos/Wikia/app/subscribers","subscription_url":"https://api.github.com/repos/Wikia/app/subscription","commits_url":"https://api.github.com/repos/Wikia/app/commits{/sha}","git_commits_url":"https://api.github.com/repos/Wikia/app/git/commits{/sha}","comments_url":"https://api.github.com/repos/Wikia/app/comments{/number}","issue_comment_url":"https://api.github.com/repos/Wikia/app/issues/comments{/number}","contents_url":"https://api.github.com/repos/Wikia/app/contents/{+path}","compare_url":"https://api.github.com/repos/Wikia/app/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Wikia/app/merges","archive_url":"https://api.github.com/repos/Wikia/app/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Wikia/app/downloads","issues_url":"https://api.github.com/repos/Wikia/app/issues{/number}","pulls_url":"https://api.github.com/repos/Wikia/app/pulls{/number}","milestones_url":"https://api.github.com/repos/Wikia/app/milestones{/number}","notifications_url":"https://api.github.com/repos/Wikia/app/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Wikia/app/labels{/name}","releases_url":"https://api.github.com/repos/Wikia/app/releases{/id}","created_at":"2012-08-23T20:55:58Z","updated_at":"2015-03-05T13:52:35Z","pushed_at":"2015-03-05T14:10:00Z","git_url":"git://github.com/Wikia/app.git","ssh_url":"git@github.com:Wikia/app.git","clone_url":"https://github.com/Wikia/app.git","svn_url":"https://github.com/Wikia/app","homepage":"http://dev.wikia.com","size":1373216,"stargazers_count":74,"watchers_count":74,"language":"PHP","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":52,"mirror_url":null,"open_issues_count":60,"forks":52,"open_issues":60,"watchers":74,"default_branch":"dev"}},"base":{"label":"Wikia:dev","ref":"dev","sha":"ba5afc3c55d2531b53fab8420fd5f5429d79763c","user":{"login":"Wikia","id":1171011,"avatar_url":"https://avatars.githubusercontent.com/u/1171011?v=3","gravatar_id":"","url":"https://api.github.com/users/Wikia","html_url":"https://github.com/Wikia","followers_url":"https://api.github.com/users/Wikia/followers","following_url":"https://api.github.com/users/Wikia/following{/other_user}","gists_url":"https://api.github.com/users/Wikia/gists{/gist_id}","starred_url":"https://api.github.com/users/Wikia/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Wikia/subscriptions","organizations_url":"https://api.github.com/users/Wikia/orgs","repos_url":"https://api.github.com/users/Wikia/repos","events_url":"https://api.github.com/users/Wikia/events{/privacy}","received_events_url":"https://api.github.com/users/Wikia/received_events","type":"Organization","site_admin":false},"repo":{"id":5532313,"name":"app","full_name":"Wikia/app","owner":{"login":"Wikia","id":1171011,"avatar_url":"https://avatars.githubusercontent.com/u/1171011?v=3","gravatar_id":"","url":"https://api.github.com/users/Wikia","html_url":"https://github.com/Wikia","followers_url":"https://api.github.com/users/Wikia/followers","following_url":"https://api.github.com/users/Wikia/following{/other_user}","gists_url":"https://api.github.com/users/Wikia/gists{/gist_id}","starred_url":"https://api.github.com/users/Wikia/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Wikia/subscriptions","organizations_url":"https://api.github.com/users/Wikia/orgs","repos_url":"https://api.github.com/users/Wikia/repos","events_url":"https://api.github.com/users/Wikia/events{/privacy}","received_events_url":"https://api.github.com/users/Wikia/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Wikia/app","description":"Wikia Application Code","fork":false,"url":"https://api.github.com/repos/Wikia/app","forks_url":"https://api.github.com/repos/Wikia/app/forks","keys_url":"https://api.github.com/repos/Wikia/app/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Wikia/app/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Wikia/app/teams","hooks_url":"https://api.github.com/repos/Wikia/app/hooks","issue_events_url":"https://api.github.com/repos/Wikia/app/issues/events{/number}","events_url":"https://api.github.com/repos/Wikia/app/events","assignees_url":"https://api.github.com/repos/Wikia/app/assignees{/user}","branches_url":"https://api.github.com/repos/Wikia/app/branches{/branch}","tags_url":"https://api.github.com/repos/Wikia/app/tags","blobs_url":"https://api.github.com/repos/Wikia/app/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Wikia/app/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Wikia/app/git/refs{/sha}","trees_url":"https://api.github.com/repos/Wikia/app/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Wikia/app/statuses/{sha}","languages_url":"https://api.github.com/repos/Wikia/app/languages","stargazers_url":"https://api.github.com/repos/Wikia/app/stargazers","contributors_url":"https://api.github.com/repos/Wikia/app/contributors","subscribers_url":"https://api.github.com/repos/Wikia/app/subscribers","subscription_url":"https://api.github.com/repos/Wikia/app/subscription","commits_url":"https://api.github.com/repos/Wikia/app/commits{/sha}","git_commits_url":"https://api.github.com/repos/Wikia/app/git/commits{/sha}","comments_url":"https://api.github.com/repos/Wikia/app/comments{/number}","issue_comment_url":"https://api.github.com/repos/Wikia/app/issues/comments{/number}","contents_url":"https://api.github.com/repos/Wikia/app/contents/{+path}","compare_url":"https://api.github.com/repos/Wikia/app/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Wikia/app/merges","archive_url":"https://api.github.com/repos/Wikia/app/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Wikia/app/downloads","issues_url":"https://api.github.com/repos/Wikia/app/issues{/number}","pulls_url":"https://api.github.com/repos/Wikia/app/pulls{/number}","milestones_url":"https://api.github.com/repos/Wikia/app/milestones{/number}","notifications_url":"https://api.github.com/repos/Wikia/app/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Wikia/app/labels{/name}","releases_url":"https://api.github.com/repos/Wikia/app/releases{/id}","created_at":"2012-08-23T20:55:58Z","updated_at":"2015-03-05T13:52:35Z","pushed_at":"2015-03-05T14:10:00Z","git_url":"git://github.com/Wikia/app.git","ssh_url":"git@github.com:Wikia/app.git","clone_url":"https://github.com/Wikia/app.git","svn_url":"https://github.com/Wikia/app","homepage":"http://dev.wikia.com","size":1373216,"stargazers_count":74,"watchers_count":74,"language":"PHP","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":52,"mirror_url":null,"open_issues_count":60,"forks":52,"open_issues":60,"watchers":74,"default_branch":"dev"}},"_links":{"self":{"href":"https://api.github.com/repos/Wikia/app/pulls/6534"},"html":{"href":"https://github.com/Wikia/app/pull/6534"},"issue":{"href":"https://api.github.com/repos/Wikia/app/issues/6534"},"comments":{"href":"https://api.github.com/repos/Wikia/app/issues/6534/comments"},"review_comments":{"href":"https://api.github.com/repos/Wikia/app/pulls/6534/comments"},"review_comment":{"href":"https://api.github.com/repos/Wikia/app/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Wikia/app/pulls/6534/commits"},"statuses":{"href":"https://api.github.com/repos/Wikia/app/statuses/3f9ff96dd656a8dbdb2f22c4c79eb021c631d42b"}}}}