MediaWiki
REL1_22
|
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 // Init session if necessary 00051 if ( session_id() == '' ) { 00052 wfSetupSession(); 00053 } 00054 00055 if ( $params['mailpassword'] && !$params['email'] ) { 00056 $this->dieUsageMsg( 'noemail' ); 00057 } 00058 00059 if ( $params['language'] && !Language::isSupportedLanguage( $params['language'] ) ) { 00060 $this->dieUsage( 'Invalid language parameter', 'langinvalid' ); 00061 } 00062 00063 $context = new DerivativeContext( $this->getContext() ); 00064 $context->setRequest( new DerivativeRequest( 00065 $this->getContext()->getRequest(), 00066 array( 00067 'type' => 'signup', 00068 'uselang' => $params['language'], 00069 'wpName' => $params['name'], 00070 'wpPassword' => $params['password'], 00071 'wpRetype' => $params['password'], 00072 'wpDomain' => $params['domain'], 00073 'wpEmail' => $params['email'], 00074 'wpRealName' => $params['realname'], 00075 'wpCreateaccountToken' => $params['token'], 00076 'wpCreateaccount' => $params['mailpassword'] ? null : '1', 00077 'wpCreateaccountMail' => $params['mailpassword'] ? '1' : null 00078 ) 00079 ) ); 00080 00081 $loginForm = new LoginForm(); 00082 $loginForm->setContext( $context ); 00083 $loginForm->load(); 00084 00085 $status = $loginForm->addNewaccountInternal(); 00086 $result = array(); 00087 if ( $status->isGood() ) { 00088 // Success! 00089 global $wgEmailAuthentication; 00090 $user = $status->getValue(); 00091 00092 if ( $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 $this->dieStatus( $status ); 00136 } elseif ( !$status->isGood() ) { 00137 // Status is not good, but OK. This means warnings. 00138 $result['result'] = 'warning'; 00139 00140 // Add any warnings to the result 00141 $warnings = $status->getErrorsByType( 'warning' ); 00142 if ( $warnings ) { 00143 foreach ( $warnings as &$warning ) { 00144 $apiResult->setIndexedTagName( $warning['params'], 'param' ); 00145 } 00146 $apiResult->setIndexedTagName( $warnings, 'warning' ); 00147 $result['warnings'] = $warnings; 00148 } 00149 } else { 00150 // Everything was fine. 00151 $result['result'] = 'success'; 00152 } 00153 00154 $apiResult->addValue( null, 'createaccount', $result ); 00155 } 00156 00157 public function getDescription() { 00158 return 'Create a new user account.'; 00159 } 00160 00161 public function mustBePosted() { 00162 return true; 00163 } 00164 00165 public function isReadMode() { 00166 return false; 00167 } 00168 00169 public function isWriteMode() { 00170 return true; 00171 } 00172 00173 public function getAllowedParams() { 00174 global $wgEmailConfirmToEdit; 00175 return array( 00176 'name' => array( 00177 ApiBase::PARAM_TYPE => 'user', 00178 ApiBase::PARAM_REQUIRED => true 00179 ), 00180 'password' => null, 00181 'domain' => null, 00182 'token' => null, 00183 'email' => array( 00184 ApiBase::PARAM_TYPE => 'string', 00185 ApiBase::PARAM_REQUIRED => $wgEmailConfirmToEdit 00186 ), 00187 'realname' => null, 00188 'mailpassword' => array( 00189 ApiBase::PARAM_TYPE => 'boolean', 00190 ApiBase::PARAM_DFLT => false 00191 ), 00192 'reason' => null, 00193 'language' => null 00194 ); 00195 } 00196 00197 public function getParamDescription() { 00198 $p = $this->getModulePrefix(); 00199 return array( 00200 'name' => 'Username', 00201 'password' => "Password (ignored if {$p}mailpassword is set)", 00202 'domain' => 'Domain for external authentication (optional)', 00203 'token' => 'Account creation token obtained in first request', 00204 'email' => 'Email address of user (optional)', 00205 'realname' => 'Real name of user (optional)', 00206 'mailpassword' => 'If set to any value, a random password will be emailed to the user', 00207 'reason' => 'Optional reason for creating the account to be put in the logs', 00208 'language' => 'Language code to set as default for the user (optional, defaults to content language)' 00209 ); 00210 } 00211 00212 public function getResultProperties() { 00213 return array( 00214 'createaccount' => array( 00215 'result' => array( 00216 ApiBase::PROP_TYPE => array( 00217 'success', 00218 'warning', 00219 'needtoken' 00220 ) 00221 ), 00222 'username' => array( 00223 ApiBase::PROP_TYPE => 'string', 00224 ApiBase::PROP_NULLABLE => true 00225 ), 00226 'userid' => array( 00227 ApiBase::PROP_TYPE => 'int', 00228 ApiBase::PROP_NULLABLE => true 00229 ), 00230 'token' => array( 00231 ApiBase::PROP_TYPE => 'string', 00232 ApiBase::PROP_NULLABLE => true 00233 ), 00234 ) 00235 ); 00236 } 00237 00238 public function getPossibleErrors() { 00239 // Note the following errors aren't possible and don't need to be listed: 00240 // sessionfailure, nocookiesfornew, badretype 00241 $localErrors = array( 00242 'wrongpassword', // Actually caused by wrong domain field. Riddle me that... 00243 'sorbs_create_account_reason', 00244 'noname', 00245 'userexists', 00246 'password-name-match', // from User::getPasswordValidity 00247 'password-login-forbidden', // from User::getPasswordValidity 00248 'noemailtitle', 00249 'invalidemailaddress', 00250 'externaldberror', 00251 'acct_creation_throttle_hit', 00252 ); 00253 00254 $errors = parent::getPossibleErrors(); 00255 // All local errors are from LoginForm, which means they're actually message keys. 00256 foreach ( $localErrors as $error ) { 00257 $errors[] = array( 'code' => $error, 'info' => wfMessage( $error )->inLanguage( 'en' )->useDatabase( false )->parse() ); 00258 } 00259 00260 $errors[] = array( 00261 'code' => 'permdenied-createaccount', 00262 'info' => 'You do not have the right to create a new account' 00263 ); 00264 $errors[] = array( 00265 'code' => 'blocked', 00266 'info' => 'You cannot create a new account because you are blocked' 00267 ); 00268 $errors[] = array( 00269 'code' => 'aborted', 00270 'info' => 'Account creation aborted by hook (info may vary)' 00271 ); 00272 $errors[] = array( 00273 'code' => 'langinvalid', 00274 'info' => 'Invalid language parameter' 00275 ); 00276 00277 // 'passwordtooshort' has parameters. :( 00278 global $wgMinimalPasswordLength; 00279 $errors[] = array( 00280 'code' => 'passwordtooshort', 00281 'info' => wfMessage( 'passwordtooshort', $wgMinimalPasswordLength )->inLanguage( 'en' )->useDatabase( false )->parse() 00282 ); 00283 return $errors; 00284 } 00285 00286 public function getExamples() { 00287 return array( 00288 'api.php?action=createaccount&name=testuser&password=test123', 00289 'api.php?action=createaccount&name=testmailuser&mailpassword=true&reason=MyReason', 00290 ); 00291 } 00292 00293 public function getHelpUrls() { 00294 return 'https://www.mediawiki.org/wiki/API:Account_creation'; 00295 } 00296 }