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