[MediaWiki-commits] [Gerrit] mediawiki...MediaWikiAuth[master]: Update extension for AuthManager
jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/386711 ) Change subject: Update extension for AuthManager .. Update extension for AuthManager In addition to AuthManager compatibility, this brings it up to modern coding standards regarding array syntax and the like, and converts the extension to use extension registration. Compatibility shims have been removed. Bug: T110293 Change-Id: Ia0caae13109affe6a441f087e31dc83e9856f309 Co-Authored-By: Isarra--- A ExternalWikiPrimaryAuthenticationProvider.php D MediaWikiAuth.i18n.php D MediaWikiAuth.php D MediaWikiAuthPlugin.class.php A PopulateImportedWatchlistJob.php D README D Snoopy.class.php A extension.json M i18n/en.json M i18n/qqq.json D patches/SpecialUserlogin.php-1.17alpha.r67921.patch D patches/SpecialUserlogin.php-1.20.0.patch D patches/SpecialUserlogin.php-1.21.2.patch D patches/SpecialUserlogin.php-1.23.3.patch 14 files changed, 456 insertions(+), 2,120 deletions(-) Approvals: Jack Phoenix: Looks good to me, approved jenkins-bot: Verified diff --git a/ExternalWikiPrimaryAuthenticationProvider.php b/ExternalWikiPrimaryAuthenticationProvider.php new file mode 100644 index 000..c8fd679 --- /dev/null +++ b/ExternalWikiPrimaryAuthenticationProvider.php @@ -0,0 +1,363 @@ +cookieJar = new \CookieJar(); + } + + /** +* Attempt to authenticate against a remote wiki's API +* +* We first check to see if the given user exists in the remote wiki; if they do not +* then we abstain from this auth provider (as the username may be handled by a different +* provider). If they exist, we attempt to auth against that username with our provided +* password, and return the result (PASS/FAIL). +* +* Once the user successfully authenticates, we import their Preferences and Watchlist from +* the remote wiki and prompt them to change their password. +*/ + public function beginPrimaryAuthentication( array $reqs ) { + $req = AuthenticationRequest::getRequestByClass( $reqs, PasswordAuthenticationRequest::class ); + if ( !$req ) { + return AuthenticationResponse::newAbstain(); + } + + if ( $req->username === null || $req->password === null ) { + return AuthenticationResponse::newAbstain(); + } + + // Check if the user exists on the local wiki. If so, do not attempt to auth against the remote one. + // if $existingUser is false, that means username validation failed so we won't be able to auth with + // this name anyway once the account does exist. + $existingUser = User::newFromName( $req->username, 'usable' ); + if ( $existingUser === false || $existingUser->getId() !== 0 ) { + return AuthenticationResponse::newAbstain(); + } + + $username = $existingUser->getName(); + + // Check for username existence on other wiki + if ( !$this->testUserExists( $username ) ) { + return AuthenticationResponse::newAbstain(); + } + + // Grab remote MediaWiki version; our auth flow depends on what we get back + $resp = $this->apiRequest( 'GET', [ + 'action' => 'query', + 'meta' => 'siteinfo', + 'siprop' => 'general' + ], [], __METHOD__ ); + // generator is of the form 'MediaWiki X.X.X'; strip MediaWiki from out front + $remoteVersion = substr( $resp->query->general->generator, 10 ); + + if ( version_compare( $remoteVersion, '1.27', '<' ) ) { + // use old login API + $resp = $this->apiRequest( 'POST', [ + 'action' => 'login' + ], [ + 'lgname' => $username, + 'lgpassword' => $req->password + ], __METHOD__ ); + + if ( $resp->login->result === 'NeedToken' ) { + $loginToken = $resp->login->token; + + $resp = $this->apiRequest( 'POST', [ + 'action' => 'login' + ], [ + 'lgname' => $username, + 'lgpassword' => $req->password, + 'lgtoken' => $loginToken + ], __METHOD__ ); + } + + if ( $resp->login->result !== 'Success' ) { + $this->logger->info( 'Authentication against legacy
[MediaWiki-commits] [Gerrit] mediawiki...MediaWikiAuth[master]: Update extension for AuthManager
Skizzerz has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/386711 ) Change subject: Update extension for AuthManager .. Update extension for AuthManager In addition to AuthManager compatibility, this brings it up to modern coding standards regarding array syntax and the like, and converts the extension to use extension registration. Compatibility shims have been removed. Bug: T110293 Change-Id: Ia0caae13109affe6a441f087e31dc83e9856f309 Co-Authored-By: Isarra--- A ExternalWikiPrimaryAuthenticationProvider.php D MediaWikiAuth.i18n.php D MediaWikiAuth.php D MediaWikiAuthPlugin.class.php A PopulateImportedWatchlistJob.php D README D Snoopy.class.php A extension.json M i18n/en.json M i18n/qqq.json D patches/SpecialUserlogin.php-1.17alpha.r67921.patch D patches/SpecialUserlogin.php-1.20.0.patch D patches/SpecialUserlogin.php-1.21.2.patch D patches/SpecialUserlogin.php-1.23.3.patch 14 files changed, 456 insertions(+), 2,116 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/MediaWikiAuth refs/changes/11/386711/1 diff --git a/ExternalWikiPrimaryAuthenticationProvider.php b/ExternalWikiPrimaryAuthenticationProvider.php new file mode 100644 index 000..3d24e68 --- /dev/null +++ b/ExternalWikiPrimaryAuthenticationProvider.php @@ -0,0 +1,364 @@ +cookieJar = new \CookieJar(); + } + + /** +* Attempt to authenticate against a remote wiki's API +* +* We first check to see if the given user exists in the remote wiki; if they do not +* then we abstain from this auth provider (as the username may be handled by a different +* provider). If they exist, we attempt to auth against that username with our provided +* password, and return the result (PASS/FAIL). +* +* Once the user successfully authenticates, we import their Preferences and Watchlist from +* the remote wiki and prompt them to change their password. +*/ + public function beginPrimaryAuthentication( array $reqs ) { + $req = AuthenticationRequest::getRequestByClass( $reqs, PasswordAuthenticationRequest::class ); + if ( !$req ) { + return AuthenticationResponse::newAbstain(); + } + + if ( $req->username === null || $req->password === null ) { + return AuthenticationResponse::newAbstain(); + } + + // Check if the user exists on the local wiki. If so, do not attempt to auth against the remote one. + // if $existingUser is false, that means username validation failed so we won't be able to auth with + // this name anyway once the account does exist. + $existingUser = User::newFromName( $req->username, 'usable' ); + if ( $existingUser === false || $existingUser->getId() !== 0 ) { + return AuthenticationResponse::newAbstain(); + } + + $username = $existingUser->getName(); + + // Check for username existence on other wiki + if ( !$this->testUserExists( $username ) ) { + return AuthenticationResponse::newAbstain(); + } + + // Grab remote MediaWiki version; our auth flow depends on what we get back + $resp = $this->apiRequest( 'GET', [ + 'action' => 'query', + 'meta' => 'siteinfo', + 'siprop' => 'general' + ], [], __METHOD__ ); + // generator is of the form 'MediaWiki X.X.X'; strip MediaWiki from out front + $remoteVersion = substr( $resp->query->general->generator, 10 ); + + if ( version_compare( $remoteVersion, '1.27', '<' ) ) { + // use old login API + $resp = $this->apiRequest( 'POST', [ + 'action' => 'login' + ], [ + 'lgname' => $username, + 'lgpassword' => $req->password + ], __METHOD__ ); + + if ( $resp->login->result === 'NeedToken' ) { + $loginToken = $resp->login->token; + + $resp = $this->apiRequest( 'POST', [ + 'action' => 'login' + ], [ + 'lgname' => $username, + 'lgpassword' => $req->password, + 'lgtoken' => $loginToken + ], __METHOD__ ); + } + + if ( $resp->login->result !== 'Success' ) { + $this->logger->info( 'Authentication