'stasherrors' rather than a 'stashfailed' text string.
* action=watch reports 'errors' and 'warnings' instead of a single 'error', and
no longer returns a 'message' on success.
+* Added action=validatepassword to validate passwords for the account creation
+ and password change forms.
=== Action API internal changes in 1.29 ===
* New methods were added to ApiBase to handle errors and warnings using i18n
'ApiUpload' => __DIR__ . '/includes/api/ApiUpload.php',
'ApiUsageException' => __DIR__ . '/includes/api/ApiUsageException.php',
'ApiUserrights' => __DIR__ . '/includes/api/ApiUserrights.php',
+ 'ApiValidatePassword' => __DIR__ . '/includes/api/ApiValidatePassword.php',
'ApiWatch' => __DIR__ . '/includes/api/ApiWatch.php',
'ArchivedFile' => __DIR__ . '/includes/filerepo/file/ArchivedFile.php',
'ArrayDiffFormatter' => __DIR__ . '/includes/diff/ArrayDiffFormatter.php',
&$tokenTypes: supported token types in format 'type' => callback function
used to retrieve this type of tokens.
+'ApiValidatePassword': Called from ApiValidatePassword.
+$module: ApiValidatePassword instance.
+&$r: Result array.
+
'Article::MissingArticleConditions': Before fetching deletion & move log entries
to display a message of a non-existing page being deleted/moved, give extensions
a chance to hide their (unrelated) log entries.
'tokens' => 'ApiTokens',
'checktoken' => 'ApiCheckToken',
'cspreport' => 'ApiCSPReport',
+ 'validatepassword' => 'ApiValidatePassword',
// Write modules
'purge' => 'ApiPurge',
--- /dev/null
+<?php
+
+use MediaWiki\Auth\AuthManager;
+
+/**
+ * @ingroup API
+ */
+class ApiValidatePassword extends ApiBase {
+
+ public function execute() {
+ $params = $this->extractRequestParams();
+
+ // For sanity
+ $this->requirePostedParameters( [ 'password' ] );
+
+ if ( $params['user'] !== null ) {
+ $user = User::newFromName( $params['user'], 'creatable' );
+ if ( !$user ) {
+ $encParamName = $this->encodeParamName( 'user' );
+ $this->dieWithError(
+ [ 'apierror-baduser', $encParamName, wfEscapeWikiText( $params['user'] ) ],
+ "baduser_{$encParamName}"
+ );
+ }
+
+ if ( !$user->isAnon() || AuthManager::singleton()->userExists( $user->getName() ) ) {
+ $this->dieWithError( 'userexists' );
+ }
+
+ $user->setEmail( (string)$params['email'] );
+ $user->setRealName( (string)$params['realname'] );
+ } else {
+ $user = $this->getUser();
+ }
+
+ $validity = $user->checkPasswordValidity( $params['password'] );
+ $r['validity'] = $validity->isGood() ? 'Good' : ( $validity->isOK() ? 'Change' : 'Invalid' );
+ $messages = array_merge(
+ $this->getErrorFormatter()->arrayFromStatus( $validity, 'error' ),
+ $this->getErrorFormatter()->arrayFromStatus( $validity, 'warning' )
+ );
+ if ( $messages ) {
+ $r['validitymessages'] = $messages;
+ }
+
+ Hooks::run( 'ApiValidatePassword', [ $this, &$r ] );
+
+ $this->getResult()->addValue( null, $this->getModuleName(), $r );
+ }
+
+ public function mustBePosted() {
+ return true;
+ }
+
+ public function getAllowedParams() {
+ return [
+ 'password' => [
+ ApiBase::PARAM_TYPE => 'password',
+ ApiBase::PARAM_REQUIRED => true
+ ],
+ 'user' => [
+ ApiBase::PARAM_TYPE => 'user',
+ ],
+ 'email' => null,
+ 'realname' => null,
+ ];
+ }
+
+ protected function getExamplesMessages() {
+ return [
+ 'action=validatepassword&password=foobar'
+ => 'apihelp-validatepassword-example-1',
+ 'action=validatepassword&password=querty&user=Example'
+ => 'apihelp-validatepassword-example-2',
+ ];
+ }
+
+ public function getHelpUrls() {
+ return 'https://www.mediawiki.org/wiki/API:Validatepassword';
+ }
+}
"apihelp-userrights-example-user": "Add user <kbd>FooBot</kbd> to group <kbd>bot</kbd>, and remove from groups <kbd>sysop</kbd> and <kbd>bureaucrat</kbd>.",
"apihelp-userrights-example-userid": "Add the user with ID <kbd>123</kbd> to group <kbd>bot</kbd>, and remove from groups <kbd>sysop</kbd> and <kbd>bureaucrat</kbd>.",
+ "apihelp-validatepassword-description": "Validate a password against the wiki's password policies.\n\nValidity is reported as <samp>Good</samp> if the password is acceptable, <samp>Change</samp> if the password may be used for login but must be changed, or <samp>Invalid</samp> if the password is not usable.",
+ "apihelp-validatepassword-param-password": "Password to validate.",
+ "apihelp-validatepassword-param-user": "User name, for use when testing account creation. The named user must not exist.",
+ "apihelp-validatepassword-param-email": "Email address, for use when testing account creation.",
+ "apihelp-validatepassword-param-realname": "Real name, for use when testing account creation.",
+ "apihelp-validatepassword-example-1": "Validate the password <kbd>foobar</kbd> for the current user.",
+ "apihelp-validatepassword-example-2": "Validate the password <kbd>qwerty</kbd> for creating user <kbd>Example</kbd>.",
+
"apihelp-watch-description": "Add or remove pages from the current user's watchlist.",
"apihelp-watch-param-title": "The page to (un)watch. Use <var>$1titles</var> instead.",
"apihelp-watch-param-unwatch": "If set the page will be unwatched rather than watched.",
"apihelp-userrights-param-reason": "{{doc-apihelp-param|userrights|reason}}",
"apihelp-userrights-example-user": "{{doc-apihelp-example|userrights}}",
"apihelp-userrights-example-userid": "{{doc-apihelp-example|userrights}}",
+ "apihelp-validatepassword-description": "{{doc-apihelp-description|validatepassword}}",
+ "apihelp-validatepassword-param-email": "{{doc-apihelp-param|validatepassword|email}}",
+ "apihelp-validatepassword-param-password": "{{doc-apihelp-param|validatepassword|password}}",
+ "apihelp-validatepassword-param-realname": "{{doc-apihelp-param|validatepassword|realname}}",
+ "apihelp-validatepassword-param-user": "{{doc-apihelp-param|validatepassword|user}}",
+ "apihelp-validatepassword-example-1": "{{doc-apihelp-example|validatepassword}}",
+ "apihelp-validatepassword-example-2": "{{doc-apihelp-example|validatepassword}}",
"apihelp-watch-description": "{{doc-apihelp-description|watch}}",
"apihelp-watch-param-title": "{{doc-apihelp-param|watch|title}}",
"apihelp-watch-param-unwatch": "{{doc-apihelp-param|watch|unwatch}}",