If you made a request to action=createaccount and this was the first time (so no account creation token had yet been generated for you) a "nocookiesfornew" error was returned. This is incorrect, what is supposed to happen in that case is the api returns what token to use. This is how users are supposed to request tokens, so the issue is very confusing. No release notes since this module was introduced in this version. Also removed sessionfailure from possible errors, as it isn't one (that status triggers the needtoken result). Change-Id: Ibfc3879fa89b1e11303aef65feb45a91afc215e6
270 lines
7.8 KiB
PHP
270 lines
7.8 KiB
PHP
<?php
|
|
/**
|
|
* Created on August 7, 2012
|
|
*
|
|
* Copyright © 2012 Tyler Romeo <tylerromeo@gmail.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
*
|
|
* @file
|
|
*/
|
|
|
|
/**
|
|
* Unit to authenticate account registration attempts to the current wiki.
|
|
*
|
|
* @ingroup API
|
|
*/
|
|
class ApiCreateAccount extends ApiBase {
|
|
public function execute() {
|
|
$params = $this->extractRequestParams();
|
|
|
|
$result = array();
|
|
|
|
// Init session if necessary
|
|
if ( session_id() == '' ) {
|
|
wfSetupSession();
|
|
}
|
|
|
|
if( $params['mailpassword'] && !$params['email'] ) {
|
|
$this->dieUsageMsg( 'noemail' );
|
|
}
|
|
|
|
$context = new DerivativeContext( $this->getContext() );
|
|
$context->setRequest( new DerivativeRequest(
|
|
$this->getContext()->getRequest(),
|
|
array(
|
|
'type' => 'signup',
|
|
'uselang' => $params['language'],
|
|
'wpName' => $params['name'],
|
|
'wpPassword' => $params['password'],
|
|
'wpRetype' => $params['password'],
|
|
'wpDomain' => $params['domain'],
|
|
'wpEmail' => $params['email'],
|
|
'wpRealName' => $params['realname'],
|
|
'wpCreateaccountToken' => $params['token'],
|
|
'wpCreateaccount' => $params['mailpassword'] ? null : '1',
|
|
'wpCreateaccountMail' => $params['mailpassword'] ? '1' : null
|
|
)
|
|
) );
|
|
|
|
$loginForm = new LoginForm();
|
|
$loginForm->setContext( $context );
|
|
$loginForm->load();
|
|
|
|
$status = $loginForm->addNewaccountInternal();
|
|
$result = array();
|
|
if( $status->isGood() ) {
|
|
// Success!
|
|
$user = $status->getValue();
|
|
|
|
// If we showed up language selection links, and one was in use, be
|
|
// smart (and sensible) and save that language as the user's preference
|
|
global $wgLoginLanguageSelector, $wgEmailAuthentication;
|
|
if( $wgLoginLanguageSelector && $params['language'] ) {
|
|
$user->setOption( 'language', $params['language'] );
|
|
}
|
|
|
|
if( $params['mailpassword'] ) {
|
|
// If mailpassword was set, disable the password and send an email.
|
|
$user->setPassword( null );
|
|
$status->merge( $loginForm->mailPasswordInternal( $user, false, 'createaccount-title', 'createaccount-text' ) );
|
|
} elseif( $wgEmailAuthentication && Sanitizer::validateEmail( $user->getEmail() ) ) {
|
|
// Send out an email authentication message if needed
|
|
$status->merge( $user->sendConfirmationMail() );
|
|
}
|
|
|
|
// Save settings (including confirmation token)
|
|
$user->saveSettings();
|
|
|
|
wfRunHooks( 'AddNewAccount', array( $user, $params['mailpassword'] ) );
|
|
|
|
if ( $params['mailpassword'] ) {
|
|
$logAction = 'byemail';
|
|
} elseif ( $this->getUser()->isLoggedIn() ) {
|
|
$logAction = 'create2';
|
|
} else {
|
|
$logAction = 'create';
|
|
}
|
|
$user->addNewUserLogEntry( $logAction, (string)$params['reason'] );
|
|
|
|
// Add username, id, and token to result.
|
|
$result['username'] = $user->getName();
|
|
$result['userid'] = $user->getId();
|
|
$result['token'] = $user->getToken();
|
|
}
|
|
|
|
$apiResult = $this->getResult();
|
|
|
|
if( $status->hasMessage( 'sessionfailure' ) || $status->hasMessage( 'nocookiesfornew' ) ) {
|
|
// Token was incorrect, so add it to result, but don't throw an exception
|
|
// since not having the correct token is part of the normal
|
|
// flow of events.
|
|
$result['token'] = LoginForm::getCreateaccountToken();
|
|
$result['result'] = 'needtoken';
|
|
} elseif( !$status->isOK() ) {
|
|
// There was an error. Die now.
|
|
// Cannot use dieUsageMsg() directly because extensions
|
|
// might return custom error messages.
|
|
$errors = $status->getErrorsArray();
|
|
if( $errors[0] instanceof Message ) {
|
|
$code = 'aborted';
|
|
$desc = $errors[0];
|
|
} else {
|
|
$code = array_shift( $errors[0] );
|
|
$desc = wfMessage( $code, $errors[0] );
|
|
}
|
|
$this->dieUsage( $desc, $code );
|
|
} elseif( !$status->isGood() ) {
|
|
// Status is not good, but OK. This means warnings.
|
|
$result['result'] = 'warning';
|
|
|
|
// Add any warnings to the result
|
|
$warnings = $status->getErrorsByType( 'warning' );
|
|
if( $warnings ) {
|
|
foreach( $warnings as &$warning ) {
|
|
$apiResult->setIndexedTagName( $warning['params'], 'param' );
|
|
}
|
|
$apiResult->setIndexedTagName( $warnings, 'warning' );
|
|
$result['warnings'] = $warnings;
|
|
}
|
|
} else {
|
|
// Everything was fine.
|
|
$result['result'] = 'success';
|
|
}
|
|
|
|
$apiResult->addValue( null, 'createaccount', $result );
|
|
}
|
|
|
|
public function getDescription() {
|
|
return 'Create a new user account.';
|
|
}
|
|
|
|
public function mustBePosted() {
|
|
return true;
|
|
}
|
|
|
|
public function isReadMode() {
|
|
return false;
|
|
}
|
|
|
|
public function isWriteMode() {
|
|
return true;
|
|
}
|
|
|
|
public function getAllowedParams() {
|
|
global $wgEmailConfirmToEdit;
|
|
return array(
|
|
'name' => array(
|
|
ApiBase::PARAM_TYPE => 'user',
|
|
ApiBase::PARAM_REQUIRED => true
|
|
),
|
|
'password' => null,
|
|
'domain' => null,
|
|
'token' => null,
|
|
'email' => array(
|
|
ApiBase::PARAM_TYPE => 'string',
|
|
ApiBase::PARAM_REQUIRED => $wgEmailConfirmToEdit
|
|
),
|
|
'realname' => null,
|
|
'mailpassword' => array(
|
|
ApiBase::PARAM_TYPE => 'boolean',
|
|
ApiBase::PARAM_DFLT => false
|
|
),
|
|
'reason' => null,
|
|
'language' => null
|
|
);
|
|
}
|
|
|
|
public function getParamDescription() {
|
|
$p = $this->getModulePrefix();
|
|
return array(
|
|
'name' => 'Username',
|
|
'password' => "Password (ignored if {$p}mailpassword is set)",
|
|
'domain' => 'Domain for external authentication (optional)',
|
|
'token' => 'Account creation token obtained in first request',
|
|
'email' => 'Email address of user (optional)',
|
|
'realname' => 'Real name of user (optional)',
|
|
'mailpassword' => 'If set to any value, a random password will be emailed to the user',
|
|
'reason' => 'Optional reason for creating the account to be put in the logs',
|
|
'language' => 'Language code to set as default for the user (optional, defaults to content language)'
|
|
);
|
|
}
|
|
|
|
public function getResultProperties() {
|
|
return array(
|
|
'createaccount' => array(
|
|
'result' => array(
|
|
ApiBase::PROP_TYPE => array(
|
|
'success',
|
|
'warning',
|
|
'needtoken'
|
|
)
|
|
),
|
|
'username' => array(
|
|
ApiBase::PROP_TYPE => 'string',
|
|
ApiBase::PROP_NULLABLE => true
|
|
),
|
|
'userid' => array(
|
|
ApiBase::PROP_TYPE => 'int',
|
|
ApiBase::PROP_NULLABLE => true
|
|
),
|
|
'token' => array(
|
|
ApiBase::PROP_TYPE => 'string',
|
|
ApiBase::PROP_NULLABLE => true
|
|
),
|
|
)
|
|
);
|
|
}
|
|
|
|
public function getPossibleErrors() {
|
|
$localErrors = array(
|
|
'wrongpassword',
|
|
'sorbs_create_account_reason',
|
|
'noname',
|
|
'userexists',
|
|
'password-name-match',
|
|
'password-login-forbidden',
|
|
'noemailtitle',
|
|
'invalidemailaddress',
|
|
'externaldberror'
|
|
);
|
|
|
|
$errors = parent::getPossibleErrors();
|
|
// All local errors are from LoginForm, which means they're actually message keys.
|
|
foreach( $localErrors as $error ) {
|
|
$errors[] = array( 'code' => $error, 'info' => wfMessage( $error )->parse() );
|
|
}
|
|
|
|
// 'passwordtooshort' has parameters. :(
|
|
global $wgMinimalPasswordLength;
|
|
$errors[] = array(
|
|
'code' => 'passwordtooshort',
|
|
'info' => wfMessage( 'passwordtooshort', $wgMinimalPasswordLength )->parse()
|
|
);
|
|
return $errors;
|
|
}
|
|
|
|
public function getExamples() {
|
|
return array(
|
|
'api.php?action=createaccount&name=testuser&password=test123',
|
|
'api.php?action=createaccount&name=testmailuser&mailpassword=true&reason=MyReason',
|
|
);
|
|
}
|
|
|
|
public function getHelpUrls() {
|
|
return 'https://www.mediawiki.org/wiki/API:Account_creation';
|
|
}
|
|
}
|