MediaWiki  REL1_21
ApiCreateAccount.php
Go to the documentation of this file.
00001 <?php
00030 class ApiCreateAccount extends ApiBase {
00031         public function execute() {
00032                 // If we're in JSON callback mode, no tokens can be obtained
00033                 if ( !is_null( $this->getMain()->getRequest()->getVal( 'callback' ) ) ) {
00034                         $this->dieUsage( 'Cannot create account when using a callback', 'aborted' );
00035                 }
00036 
00037                 // $loginForm->addNewaccountInternal will throw exceptions
00038                 // if wiki is read only (already handled by api), user is blocked or does not have rights.
00039                 // Use userCan in order to hit GlobalBlock checks (according to Special:userlogin)
00040                 $loginTitle = SpecialPage::getTitleFor( 'Userlogin' );
00041                 if ( !$loginTitle->userCan( 'createaccount', $this->getUser() ) ) {
00042                         $this->dieUsage( 'You do not have the right to create a new account', 'permdenied-createaccount' );
00043                 }
00044                 if ( $this->getUser()->isBlockedFromCreateAccount() ) {
00045                         $this->dieUsage( 'You cannot create a new account because you are blocked', 'blocked' );
00046                 }
00047 
00048                 $params = $this->extractRequestParams();
00049 
00050                 $result = array();
00051 
00052                 // Init session if necessary
00053                 if ( session_id() == '' ) {
00054                         wfSetupSession();
00055                 }
00056 
00057                 if( $params['mailpassword'] && !$params['email'] ) {
00058                         $this->dieUsageMsg( 'noemail' );
00059                 }
00060 
00061                 $context = new DerivativeContext( $this->getContext() );
00062                 $context->setRequest( new DerivativeRequest(
00063                         $this->getContext()->getRequest(),
00064                         array(
00065                                 'type' => 'signup',
00066                                 'uselang' => $params['language'],
00067                                 'wpName' => $params['name'],
00068                                 'wpPassword' => $params['password'],
00069                                 'wpRetype' => $params['password'],
00070                                 'wpDomain' => $params['domain'],
00071                                 'wpEmail' => $params['email'],
00072                                 'wpRealName' => $params['realname'],
00073                                 'wpCreateaccountToken' => $params['token'],
00074                                 'wpCreateaccount' => $params['mailpassword'] ? null : '1',
00075                                 'wpCreateaccountMail' => $params['mailpassword'] ? '1' : null
00076                         )
00077                 ) );
00078 
00079                 $loginForm = new LoginForm();
00080                 $loginForm->setContext( $context );
00081                 $loginForm->load();
00082 
00083                 $status = $loginForm->addNewaccountInternal();
00084                 $result = array();
00085                 if( $status->isGood() ) {
00086                         // Success!
00087                         $user = $status->getValue();
00088 
00089                         // If we showed up language selection links, and one was in use, be
00090                         // smart (and sensible) and save that language as the user's preference
00091                         global $wgLoginLanguageSelector, $wgEmailAuthentication;
00092                         if( $wgLoginLanguageSelector && $params['language'] ) {
00093                                 $user->setOption( 'language', $params['language'] );
00094                         }
00095 
00096                         if( $params['mailpassword'] ) {
00097                                 // If mailpassword was set, disable the password and send an email.
00098                                 $user->setPassword( null );
00099                                 $status->merge( $loginForm->mailPasswordInternal( $user, false, 'createaccount-title', 'createaccount-text' ) );
00100                         } elseif( $wgEmailAuthentication && Sanitizer::validateEmail( $user->getEmail() ) ) {
00101                                 // Send out an email authentication message if needed
00102                                 $status->merge( $user->sendConfirmationMail() );
00103                         }
00104 
00105                         // Save settings (including confirmation token)
00106                         $user->saveSettings();
00107 
00108                         wfRunHooks( 'AddNewAccount', array( $user, $params['mailpassword'] ) );
00109 
00110                         if ( $params['mailpassword'] ) {
00111                                 $logAction = 'byemail';
00112                         } elseif ( $this->getUser()->isLoggedIn() ) {
00113                                 $logAction = 'create2';
00114                         } else {
00115                                 $logAction = 'create';
00116                         }
00117                         $user->addNewUserLogEntry( $logAction, (string)$params['reason'] );
00118 
00119                         // Add username, id, and token to result.
00120                         $result['username'] = $user->getName();
00121                         $result['userid'] = $user->getId();
00122                         $result['token'] = $user->getToken();
00123                 }
00124 
00125                 $apiResult = $this->getResult();
00126 
00127                 if( $status->hasMessage( 'sessionfailure' ) || $status->hasMessage( 'nocookiesfornew' ) ) {
00128                         // Token was incorrect, so add it to result, but don't throw an exception
00129                         // since not having the correct token is part of the normal
00130                         // flow of events.
00131                         $result['token'] = LoginForm::getCreateaccountToken();
00132                         $result['result'] = 'needtoken';
00133                 } elseif( !$status->isOK() ) {
00134                         // There was an error. Die now.
00135                         // Cannot use dieUsageMsg() directly because extensions
00136                         // might return custom error messages.
00137                         $errors = $status->getErrorsArray();
00138                         if( $errors[0] instanceof Message ) {
00139                                 $code = 'aborted';
00140                                 $desc = $errors[0];
00141                         } else {
00142                                 $code = array_shift( $errors[0] );
00143                                 $desc = wfMessage( $code, $errors[0] );
00144                         }
00145                         $this->dieUsage( $desc, $code );
00146                 } elseif( !$status->isGood() ) {
00147                         // Status is not good, but OK. This means warnings.
00148                         $result['result'] = 'warning';
00149 
00150                         // Add any warnings to the result
00151                         $warnings = $status->getErrorsByType( 'warning' );
00152                         if( $warnings ) {
00153                                 foreach( $warnings as &$warning ) {
00154                                         $apiResult->setIndexedTagName( $warning['params'], 'param' );
00155                                 }
00156                                 $apiResult->setIndexedTagName( $warnings, 'warning' );
00157                                 $result['warnings'] = $warnings;
00158                         }
00159                 } else {
00160                         // Everything was fine.
00161                         $result['result'] = 'success';
00162                 }
00163 
00164                 $apiResult->addValue( null, 'createaccount', $result );
00165         }
00166 
00167         public function getDescription() {
00168                 return 'Create a new user account.';
00169         }
00170 
00171         public function mustBePosted() {
00172                 return true;
00173         }
00174 
00175         public function isReadMode() {
00176                 return false;
00177         }
00178 
00179         public function isWriteMode() {
00180                 return true;
00181         }
00182 
00183         public function getAllowedParams() {
00184                 global $wgEmailConfirmToEdit;
00185                 return array(
00186                         'name' => array(
00187                                 ApiBase::PARAM_TYPE => 'user',
00188                                 ApiBase::PARAM_REQUIRED => true
00189                         ),
00190                         'password' => null,
00191                         'domain' => null,
00192                         'token' => null,
00193                         'email' => array(
00194                                 ApiBase::PARAM_TYPE => 'string',
00195                                 ApiBase::PARAM_REQUIRED => $wgEmailConfirmToEdit
00196                         ),
00197                         'realname' => null,
00198                         'mailpassword' => array(
00199                                 ApiBase::PARAM_TYPE => 'boolean',
00200                                 ApiBase::PARAM_DFLT => false
00201                         ),
00202                         'reason' => null,
00203                         'language' => null
00204                 );
00205         }
00206 
00207         public function getParamDescription() {
00208                 $p = $this->getModulePrefix();
00209                 return array(
00210                         'name' => 'Username',
00211                         'password' => "Password (ignored if {$p}mailpassword is set)",
00212                         'domain' => 'Domain for external authentication (optional)',
00213                         'token' => 'Account creation token obtained in first request',
00214                         'email' => 'Email address of user (optional)',
00215                         'realname' => 'Real name of user (optional)',
00216                         'mailpassword' => 'If set to any value, a random password will be emailed to the user',
00217                         'reason' => 'Optional reason for creating the account to be put in the logs',
00218                         'language' => 'Language code to set as default for the user (optional, defaults to content language)'
00219                 );
00220         }
00221 
00222         public function getResultProperties() {
00223                 return array(
00224                         'createaccount' => array(
00225                                 'result' => array(
00226                                         ApiBase::PROP_TYPE => array(
00227                                                 'success',
00228                                                 'warning',
00229                                                 'needtoken'
00230                                         )
00231                                 ),
00232                                 'username' => array(
00233                                         ApiBase::PROP_TYPE => 'string',
00234                                         ApiBase::PROP_NULLABLE => true
00235                                 ),
00236                                 'userid' => array(
00237                                         ApiBase::PROP_TYPE => 'int',
00238                                         ApiBase::PROP_NULLABLE => true
00239                                 ),
00240                                 'token' => array(
00241                                         ApiBase::PROP_TYPE => 'string',
00242                                         ApiBase::PROP_NULLABLE => true
00243                                 ),
00244                         )
00245                 );
00246         }
00247 
00248         public function getPossibleErrors() {
00249                 // Note the following errors aren't possible and don't need to be listed:
00250                 // sessionfailure, nocookiesfornew, badretype
00251                 $localErrors = array(
00252                         'wrongpassword', // Actually caused by wrong domain field. Riddle me that...
00253                         'sorbs_create_account_reason',
00254                         'noname',
00255                         'userexists',
00256                         'password-name-match', // from User::getPasswordValidity
00257                         'password-login-forbidden', // from User::getPasswordValidity
00258                         'noemailtitle',
00259                         'invalidemailaddress',
00260                         'externaldberror',
00261                         'acct_creation_throttle_hit',
00262                 );
00263 
00264                 $errors = parent::getPossibleErrors();
00265                 // All local errors are from LoginForm, which means they're actually message keys.
00266                 foreach( $localErrors as $error ) {
00267                         $errors[] = array( 'code' => $error, 'info' => wfMessage( $error )->parse() );
00268                 }
00269 
00270                 $errors[] = array(
00271                         'code' => 'permdenied-createaccount',
00272                         'info' => 'You do not have the right to create a new account'
00273                 );
00274                 $errors[] = array(
00275                         'code' => 'blocked',
00276                         'info' => 'You cannot create a new account because you are blocked'
00277                 );
00278                 $errors[] = array(
00279                         'code' => 'aborted',
00280                         'info' => 'Account creation aborted by hook (info may vary)'
00281                 );
00282 
00283                 // 'passwordtooshort' has parameters. :(
00284                 global $wgMinimalPasswordLength;
00285                 $errors[] = array(
00286                         'code' => 'passwordtooshort',
00287                         'info' => wfMessage( 'passwordtooshort', $wgMinimalPasswordLength )->parse()
00288                 );
00289                 return $errors;
00290         }
00291 
00292         public function getExamples() {
00293                 return array(
00294                         'api.php?action=createaccount&name=testuser&password=test123',
00295                         'api.php?action=createaccount&name=testmailuser&mailpassword=true&reason=MyReason',
00296                 );
00297         }
00298 
00299         public function getHelpUrls() {
00300                 return 'https://www.mediawiki.org/wiki/API:Account_creation';
00301         }
00302 }