MediaWiki
REL1_23
|
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 }