From: Gergő Tisza Date: Wed, 8 Jun 2016 20:08:45 +0000 (+0000) Subject: Add new convenience User method for authentication data change X-Git-Tag: 1.31.0-rc.0~6681^2 X-Git-Url: http://git.cyclocoop.org/%22%20.%20generer_url_ecrire%28%22articles%22%2C%22id_article=%24ze_article%22%29%20.%20%22?a=commitdiff_plain;h=b568497e9a863bf71338b254eb05ca3da9c38eb5;p=lhc%2Fweb%2Fwiklou.git Add new convenience User method for authentication data change Also update createAndPromote.php to use it so it can display errors. Note that there are two possible approaches. The other is to do the update for all requests for which the test passed, even if some tests fail. The approach of the patch seems more manageable from the caller's point of view (either the operation was a success, or it failed and nothing happened). Change-Id: I86abed4b80472cd888337444fac0cbcb870b1246 --- diff --git a/includes/user/User.php b/includes/user/User.php index 8ecf468647..5eef0c244e 100644 --- a/includes/user/User.php +++ b/includes/user/User.php @@ -2560,23 +2560,16 @@ class User implements IDBAccessObject { throw new LogicException( 'Cannot set a password for a user that is not in the database.' ); } - $data = [ + $status = $this->changeAuthenticationData( [ 'username' => $this->getName(), 'password' => $str, 'retype' => $str, - ]; - $reqs = $manager->getAuthenticationRequests( AuthManager::ACTION_CHANGE, $this ); - $reqs = AuthenticationRequest::loadRequestsFromSubmission( $reqs, $data ); - foreach ( $reqs as $req ) { - $status = $manager->allowsAuthenticationDataChange( $req ); - if ( !$status->isGood() ) { - \MediaWiki\Logger\LoggerFactory::getInstance( 'authentication' ) - ->info( __METHOD__ . ': Password change rejected: ' . $status->getWikiText() ); - return false; - } - } - foreach ( $reqs as $req ) { - $manager->changeAuthenticationData( $req ); + ] ); + if ( !$status->isGood() ) { + \MediaWiki\Logger\LoggerFactory::getInstance( 'authentication' ) + ->info( __METHOD__ . ': Password change rejected: ' + . $status->getWikiText( null, null, 'en' ) ); + return false; } $this->setOption( 'watchlisttoken', false ); @@ -2587,6 +2580,45 @@ class User implements IDBAccessObject { return true; } + /** + * Changes credentials of the user. + * + * This is a convenience wrapper around AuthManager::changeAuthenticationData. + * Note that this can return a status that isOK() but not isGood() on certain types of failures, + * e.g. when no provider handled the change. + * + * @param array $data A set of authentication data in fieldname => value format. This is the + * same data you would pass the changeauthenticationdata API - 'username', 'password' etc. + * @return Status + * @since 1.27 + */ + public function changeAuthenticationData( array $data ) { + global $wgDisableAuthManager; + if ( $wgDisableAuthManager ) { + throw new LogicException( __METHOD__ . ' cannot be called when $wgDisableAuthManager ' + . 'is true' ); + } + + $manager = AuthManager::singleton(); + $reqs = $manager->getAuthenticationRequests( AuthManager::ACTION_CHANGE, $this ); + $reqs = AuthenticationRequest::loadRequestsFromSubmission( $reqs, $data ); + + $status = Status::newGood( 'ignored' ); + foreach ( $reqs as $req ) { + $status->merge( $manager->allowsAuthenticationDataChange( $req ), true ); + } + if ( $status->getValue() === 'ignored' ) { + $status->warning( 'authenticationdatachange-ignored' ); + } + + if ( $status->isGood() ) { + foreach ( $reqs as $req ) { + $manager->changeAuthenticationData( $req ); + } + } + return $status; + } + /** * Get the user's current token. * @param bool $forceCreation Force the generation of a new token if the diff --git a/languages/i18n/en.json b/languages/i18n/en.json index a028283e51..91d75413b1 100644 --- a/languages/i18n/en.json +++ b/languages/i18n/en.json @@ -4183,5 +4183,6 @@ "linkaccounts-success-text": "The account was linked.", "linkaccounts-submit": "Link accounts", "unlinkaccounts": "Unlink accounts", - "unlinkaccounts-success": "The account was unlinked." + "unlinkaccounts-success": "The account was unlinked.", + "authenticationdatachange-ignored": "The authentication data change was not handled. Maybe no provider was configured?" } diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json index ad9a372e3d..ef5e8194b3 100644 --- a/languages/i18n/qqq.json +++ b/languages/i18n/qqq.json @@ -4364,5 +4364,6 @@ "linkaccounts-success-text": "Text shown on top of the form after a successful action.", "linkaccounts-submit": "Text of the main submit button on [[Special:LinkAccounts]] (when there is one)", "unlinkaccounts": "Title of the special page [[Special:UnlinkAccounts]] which allows the user to remove linked remote accounts.", - "unlinkaccounts-success": "Account unlinking form success message" + "unlinkaccounts-success": "Account unlinking form success message", + "authenticationdatachange-ignored": "Shown when authentication data change was unsuccessful due to configuration problems." } diff --git a/maintenance/changePassword.php b/maintenance/changePassword.php index 8687f81410..a550d12777 100644 --- a/maintenance/changePassword.php +++ b/maintenance/changePassword.php @@ -41,6 +41,8 @@ class ChangePassword extends Maintenance { } public function execute() { + global $wgDisableAuthManager; + if ( $this->hasOption( "user" ) ) { $user = User::newFromName( $this->getOption( 'user' ) ); } elseif ( $this->hasOption( "userid" ) ) { @@ -51,8 +53,20 @@ class ChangePassword extends Maintenance { if ( !$user || !$user->getId() ) { $this->error( "No such user: " . $this->getOption( 'user' ), true ); } + $password = $this->getOption( 'password' ); try { - $user->setPassword( $this->getOption( 'password' ) ); + if ( $wgDisableAuthManager ) { + $user->setPassword( $password ); + } else { + $status = $user->changeAuthenticationData( [ + 'username' => $user->getName(), + 'password' => $password, + 'retype' => $password, + ] ); + if ( !$status->isGood() ) { + throw new PasswordError( $status->getWikiText( null, null, 'en' ) ); + } + } $user->saveSettings(); $this->output( "Password set for " . $user->getName() . "\n" ); } catch ( PasswordError $pwe ) { diff --git a/maintenance/createAndPromote.php b/maintenance/createAndPromote.php index 848c2f7eda..3591b9ce24 100644 --- a/maintenance/createAndPromote.php +++ b/maintenance/createAndPromote.php @@ -56,6 +56,8 @@ class CreateAndPromote extends Maintenance { } public function execute() { + global $wgDisableAuthManager; + $username = $this->getArg( 0 ); $password = $this->getArg( 1 ); $force = $this->hasOption( 'force' ); @@ -120,7 +122,18 @@ class CreateAndPromote extends Maintenance { if ( $password ) { # Try to set the password try { - $user->setPassword( $password ); + if ( $wgDisableAuthManager ) { + $user->setPassword( $password ); + } else { + $status = $user->changeAuthenticationData( [ + 'username' => $user->getName(), + 'password' => $password, + 'retype' => $password, + ] ); + if ( !$status->isGood() ) { + throw new PasswordError( $status->getWikiText( null, null, 'en' ) ); + } + } if ( $exists ) { $this->output( "Password set.\n" ); $user->saveSettings();