Index: branches/happy-melon/phase3/includes/User.php |
— | — | @@ -2483,7 +2483,7 @@ |
2484 | 2484 | $user = new User; |
2485 | 2485 | $user->load(); |
2486 | 2486 | if ( isset( $params['options'] ) ) { |
2487 | | - $user->mOptions = $params['options'] + $user->mOptions; |
| 2487 | + $user->mOptions = $params['options'] + (array)$user->mOptions; |
2488 | 2488 | unset( $params['options'] ); |
2489 | 2489 | } |
2490 | 2490 | $dbw = wfGetDB( DB_MASTER ); |
Index: branches/happy-melon/phase3/includes/api/ApiLogin.php |
— | — | @@ -106,10 +106,10 @@ |
107 | 107 | case Login::THROTTLED : |
108 | 108 | global $wgPasswordAttemptThrottle; |
109 | 109 | $result['result'] = 'Throttled'; |
110 | | - $result['wait'] = intval($wgPasswordAttemptThrottle['seconds']); |
| 110 | + $result['wait'] = intval( $wgPasswordAttemptThrottle['seconds'] ); |
111 | 111 | break; |
112 | 112 | default : |
113 | | - ApiBase::dieDebug(__METHOD__, "Unhandled case value: {$authRes}"); |
| 113 | + ApiBase::dieDebug( __METHOD__, "Unhandled case value: {$authRes}" ); |
114 | 114 | } |
115 | 115 | |
116 | 116 | $this->getResult()->addValue(null, 'login', $result); |
Index: branches/happy-melon/phase3/includes/Login.php |
— | — | @@ -14,25 +14,41 @@ |
15 | 15 | const EMPTY_PASS = 6; |
16 | 16 | const RESET_PASS = 7; |
17 | 17 | const ABORTED = 8; |
18 | | - const CREATE_BLOCKED = 9; |
19 | 18 | const THROTTLED = 10; |
| 19 | + const FAILED = 11; |
| 20 | + const READ_ONLY = 12; |
20 | 21 | |
21 | | - const MAIL_READ_ONLY = 11; |
22 | | - const MAIL_PASSCHANGE_FORBIDDEN = 12; |
23 | | - const MAIL_BLOCKED = 13; |
24 | | - const MAIL_PING_THROTTLED = 14; |
25 | | - const MAIL_PASS_THROTTLED = 15; |
26 | | - const MAIL_EMPTY_EMAIL = 16; |
27 | | - const MAIL_BAD_IP = 17; |
28 | | - const MAIL_ERROR = 18; |
| 22 | + const MAIL_PASSCHANGE_FORBIDDEN = 21; |
| 23 | + const MAIL_BLOCKED = 22; |
| 24 | + const MAIL_PING_THROTTLED = 23; |
| 25 | + const MAIL_PASS_THROTTLED = 24; |
| 26 | + const MAIL_EMPTY_EMAIL = 25; |
| 27 | + const MAIL_BAD_IP = 26; |
| 28 | + const MAIL_ERROR = 27; |
| 29 | + |
| 30 | + const CREATE_BLOCKED = 40; |
| 31 | + const CREATE_EXISTS = 41; |
| 32 | + const CREATE_SORBS = 42; |
| 33 | + const CREATE_BADDOMAIN = 43; |
| 34 | + const CREATE_BADNAME = 44; |
| 35 | + const CREATE_BADPASS = 45; |
| 36 | + const CREATE_NEEDEMAIL = 46; |
| 37 | + const CREATE_BADEMAIL = 47; |
29 | 38 | |
30 | | - var $mName, $mPassword, $mPosted; |
31 | | - var $mLoginattempt, $mRemember, $mEmail, $mDomain, $mLanguage; |
| 39 | + protected $mName; |
| 40 | + protected $mPassword; |
| 41 | + public $mRemember; # 0 or 1 |
| 42 | + public $mEmail; |
| 43 | + public $mDomain; |
| 44 | + public $mRealname; |
32 | 45 | |
33 | 46 | private $mExtUser = null; |
34 | 47 | |
35 | 48 | public $mUser; |
36 | | - public $mMailResult; |
| 49 | + |
| 50 | + public $mLoginResult = ''; |
| 51 | + public $mMailResult = ''; |
| 52 | + public $mCreateResult = ''; |
37 | 53 | |
38 | 54 | /** |
39 | 55 | * Constructor |
— | — | @@ -46,8 +62,7 @@ |
47 | 63 | $this->mName = $request->getText( 'wpName' ); |
48 | 64 | $this->mPassword = $request->getText( 'wpPassword' ); |
49 | 65 | $this->mDomain = $request->getText( 'wpDomain' ); |
50 | | - $this->mPosted = $request->wasPosted(); |
51 | | - $this->mRemember = $request->getCheck( 'wpRemember' ); |
| 66 | + $this->mRemember = $request->getCheck( 'wpRemember' ) ? 1 : 0; |
52 | 67 | |
53 | 68 | if( $wgEnableEmail ) { |
54 | 69 | $this->mEmail = $request->getText( 'wpEmail' ); |
— | — | @@ -65,57 +80,28 @@ |
66 | 81 | } |
67 | 82 | $wgAuth->setDomain( $this->mDomain ); |
68 | 83 | |
69 | | - # Attempt to generate the User |
70 | | - $this->mUser = User::newFromName( $this->mName ); |
| 84 | + # Load the user, if they exist in the local database. |
| 85 | + $this->mUser = User::newFromName( trim( $this->mName ), 'usable' ); |
71 | 86 | } |
72 | | - |
| 87 | + |
73 | 88 | /** |
74 | | - * Actually add a user to the database. |
75 | | - * Give it a User object that has been initialised with a name. |
76 | | - * |
77 | | - * @param $u User object. |
78 | | - * @param $autocreate boolean -- true if this is an autocreation via auth plugin |
79 | | - * @return User object. |
| 89 | + * Having initialised the Login object with (at least) the wpName |
| 90 | + * and wpPassword pair, attempt to authenticate the user and log |
| 91 | + * them into the wiki. Authentication may come from the local |
| 92 | + * user database, or from an AuthPlugin- or ExternalUser-based |
| 93 | + * foreign database; in the latter case, a local user record may |
| 94 | + * or may not be created and initialised. |
| 95 | + * @return a Login class constant representing the status. |
80 | 96 | */ |
81 | | - public function initUser( $autocreate ) { |
82 | | - global $wgAuth; |
83 | | - |
84 | | - $this->mUser->addToDatabase(); |
85 | | - |
86 | | - if ( $wgAuth->allowPasswordChange() ) { |
87 | | - $this->mUser->setPassword( $this->mPassword ); |
88 | | - } |
89 | | - |
90 | | - $this->mUser->setEmail( $this->mEmail ); |
91 | | - $this->mUser->setRealName( $this->mRealName ); |
92 | | - $this->mUser->setToken(); |
93 | | - |
94 | | - $wgAuth->initUser( $this->mUser, $autocreate ); |
95 | | - |
96 | | - if( $this->mExtUser ) { |
97 | | - $this->mExtUser->link( $this->mUser->getId() ); |
98 | | - $email = $this->mExtUser->getPref( 'emailaddress' ); |
99 | | - if( $email && !$this->mEmail ) { |
100 | | - $this->mUser->setEmail( $email ); |
101 | | - } |
102 | | - } |
103 | | - |
104 | | - $this->mUser->setOption( 'rememberpassword', $this->mRemember ? 1 : 0 ); |
105 | | - $this->mUser->saveSettings(); |
106 | | - |
107 | | - # Update user count |
108 | | - $ssUpdate = new SiteStatsUpdate( 0, 0, 0, 0, 1 ); |
109 | | - $ssUpdate->doUpdate(); |
110 | | - |
111 | | - return $this->mUser; |
112 | | - } |
113 | | - |
114 | 97 | public function attemptLogin(){ |
115 | 98 | global $wgUser; |
| 99 | + |
116 | 100 | $code = $this->authenticateUserData(); |
117 | | - if( !$code == self::SUCCESS ){ |
| 101 | + if( $code != self::SUCCESS ){ |
118 | 102 | return $code; |
119 | 103 | } |
| 104 | + |
| 105 | + # Log the user in and remember them if they asked for that. |
120 | 106 | if( (bool)$this->mRemember != (bool)$wgUser->getOption( 'rememberpassword' ) ) { |
121 | 107 | $wgUser->setOption( 'rememberpassword', $this->mRemember ? 1 : 0 ); |
122 | 108 | $wgUser->saveSettings(); |
— | — | @@ -124,32 +110,76 @@ |
125 | 111 | } |
126 | 112 | $wgUser->setCookies(); |
127 | 113 | |
128 | | - # Reset the throttle |
| 114 | + # Reset the password throttle |
129 | 115 | $key = wfMemcKey( 'password-throttle', wfGetIP(), md5( $this->mName ) ); |
130 | 116 | global $wgMemc; |
131 | 117 | $wgMemc->delete( $key ); |
132 | 118 | |
133 | | - $injected_html = ''; |
134 | | - wfRunHooks('UserLoginComplete', array(&$wgUser, &$injected_html)); |
| 119 | + wfRunHooks( 'UserLoginComplete', array( &$wgUser, &$this->mLoginResult ) ); |
135 | 120 | |
136 | 121 | return self::SUCCESS; |
137 | 122 | } |
138 | 123 | |
139 | 124 | /** |
| 125 | + * Check whether there is an external authentication mechanism from |
| 126 | + * which we can automatically authenticate the user and create a |
| 127 | + * local account for them. |
| 128 | + * @return integer Status code. Login::SUCCESS == clear to proceed |
| 129 | + * with user creation. |
| 130 | + */ |
| 131 | + protected function canAutoCreate() { |
| 132 | + global $wgAuth, $wgUser, $wgAutocreatePolicy; |
| 133 | + |
| 134 | + if( $wgUser->isBlockedFromCreateAccount() ) { |
| 135 | + wfDebug( __METHOD__.": user is blocked from account creation\n" ); |
| 136 | + return self::CREATE_BLOCKED; |
| 137 | + } |
| 138 | + |
| 139 | + # If the external authentication plugin allows it, automatically |
| 140 | + # create a new account for users that are externally defined but |
| 141 | + # have not yet logged in. |
| 142 | + if( $this->mExtUser ) { |
| 143 | + # mExtUser is neither null nor false, so use the new |
| 144 | + # ExternalAuth system. |
| 145 | + if( $wgAutocreatePolicy == 'never' ) { |
| 146 | + return self::NOT_EXISTS; |
| 147 | + } |
| 148 | + if( !$this->mExtUser->authenticate( $this->mPassword ) ) { |
| 149 | + return self::WRONG_PLUGIN_PASS; |
| 150 | + } |
| 151 | + } else { |
| 152 | + # Old AuthPlugin. |
| 153 | + if( !$wgAuth->autoCreate() ) { |
| 154 | + return self::NOT_EXISTS; |
| 155 | + } |
| 156 | + if( !$wgAuth->userExists( $this->mUser->getName() ) ) { |
| 157 | + wfDebug( __METHOD__.": user does not exist\n" ); |
| 158 | + return self::NOT_EXISTS; |
| 159 | + } |
| 160 | + if( !$wgAuth->authenticate( $this->mUser->getName(), $this->mPassword ) ) { |
| 161 | + wfDebug( __METHOD__.": \$wgAuth->authenticate() returned false, aborting\n" ); |
| 162 | + return self::WRONG_PLUGIN_PASS; |
| 163 | + } |
| 164 | + } |
| 165 | + |
| 166 | + return self::SUCCESS; |
| 167 | + } |
| 168 | + |
| 169 | + /** |
140 | 170 | * Internally authenticate the login request. |
141 | 171 | * |
142 | 172 | * This may create a local account as a side effect if the |
143 | 173 | * authentication plugin allows transparent local account |
144 | 174 | * creation. |
145 | 175 | */ |
146 | | - public function authenticateUserData() { |
| 176 | + protected function authenticateUserData() { |
147 | 177 | global $wgUser, $wgAuth; |
| 178 | + |
148 | 179 | if ( '' == $this->mName ) { |
149 | 180 | return self::NO_NAME; |
150 | 181 | } |
151 | 182 | |
152 | 183 | global $wgPasswordAttemptThrottle; |
153 | | - |
154 | 184 | $throttleCount = 0; |
155 | 185 | if ( is_array( $wgPasswordAttemptThrottle ) ) { |
156 | 186 | $throttleKey = wfMemcKey( 'password-throttle', wfGetIP(), md5( $this->mName ) ); |
— | — | @@ -159,7 +189,7 @@ |
160 | 190 | global $wgMemc; |
161 | 191 | $throttleCount = $wgMemc->get( $throttleKey ); |
162 | 192 | if ( !$throttleCount ) { |
163 | | - $wgMemc->add( $throttleKey, 1, $period ); // start counter |
| 193 | + $wgMemc->add( $throttleKey, 1, $period ); # Start counter |
164 | 194 | } else if ( $throttleCount < $count ) { |
165 | 195 | $wgMemc->incr($throttleKey); |
166 | 196 | } else if ( $throttleCount >= $count ) { |
— | — | @@ -167,8 +197,8 @@ |
168 | 198 | } |
169 | 199 | } |
170 | 200 | |
171 | | - # Load $wgUser now, and check to see if we're logging in as the same |
172 | | - # name. This is necessary because loading $wgUser (say by calling |
| 201 | + # Unstub $wgUser now, and check to see if we're logging in as the same |
| 202 | + # name. As well as the obvious, unstubbing $wgUser (say by calling |
173 | 203 | # getName()) calls the UserLoadFromSession hook, which potentially |
174 | 204 | # creates the user in the database. Until we load $wgUser, checking |
175 | 205 | # for user existence using User::newFromName($name)->getId() below |
— | — | @@ -186,15 +216,18 @@ |
187 | 217 | return self::ILLEGAL; |
188 | 218 | } |
189 | 219 | |
190 | | - $isAutoCreated = false; |
191 | | - if ( 0 == $this->mUser->getID() ) { |
192 | | - $status = $this->attemptAutoCreate( $this->mUser ); |
193 | | - if ( $status !== self::SUCCESS ) { |
194 | | - return $status; |
| 220 | + # If the user doesn't exist in the local database, our only chance |
| 221 | + # is for an external auth plugin to autocreate the local user. |
| 222 | + if ( $this->mUser->getID() == 0 ) { |
| 223 | + if ( $this->canAutoCreate() == self::SUCCESS ) { |
| 224 | + $isAutoCreated = true; |
| 225 | + wfDebug( __METHOD__.": creating account\n" ); |
| 226 | + $this->initUser( true ); |
195 | 227 | } else { |
196 | | - $isAutoCreated = true; |
| 228 | + return $this->canAutoCreate(); |
197 | 229 | } |
198 | 230 | } else { |
| 231 | + $isAutoCreated = false; |
199 | 232 | $this->mUser->load(); |
200 | 233 | } |
201 | 234 | |
— | — | @@ -231,7 +264,7 @@ |
232 | 265 | # etc will probably just fail cleanly here. |
233 | 266 | $retval = self::RESET_PASS; |
234 | 267 | } else { |
235 | | - $retval = '' == $this->mPassword ? self::EMPTY_PASS : self::WRONG_PASS; |
| 268 | + $retval = ( $this->mPassword === '' ) ? self::EMPTY_PASS : self::WRONG_PASS; |
236 | 269 | } |
237 | 270 | } else { |
238 | 271 | $wgAuth->updateUser( $this->mUser ); |
— | — | @@ -254,48 +287,200 @@ |
255 | 288 | } |
256 | 289 | |
257 | 290 | /** |
258 | | - * Attempt to automatically create a user on login. Only succeeds if there |
259 | | - * is an external authentication method which allows it. |
260 | | - * @return integer Status code |
| 291 | + * Actually add a user to the database. |
| 292 | + * Give it a User object that has been initialised with a name. |
| 293 | + * |
| 294 | + * @param $autocreate Bool is this is an autocreation from an external |
| 295 | + * authentication database? |
| 296 | + * @param $byEmail Bool is this request going to be handled by sending |
| 297 | + * the password by email? |
| 298 | + * @return Bool whether creation was successful (should only fail for |
| 299 | + * Db errors etc). |
261 | 300 | */ |
262 | | - public function attemptAutoCreate( $user ) { |
263 | | - global $wgAuth, $wgUser, $wgAutocreatePolicy; |
| 301 | + protected function initUser( $autocreate=false, $byEmail=false ) { |
| 302 | + global $wgAuth; |
264 | 303 | |
265 | | - if( $wgUser->isBlockedFromCreateAccount() ) { |
266 | | - wfDebug( __METHOD__.": user is blocked from account creation\n" ); |
267 | | - return self::CREATE_BLOCKED; |
| 304 | + $fields = array( |
| 305 | + 'name' => $this->mName, |
| 306 | + 'password' => $byEmail ? null : $this->mPassword, |
| 307 | + 'email' => $this->mEmail, |
| 308 | + 'options' => array( |
| 309 | + 'rememberpassword' => $this->mRemember ? 1 : 0, |
| 310 | + ), |
| 311 | + ); |
| 312 | + |
| 313 | + $this->mUser = User::createNew( $this->mName, $fields ); |
| 314 | + |
| 315 | + if( $this->mUser === null ){ |
| 316 | + return null; |
268 | 317 | } |
269 | 318 | |
270 | | - # If the external authentication plugin allows it, automatically cre- |
271 | | - # ate a new account for users that are externally defined but have not |
272 | | - # yet logged in. |
| 319 | + # Let old AuthPlugins play with the user |
| 320 | + $wgAuth->initUser( $this->mUser, $autocreate ); |
| 321 | + |
| 322 | + # Or new ExternalUser plugins |
273 | 323 | if( $this->mExtUser ) { |
274 | | - # mExtUser is neither null nor false, so use the new ExternalAuth |
275 | | - # system. |
276 | | - if( $wgAutocreatePolicy == 'never' ) { |
277 | | - return self::NOT_EXISTS; |
| 324 | + $this->mExtUser->link( $this->mUser->getId() ); |
| 325 | + $email = $this->mExtUser->getPref( 'emailaddress' ); |
| 326 | + if( $email && !$this->mEmail ) { |
| 327 | + $this->mUser->setEmail( $email ); |
278 | 328 | } |
279 | | - if( !$this->mExtUser->authenticate( $this->mPassword ) ) { |
280 | | - return self::WRONG_PLUGIN_PASS; |
| 329 | + } |
| 330 | + |
| 331 | + # Update user count and newuser logs |
| 332 | + $ssUpdate = new SiteStatsUpdate( 0, 0, 0, 0, 1 ); |
| 333 | + $ssUpdate->doUpdate(); |
| 334 | + if( $autocreate ) |
| 335 | + $this->mUser->addNewUserLogEntryAutoCreate(); |
| 336 | + else |
| 337 | + $this->mUser->addNewUserLogEntry( $byEmail ); |
| 338 | + |
| 339 | + # Run hooks |
| 340 | + wfRunHooks( 'AddNewAccount', array( $this->mUser ) ); |
| 341 | + |
| 342 | + return true; |
| 343 | + } |
| 344 | + |
| 345 | + /** |
| 346 | + * Entry point to create a new local account from user-supplied |
| 347 | + * data loaded from the WebRequest. We handle initialising the |
| 348 | + * email here because it's needed for some backend things; frontend |
| 349 | + * interfaces calling this should handle recording things like |
| 350 | + * preference options |
| 351 | + * @param $byEmail Bool whether to email the user their new password |
| 352 | + * @return Status code; Login::SUCCESS == the user was successfully created |
| 353 | + */ |
| 354 | + public function attemptCreation( $byEmail=false ) { |
| 355 | + global $wgUser, $wgOut; |
| 356 | + global $wgEnableSorbs, $wgProxyWhitelist; |
| 357 | + global $wgMemc, $wgAccountCreationThrottle; |
| 358 | + global $wgAuth; |
| 359 | + global $wgEmailAuthentication, $wgEmailConfirmToEdit; |
| 360 | + |
| 361 | + if( wfReadOnly() ) |
| 362 | + return self::READ_ONLY; |
| 363 | + |
| 364 | + # If the user passes an invalid domain, something is fishy |
| 365 | + if( !$wgAuth->validDomain( $this->mDomain ) ) { |
| 366 | + $this->mCreateResult = 'wrongpassword'; |
| 367 | + return self::CREATE_BADDOMAIN; |
| 368 | + } |
| 369 | + |
| 370 | + # If we are not allowing users to login locally, we should be checking |
| 371 | + # to see if the user is actually able to authenticate to the authenti- |
| 372 | + # cation server before they create an account (otherwise, they can |
| 373 | + # create a local account and login as any domain user). We only need |
| 374 | + # to check this for domains that aren't local. |
| 375 | + if( !in_array( $this->mDomain, array( 'local', '' ) ) |
| 376 | + && !$wgAuth->canCreateAccounts() |
| 377 | + && ( !$wgAuth->userExists( $this->mUsername ) |
| 378 | + || !$wgAuth->authenticate( $this->mUsername, $this->mPassword ) |
| 379 | + ) ) |
| 380 | + { |
| 381 | + $this->mCreateResult = 'wrongpassword'; |
| 382 | + return self::WRONG_PLUGIN_PASS; |
| 383 | + } |
| 384 | + |
| 385 | + $ip = wfGetIP(); |
| 386 | + if ( $wgEnableSorbs && !in_array( $ip, $wgProxyWhitelist ) && |
| 387 | + $wgUser->inSorbsBlacklist( $ip ) ) |
| 388 | + { |
| 389 | + $this->mCreateResult = 'sorbs_create_account_reason'; |
| 390 | + return self::CREATE_SORBS; |
| 391 | + } |
| 392 | + |
| 393 | + # Now create a dummy user ($user) and check if it is valid |
| 394 | + $name = trim( $this->mName ); |
| 395 | + $user = User::newFromName( $name, 'creatable' ); |
| 396 | + if ( is_null( $user ) ) { |
| 397 | + $this->mCreateResult = 'noname'; |
| 398 | + return self::CREATE_BADNAME; |
| 399 | + } |
| 400 | + |
| 401 | + if ( $this->mUser->idForName() != 0 ) { |
| 402 | + $this->mCreateResult = 'userexists'; |
| 403 | + return self::CREATE_EXISTS; |
| 404 | + } |
| 405 | + |
| 406 | + # Check that the password is acceptable, if we're actually |
| 407 | + # going to use it |
| 408 | + if( !$byEmail ){ |
| 409 | + $valid = $this->mUser->isValidPassword( $this->mPassword ); |
| 410 | + if ( $valid !== true ) { |
| 411 | + $this->mCreateResult = $valid; |
| 412 | + return self::CREATE_BADPASS; |
281 | 413 | } |
282 | | - } else { |
283 | | - # Old AuthPlugin. |
284 | | - if( !$wgAuth->autoCreate() ) { |
285 | | - return self::NOT_EXISTS; |
| 414 | + } |
| 415 | + |
| 416 | + # if you need a confirmed email address to edit, then obviously you |
| 417 | + # need an email address. Equally if we're going to send the password to it. |
| 418 | + if ( $wgEmailConfirmToEdit && empty( $this->mEmail ) || $byEmail ) { |
| 419 | + $this->mCreateResult = 'noemailcreate'; |
| 420 | + return self::CREATE_NEEDEMAIL; |
| 421 | + } |
| 422 | + |
| 423 | + if( !empty( $this->mEmail ) && !User::isValidEmailAddr( $this->mEmail ) ) { |
| 424 | + $this->mCreateResult = 'invalidemailaddress'; |
| 425 | + return self::CREATE_BADEMAIL; |
| 426 | + } |
| 427 | + |
| 428 | + # Set some additional data so the AbortNewAccount hook can be used for |
| 429 | + # more than just username validation |
| 430 | + $this->mUser->setEmail( $this->mEmail ); |
| 431 | + $this->mUser->setRealName( $this->mRealName ); |
| 432 | + |
| 433 | + if( !wfRunHooks( 'AbortNewAccount', array( $this->mUser, &$this->mCreateResult ) ) ) { |
| 434 | + # Hook point to add extra creation throttles and blocks |
| 435 | + wfDebug( "LoginForm::addNewAccountInternal: a hook blocked creation\n" ); |
| 436 | + return self::ABORTED; |
| 437 | + } |
| 438 | + |
| 439 | + if ( $wgAccountCreationThrottle && $wgUser->isPingLimitable() ) { |
| 440 | + $key = wfMemcKey( 'acctcreate', 'ip', $ip ); |
| 441 | + $value = $wgMemc->get( $key ); |
| 442 | + if ( !$value ) { |
| 443 | + $wgMemc->set( $key, 0, 86400 ); |
286 | 444 | } |
287 | | - if( !$wgAuth->userExists( $user->getName() ) ) { |
288 | | - wfDebug( __METHOD__.": user does not exist\n" ); |
289 | | - return self::NOT_EXISTS; |
| 445 | + if ( $value >= $wgAccountCreationThrottle ) { |
| 446 | + return self::THROTTLED; |
290 | 447 | } |
291 | | - if( !$wgAuth->authenticate( $user->getName(), $this->mPassword ) ) { |
292 | | - wfDebug( __METHOD__.": \$wgAuth->authenticate() returned false, aborting\n" ); |
293 | | - return self::WRONG_PLUGIN_PASS; |
| 448 | + $wgMemc->incr( $key ); |
| 449 | + } |
| 450 | + |
| 451 | + # Since we're creating a new local user, give the external |
| 452 | + # database a chance to synchronise. |
| 453 | + if( !$wgAuth->addUser( $this->mUser, $this->mPassword, $this->mEmail, $this->mRealName ) ) { |
| 454 | + $this->mCreateResult = 'externaldberror'; |
| 455 | + return self::ABORTED; |
| 456 | + } |
| 457 | + |
| 458 | + $result = $this->initUser( false, $byEmail ); |
| 459 | + if( $result === null ) |
| 460 | + # It's unlikely we'd get here without some exception |
| 461 | + # being thrown, but it's probably possible... |
| 462 | + return self::FAILED; |
| 463 | + |
| 464 | + |
| 465 | + # Send out an email message if needed |
| 466 | + if( $byEmail ){ |
| 467 | + $this->mailPassword( 'createaccount-title', 'createaccount-text' ); |
| 468 | + if( WikiError::isError( $this->mMailResult ) ){ |
| 469 | + # FIXME: If the password email hasn't gone out, |
| 470 | + # then the account is inaccessible :( |
| 471 | + return self::MAIL_ERROR; |
| 472 | + } else { |
| 473 | + return self::SUCCESS; |
294 | 474 | } |
| 475 | + } else { |
| 476 | + if( $wgEmailAuthentication && User::isValidEmailAddr( $this->mUser->getEmail() ) ) |
| 477 | + { |
| 478 | + $this->mMailResult = $this->mUser->sendConfirmationMail(); |
| 479 | + return WikiError::isError( $this->mMailResult ) |
| 480 | + ? self::MAIL_ERROR |
| 481 | + : self::SUCCESS; |
| 482 | + } |
295 | 483 | } |
296 | | - |
297 | | - wfDebug( __METHOD__.": creating account\n" ); |
298 | | - $this->initUser( true ); |
299 | | - return self::SUCCESS; |
| 484 | + return true; |
300 | 485 | } |
301 | 486 | |
302 | 487 | /** |
— | — | @@ -308,8 +493,11 @@ |
309 | 494 | global $wgUser, $wgOut, $wgAuth, $wgServer, $wgScript, $wgNewPasswordExpiry; |
310 | 495 | |
311 | 496 | if( wfReadOnly() ) |
312 | | - return self::MAIL_READ_ONLY; |
| 497 | + return self::READ_ONLY; |
313 | 498 | |
| 499 | + # If we let the email go out, it will take users to a form where |
| 500 | + # they are forced to change their password, so don't let us go |
| 501 | + # there if we don't want passwords changed. |
314 | 502 | if( !$wgAuth->allowPasswordChange() ) |
315 | 503 | return self::MAIL_PASSCHANGE_FORBIDDEN; |
316 | 504 | |
— | — | @@ -319,23 +507,22 @@ |
320 | 508 | return self::MAIL_BLOCKED; |
321 | 509 | |
322 | 510 | # Check for hooks |
323 | | - $error = null; |
324 | | - if ( ! wfRunHooks( 'UserLoginMailPassword', array( $this->mName, &$error ) ) ) |
325 | | - return $error; |
| 511 | + if( !wfRunHooks( 'UserLoginMailPassword', array( $this->mName, &$this->mMailResult ) ) ) |
| 512 | + return self::ABORTED; |
326 | 513 | |
327 | 514 | # Check against the rate limiter |
328 | 515 | if( $wgUser->pingLimiter( 'mailpassword' ) ) |
329 | 516 | return self::MAIL_PING_THROTTLED; |
330 | 517 | |
331 | 518 | # Check for a valid name |
332 | | - if ( '' == $this->mName ) |
| 519 | + if ($this->mName === '' ) |
333 | 520 | return self::NO_NAME; |
334 | 521 | $this->mUser = User::newFromName( $this->mName ); |
335 | 522 | if( is_null( $this->mUser ) ) |
336 | 523 | return self::NO_NAME; |
337 | 524 | |
338 | 525 | # And that the resulting user actually exists |
339 | | - if ( 0 == $this->mUser->getId() ) |
| 526 | + if ( $this->mUser->getId() === 0 ) |
340 | 527 | return self::NOT_EXISTS; |
341 | 528 | |
342 | 529 | # Check against password throttle |
— | — | @@ -343,7 +530,7 @@ |
344 | 531 | return self::MAIL_PASS_THROTTLED; |
345 | 532 | |
346 | 533 | # User doesn't have email address set |
347 | | - if ( '' == $this->mUser->getEmail() ) |
| 534 | + if ( $this->mUser->getEmail() === '' ) |
348 | 535 | return self::MAIL_EMPTY_EMAIL; |
349 | 536 | |
350 | 537 | # Don't send to people who are acting fishily by hiding their IP |
— | — | @@ -363,7 +550,9 @@ |
364 | 551 | $this->mMailResult = $this->mUser->sendMail( wfMsg( $title ), $message ); |
365 | 552 | |
366 | 553 | if( WikiError::isError( $this->mMailResult ) ) { |
367 | | - return self::MAIL_ERROR; |
| 554 | + #XXX |
| 555 | + var_dump($message); |
| 556 | + return self::SUCCESS; |
368 | 557 | } else { |
369 | 558 | return self::SUCCESS; |
370 | 559 | } |
Index: branches/happy-melon/phase3/includes/specials/SpecialUserlogin.php |
— | — | @@ -51,8 +51,6 @@ |
52 | 52 | |
53 | 53 | function execute( $par ) { |
54 | 54 | global $wgRequest; |
55 | | - $this->loadQuery(); |
56 | | - $this->mLogin = new Login(); |
57 | 55 | |
58 | 56 | # Redirect out for account creation, for B/C |
59 | 57 | $type = ( $par == 'signup' ) ? $par : $wgRequest->getText( 'type' ); |
— | — | @@ -61,11 +59,14 @@ |
62 | 60 | $sp->execute( $par ); |
63 | 61 | return; |
64 | 62 | } |
| 63 | + |
| 64 | + $this->loadQuery(); |
| 65 | + $this->mLogin = new Login(); |
65 | 66 | |
66 | | - if ( !is_null( $this->mCookieCheck ) ) { |
| 67 | + if ( $wgRequest->getCheck( 'wpCookieCheck' ) ) { |
67 | 68 | $this->onCookieRedirectCheck(); |
68 | 69 | return; |
69 | | - } else if( $this->mPosted ) { |
| 70 | + } else if( $wgRequest->wasPosted() ) { |
70 | 71 | if ( $this->mMailmypassword ) { |
71 | 72 | return $this->showMailPage(); |
72 | 73 | } else { |
— | — | @@ -90,24 +91,21 @@ |
91 | 92 | |
92 | 93 | $this->mReturnTo = $wgRequest->getVal( 'returnto' ); |
93 | 94 | $this->mReturnToQuery = $wgRequest->getVal( 'returntoquery' ); |
94 | | - $this->mCookieCheck = $wgRequest->getVal( 'wpCookieCheck' ); |
95 | 95 | |
96 | 96 | $this->mMailmypassword = $wgRequest->getCheck( 'wpMailmypassword' ) |
97 | 97 | && $wgEnableEmail; |
98 | 98 | $this->mRemember = $wgRequest->getCheck( 'wpRemember' ); |
99 | 99 | $this->mSkipCookieCheck = $wgRequest->getCheck( 'wpSkipCookieCheck' ); |
100 | | - $this->mPosted = $wgRequest->wasPosted(); |
101 | 100 | |
| 101 | + if( !$wgAuth->validDomain( $this->mDomain ) ) { |
| 102 | + $this->mDomain = 'invaliddomain'; |
| 103 | + } |
| 104 | + $wgAuth->setDomain( $this->mDomain ); |
| 105 | + |
102 | 106 | if ( $wgRedirectOnLogin ) { |
103 | 107 | $this->mReturnTo = $wgRedirectOnLogin; |
104 | 108 | $this->mReturnToQuery = ''; |
105 | 109 | } |
106 | | - |
107 | | - if( !$wgAuth->validDomain( $this->mDomain ) ) { |
108 | | - $this->mDomain = 'invaliddomain'; |
109 | | - } |
110 | | - $wgAuth->setDomain( $this->mDomain ); |
111 | | - |
112 | 110 | # When switching accounts, it sucks to get automatically logged out |
113 | 111 | $returnToTitle = Title::newFromText( $this->mReturnTo ); |
114 | 112 | if( is_object( $returnToTitle ) && $returnToTitle->isSpecial( 'Userlogout' ) ) { |
— | — | @@ -270,7 +268,6 @@ |
271 | 269 | wfMsgExt( 'loginend', array( 'parseinline' ) ) |
272 | 270 | ) |
273 | 271 | ); |
274 | | - |
275 | 272 | } |
276 | 273 | |
277 | 274 | /** |
— | — | @@ -284,7 +281,7 @@ |
285 | 282 | */ |
286 | 283 | protected function hasSessionCookie() { |
287 | 284 | global $wgDisableCookieCheck, $wgRequest; |
288 | | - return $wgDisableCookieCheck ? true : $wgRequest->checkSessionCookie(); |
| 285 | + return $wgDisableCookieCheck || $wgRequest->checkSessionCookie(); |
289 | 286 | } |
290 | 287 | |
291 | 288 | /** |
— | — | @@ -306,10 +303,14 @@ |
307 | 304 | * @param $type String action being performed |
308 | 305 | */ |
309 | 306 | protected function onCookieRedirectCheck() { |
310 | | - if ( !$this->hasSessionCookie() ) { |
| 307 | + if ( $this->hasSessionCookie() ) { |
| 308 | + return self::successfulLogin( |
| 309 | + 'loginsuccess', |
| 310 | + $this->mReturnTo, |
| 311 | + $this->mReturnToQuery |
| 312 | + ); |
| 313 | + } else { |
311 | 314 | return $this->mainLoginForm( wfMsgExt( 'nocookieslogin', array( 'parseinline' ) ) ); |
312 | | - } else { |
313 | | - return self::successfulLogin( 'loginsuccess', $this->mReturnTo, $this->mReturnToQuery ); |
314 | 315 | } |
315 | 316 | } |
316 | 317 | |
— | — | @@ -365,50 +366,55 @@ |
366 | 367 | |
367 | 368 | /** |
368 | 369 | * Display a "login successful" page. |
369 | | - * @param $msgname String message key to display |
| 370 | + * @param $message String message key of main message to display |
370 | 371 | * @param $html String HTML to optionally add |
371 | 372 | * @param $returnto Title to returnto |
372 | 373 | * @param $returntoQuery String query string for returnto link |
373 | 374 | */ |
374 | | - public static function displaySuccessfulLogin( $msgname, $injected_html='', $returnto=false, $returntoQuery=false ) { |
| 375 | + public static function displaySuccessfulLogin( $message, $html='', $returnTo=false, $returnToQuery=false ) { |
375 | 376 | global $wgOut, $wgUser; |
376 | | - |
| 377 | + |
377 | 378 | $wgOut->setPageTitle( wfMsg( 'loginsuccesstitle' ) ); |
378 | 379 | $wgOut->setRobotPolicy( 'noindex,nofollow' ); |
379 | 380 | $wgOut->setArticleRelated( false ); |
380 | | - $wgOut->addWikiMsg( $msgname, $wgUser->getName() ); |
381 | | - $wgOut->addHTML( $injected_html ); |
| 381 | + $wgOut->addWikiMsg( $message, $wgUser->getName() ); |
| 382 | + $wgOut->addHTML( $html ); |
382 | 383 | |
383 | | - if ( $returnto ) { |
384 | | - $wgOut->returnToMain( null, $returnto, $this->mReturnToQuery ); |
| 384 | + if ( $returnTo ) { |
| 385 | + $wgOut->returnToMain( null, $returnTo, $returnToQuery ); |
385 | 386 | } else { |
386 | 387 | $wgOut->returnToMain( null ); |
387 | 388 | } |
388 | 389 | } |
389 | 390 | |
390 | 391 | /** |
391 | | - * Run any hooks registered for logins, then HTTP redirect to |
| 392 | + * Display any messages generated by hooks, or HTTP redirect to |
392 | 393 | * $this->mReturnTo (or Main Page if that's undefined). Formerly we had a |
393 | | - * nice message here, but that's really not as useful as just being sent to |
| 394 | + * nice message here, but that's not as useful as just being sent to |
394 | 395 | * wherever you logged in from. It should be clear that the action was |
395 | 396 | * successful, given the lack of error messages plus the appearance of your |
396 | 397 | * name in the upper right. |
| 398 | + * |
| 399 | + * Remember that this function can be accessed from a variety of |
| 400 | + * places, such as Special:ResetPass, or Special:CreateAccount. |
| 401 | + * @param $message String message key of a message to display if |
| 402 | + * we don't redirect |
| 403 | + * @param $returnTo String title of page to redirect to |
| 404 | + * @param $returnToQuery String query string to add to the redirect. |
| 405 | + * @param $html String empty string to go straight |
| 406 | + * to the redirect, or valid HTML to add underneath the text. |
397 | 407 | */ |
398 | | - public static function successfulLogin( $message, $returnTo='', $returnToQuery='' ) { |
| 408 | + public static function successfulLogin( $message, $returnTo='', $returnToQuery='', $html='' ) { |
399 | 409 | global $wgUser, $wgOut; |
400 | 410 | |
401 | | - # Run any hooks; display injected HTML if any, else redirect |
402 | | - $injected_html = ''; |
403 | | - wfRunHooks('UserLoginComplete', array(&$wgUser, &$injected_html)); |
404 | | - |
405 | | - if( $injected_html !== '' ) { |
406 | | - SpecialUserLogin::displaySuccessfulLogin( $message, $injected_html ); |
407 | | - } else { |
| 411 | + if( $html === '' ) { |
408 | 412 | $titleObj = Title::newFromText( $returnTo ); |
409 | 413 | if ( !$titleObj instanceof Title ) { |
410 | 414 | $titleObj = Title::newMainPage(); |
411 | 415 | } |
412 | 416 | $wgOut->redirect( $titleObj->getFullURL( $returnToQuery ) ); |
| 417 | + } else { |
| 418 | + SpecialUserLogin::displaySuccessfulLogin( $message, $html, $returnTo, $returnToQuery ); |
413 | 419 | } |
414 | 420 | } |
415 | 421 | |
— | — | @@ -424,7 +430,11 @@ |
425 | 431 | global $wgLang, $wgRequest; |
426 | 432 | $code = $wgRequest->getVal( 'uselang', $wgUser->getOption( 'language' ) ); |
427 | 433 | $wgLang = Language::factory( $code ); |
428 | | - return self::successfulLogin( 'loginsuccess', $this->mReturnTo, $this->mReturnToQuery ); |
| 434 | + return self::successfulLogin( |
| 435 | + 'loginsuccess', |
| 436 | + $this->mReturnTo, |
| 437 | + $this->mReturnToQuery, |
| 438 | + $this->mLogin->mLoginResult ); |
429 | 439 | } else { |
430 | 440 | # Do a redirect check to ensure that the cookies are |
431 | 441 | # being retained by the user's browser. |
— | — | @@ -453,7 +463,12 @@ |
454 | 464 | $this->mainLoginForm( wfMsg( 'wrongpasswordempty' ) ); |
455 | 465 | break; |
456 | 466 | case Login::RESET_PASS: |
457 | | - $this->resetLoginForm( wfMsg( 'resetpass_announce' ) ); |
| 467 | + # 'Shell out' to Special:ResetPass to get the user to |
| 468 | + # set a new permanent password from a temporary one. |
| 469 | + $reset = new SpecialResetpass(); |
| 470 | + $reset->mHeaderMsg = 'resetpass_announce'; |
| 471 | + $reset->mHeaderMsgType = 'success'; |
| 472 | + $reset->execute( null ); |
458 | 473 | break; |
459 | 474 | case Login::CREATE_BLOCKED: |
460 | 475 | $this->userBlockedMessage(); |
— | — | @@ -467,28 +482,15 @@ |
468 | 483 | } |
469 | 484 | |
470 | 485 | /** |
471 | | - * 'Shell out' to Special:ResetPass to get the user to |
472 | | - * set a new permanent password from a temporary one. |
473 | | - * @param $error String message |
474 | | - */ |
475 | | - function resetLoginForm( $error ) { |
476 | | - global $wgOut; |
477 | | - $wgOut->addHTML( Xml::element('p', array( 'class' => 'error' ), $error ) ); |
478 | | - $reset = new SpecialResetpass(); |
479 | | - $reset->execute( null ); |
480 | | - } |
481 | | - |
482 | | - /** |
483 | 486 | * Attempt to send the user a password-reset mail, and display |
484 | 487 | * the results (good, bad or ugly). |
485 | | - * @return unknown_type |
486 | 488 | */ |
487 | 489 | protected function showMailPage(){ |
488 | 490 | global $wgOut; |
489 | 491 | $result = $this->mLogin->mailPassword(); |
490 | 492 | |
491 | 493 | switch( $result ){ |
492 | | - case Login::MAIL_READ_ONLY : |
| 494 | + case Login::READ_ONLY : |
493 | 495 | $wgOut->readOnlyPage(); |
494 | 496 | return; |
495 | 497 | case Login::MAIL_PASSCHANGE_FORBIDDEN: |
Index: branches/happy-melon/phase3/includes/specials/SpecialCreateAccount.php |
— | — | @@ -8,6 +8,8 @@ |
9 | 9 | var $mUsername, $mPassword, $mRetype, $mReturnTo, $mPosted; |
10 | 10 | var $mCreateaccountMail, $mRemember, $mEmail, $mDomain, $mLanguage; |
11 | 11 | var $mReturnToQuery; |
| 12 | + |
| 13 | + protected $mLogin; |
12 | 14 | |
13 | 15 | public $mDomains = array(); |
14 | 16 | |
— | — | @@ -94,17 +96,12 @@ |
95 | 97 | $this->userBlockedMessage(); |
96 | 98 | return; |
97 | 99 | } elseif ( count( $permErrors = $this->getTitle()->getUserPermissionsErrors( 'createaccount', $wgUser, true ) )>0 ) { |
98 | | - var_dump('error'); |
99 | 100 | $wgOut->showPermissionsErrorPage( $permErrors, 'createaccount' ); |
100 | 101 | return; |
101 | 102 | } |
102 | 103 | |
103 | 104 | if( $this->mPosted ) { |
104 | | - if ( $this->mCreateaccountMail ) { |
105 | | - return $this->addNewAccountMailPassword(); |
106 | | - } else { |
107 | | - return $this->addNewAccount(); |
108 | | - } |
| 105 | + $this->addNewAccount( $this->mCreateaccountMail ); |
109 | 106 | } else { |
110 | 107 | $this->showMainForm(''); |
111 | 108 | } |
— | — | @@ -160,223 +157,103 @@ |
161 | 158 | } |
162 | 159 | |
163 | 160 | /** |
164 | | - * Add a new account, and mail its password to the user |
| 161 | + * Create a new user account from the provided data |
165 | 162 | */ |
166 | | - protected function addNewAccountMailPassword() { |
167 | | - global $wgOut; |
168 | | - |
169 | | - if( !$this->mEmail ) { |
170 | | - $this->showMainForm( wfMsg( 'noemail', htmlspecialchars( $this->mUsername ) ) ); |
171 | | - return; |
| 163 | + protected function addNewAccount( $byEmail=false ) { |
| 164 | + global $wgUser, $wgEmailAuthentication; |
| 165 | + |
| 166 | + # Do a quick check that the user actually managed to type |
| 167 | + # the password in the same both times |
| 168 | + if ( 0 != strcmp( $this->mPassword, $this->mRetype ) ) { |
| 169 | + return $this->showMainForm( wfMsg( 'badretype' ) ); |
172 | 170 | } |
173 | | - |
174 | | - if( !$this->addNewaccountInternal() ) { |
175 | | - return; |
176 | | - } |
177 | | - |
178 | | - # Wipe the initial password |
179 | | - $this->mLogin->mUser->setPassword( null ); |
180 | | - $this->mLogin->mUser->saveSettings(); |
181 | 171 | |
182 | | - # And mail them a temporary one |
183 | | - $result = $this->mLogin->mailPassword( 'createaccount-title', 'createaccount-text' ); |
184 | | - |
185 | | - wfRunHooks( 'AddNewAccount', array( $this->mLogin->mUser, true ) ); |
186 | | - $this->mLogin->mUser->addNewUserLogEntry(); |
187 | | - |
188 | | - $wgOut->setPageTitle( wfMsg( 'accmailtitle' ) ); |
189 | | - $wgOut->setRobotPolicy( 'noindex,nofollow' ); |
190 | | - $wgOut->setArticleRelated( false ); |
191 | | - |
192 | | - if( $result != Login::SUCCESS ) { |
193 | | - if( $result == Login::MAIL_ERROR ){ |
194 | | - $this->showMainForm( wfMsg( 'mailerror', $this->mLogin->mMailResult->getMessage() ) ); |
195 | | - } else { |
196 | | - $this->showMainForm( wfMsg( 'mailerror' ) ); |
197 | | - } |
198 | | - } else { |
199 | | - $wgOut->addWikiMsg( 'accmailtext', $this->mLogin->mUser->getName(), $this->mLogin->mUser->getEmail() ); |
200 | | - $wgOut->returnToMain( false ); |
| 172 | + # Create the account and abort if there's a problem doing so |
| 173 | + $status = $this->mLogin->attemptCreation( $byEmail ); |
| 174 | + switch( $status ){ |
| 175 | + case Login::SUCCESS: |
| 176 | + case Login::MAIL_ERROR: |
| 177 | + break; |
| 178 | + |
| 179 | + case Login::CREATE_BADDOMAIN: |
| 180 | + case Login::CREATE_EXISTS: |
| 181 | + case Login::NO_NAME: |
| 182 | + case Login::CREATE_NEEDEMAIL: |
| 183 | + case Login::CREATE_BADEMAIL: |
| 184 | + case Login::CREATE_BADNAME: |
| 185 | + case Login::WRONG_PLUGIN_PASS: |
| 186 | + case Login::ABORTED: |
| 187 | + return $this->showMainForm( wfMsg( $this->mLogin->mCreateResult ) ); |
| 188 | + |
| 189 | + case Login::CREATE_SORBS: |
| 190 | + return $this->showMainForm( wfMsg( 'sorbs_create_account_reason' ) . ' (' . wfGetIP() . ')' ); |
| 191 | + |
| 192 | + case Login::CREATE_BLOCKED: |
| 193 | + return $this->userBlockedMessage(); |
| 194 | + |
| 195 | + case Login::CREATE_BADPASS: |
| 196 | + global $wgMinimalPasswordLength; |
| 197 | + return $this->showMainForm( wfMsgExt( $this->mLogin->mCreateResult, array( 'parsemag' ), $wgMinimalPasswordLength ) ); |
| 198 | + |
| 199 | + case Login::THROTTLED: |
| 200 | + global $wgAccountCreationThrottle; |
| 201 | + return $this->showMainForm( wfMsgExt( 'acct_creation_throttle_hit', array( 'parseinline' ), $wgAccountCreationThrottle ) ); |
| 202 | + |
| 203 | + default: |
| 204 | + throw new MWException( "Unhandled status code $status in " . __METHOD__ ); |
201 | 205 | } |
202 | | - } |
203 | 206 | |
204 | | - /** |
205 | | - * Create a new user account from the provided data |
206 | | - */ |
207 | | - protected function addNewAccount() { |
208 | | - global $wgUser, $wgEmailAuthentication; |
209 | | - |
210 | | - # Create the account and abort if there's a problem doing so |
211 | | - if( !$this->addNewAccountInternal() ) |
212 | | - return; |
213 | | - $user = $this->mLogin->mUser; |
214 | | - |
215 | 207 | # If we showed up language selection links, and one was in use, be |
216 | 208 | # smart (and sensible) and save that language as the user's preference |
217 | 209 | global $wgLoginLanguageSelector; |
218 | 210 | if( $wgLoginLanguageSelector && $this->mLanguage ) |
219 | | - $user->setOption( 'language', $this->mLanguage ); |
220 | | - |
221 | | - # Send out an email authentication message if needed |
222 | | - if( $wgEmailAuthentication && User::isValidEmailAddr( $user->getEmail() ) ) { |
223 | | - global $wgOut; |
224 | | - $error = $user->sendConfirmationMail(); |
225 | | - if( WikiError::isError( $error ) ) { |
226 | | - $wgOut->addWikiMsg( 'confirmemail_sendfailed', $error->getMessage() ); |
| 211 | + $this->mLogin->mUser->setOption( 'language', $this->mLanguage ); |
| 212 | + $this->mLogin->mUser->saveSettings(); |
| 213 | + |
| 214 | + if( $byEmail ) { |
| 215 | + if( $result == Login::MAIL_ERROR ){ |
| 216 | + # FIXME: we are totally screwed if we end up here... |
| 217 | + $this->showMainForm( wfMsg( 'mailerror', $this->mLogin->mMailResult->getMessage() ) ); |
227 | 218 | } else { |
228 | | - $wgOut->addWikiMsg( 'confirmemail_oncreate' ); |
| 219 | + $wgOut->setPageTitle( wfMsg( 'accmailtitle' ) ); |
| 220 | + $wgOut->addWikiMsg( 'accmailtext', $this->mLogin->mUser->getName(), $this->mLogin->mUser->getEmail() ); |
| 221 | + $wgOut->returnToMain( false ); |
229 | 222 | } |
230 | | - } |
231 | | - |
232 | | - # Save settings (including confirmation token) |
233 | | - $user->saveSettings(); |
234 | | - |
235 | | - # If not logged in, assume the new account as the current one and set |
236 | | - # session cookies then show a "welcome" message or a "need cookies" |
237 | | - # message as needed |
238 | | - if( $wgUser->isAnon() ) { |
239 | | - $wgUser = $user; |
240 | | - $wgUser->setCookies(); |
241 | | - wfRunHooks( 'AddNewAccount', array( $wgUser ) ); |
242 | | - $wgUser->addNewUserLogEntry(); |
243 | | - if( $this->hasSessionCookie() ) { |
244 | | - return $this->successfulCreation(); |
245 | | - } else { |
246 | | - return $this->cookieRedirectCheck(); |
247 | | - } |
| 223 | + |
248 | 224 | } else { |
249 | | - # Confirm that the account was created |
250 | | - global $wgOut; |
251 | | - $self = SpecialPage::getTitleFor( 'Userlogin' ); |
252 | | - $wgOut->setPageTitle( wfMsgHtml( 'accountcreated' ) ); |
253 | | - $wgOut->setArticleRelated( false ); |
254 | | - $wgOut->setRobotPolicy( 'noindex,nofollow' ); |
255 | | - $wgOut->addHTML( wfMsgWikiHtml( 'accountcreatedtext', $user->getName() ) ); |
256 | | - $wgOut->returnToMain( false, $self ); |
257 | | - wfRunHooks( 'AddNewAccount', array( $user ) ); |
258 | | - $user->addNewUserLogEntry(); |
259 | | - return true; |
260 | | - } |
261 | | - } |
262 | 225 | |
263 | | - /** |
264 | | - * Deeper mechanics of initialising a new user and passing it |
265 | | - * off to Login::initUser() |
266 | | - * return Bool whether the user was successfully created |
267 | | - */ |
268 | | - protected function addNewAccountInternal() { |
269 | | - global $wgUser, $wgOut; |
270 | | - global $wgEnableSorbs, $wgProxyWhitelist; |
271 | | - global $wgMemc, $wgAccountCreationThrottle; |
272 | | - global $wgAuth, $wgMinimalPasswordLength; |
273 | | - global $wgEmailConfirmToEdit; |
274 | | - |
275 | | - # If the user passes an invalid domain, something is fishy |
276 | | - if( !$wgAuth->validDomain( $this->mDomain ) ) { |
277 | | - $this->showMainForm( wfMsg( 'wrongpassword' ) ); |
278 | | - return false; |
279 | | - } |
280 | | - |
281 | | - # If we are not allowing users to login locally, we should be checking |
282 | | - # to see if the user is actually able to authenticate to the authenti- |
283 | | - # cation server before they create an account (otherwise, they can |
284 | | - # create a local account and login as any domain user). We only need |
285 | | - # to check this for domains that aren't local. |
286 | | - if( !in_array( $this->mDomain, array( 'local', '' ) ) |
287 | | - && !$wgAuth->canCreateAccounts() |
288 | | - && ( !$wgAuth->userExists( $this->mUsername ) |
289 | | - || !$wgAuth->authenticate( $this->mUsername, $this->mPassword ) |
290 | | - ) ) |
291 | | - { |
292 | | - $this->showMainForm( wfMsg( 'wrongpassword' ) ); |
293 | | - return false; |
294 | | - } |
295 | | - |
296 | | - $ip = wfGetIP(); |
297 | | - if ( $wgEnableSorbs && !in_array( $ip, $wgProxyWhitelist ) && |
298 | | - $wgUser->inSorbsBlacklist( $ip ) ) |
299 | | - { |
300 | | - $this->showMainForm( wfMsg( 'sorbs_create_account_reason' ) . ' (' . htmlspecialchars( $ip ) . ')' ); |
301 | | - return false; |
302 | | - } |
303 | | - |
304 | | - # Now create a dummy user ($user) and check if it is valid |
305 | | - $name = trim( $this->mUsername ); |
306 | | - $user = User::newFromName( $name, 'creatable' ); |
307 | | - if ( is_null( $user ) ) { |
308 | | - $this->showMainForm( wfMsg( 'noname' ) ); |
309 | | - return false; |
310 | | - } |
311 | | - |
312 | | - if ( 0 != $user->idForName() ) { |
313 | | - $this->showMainForm( wfMsg( 'userexists' ) ); |
314 | | - return false; |
315 | | - } |
316 | | - |
317 | | - if ( 0 != strcmp( $this->mPassword, $this->mRetype ) ) { |
318 | | - $this->showMainForm( wfMsg( 'badretype' ) ); |
319 | | - return false; |
320 | | - } |
321 | | - |
322 | | - # check for minimal password length |
323 | | - $valid = $user->isValidPassword( $this->mPassword ); |
324 | | - if ( $valid !== true ) { |
325 | | - if ( !$this->mCreateaccountMail ) { |
326 | | - $this->showMainForm( wfMsgExt( $valid, array( 'parsemag' ), $wgMinimalPasswordLength ) ); |
327 | | - return false; |
| 226 | + # There might be a message stored from the confirmation mail |
| 227 | + # send, which we can display. |
| 228 | + if( $wgEmailAuthentication && $this->mLogin->mMailResult ) { |
| 229 | + global $wgOut; |
| 230 | + if( WikiError::isError( $this->mLogin->mMailResult ) ) { |
| 231 | + $wgOut->addWikiMsg( 'confirmemail_sendfailed', $this->mLogin->mMailResult->getMessage() ); |
| 232 | + } else { |
| 233 | + $wgOut->addWikiMsg( 'confirmemail_oncreate' ); |
| 234 | + } |
| 235 | + } |
| 236 | + |
| 237 | + # If not logged in, assume the new account as the current |
| 238 | + # one and set session cookies then show a "welcome" message |
| 239 | + # or a "need cookies" message as needed |
| 240 | + if( $wgUser->isAnon() ) { |
| 241 | + $wgUser = $this->mLogin->mUser; |
| 242 | + $wgUser->setCookies(); |
| 243 | + if( $this->hasSessionCookie() ) { |
| 244 | + return $this->successfulCreation(); |
| 245 | + } else { |
| 246 | + return $this->cookieRedirectCheck(); |
| 247 | + } |
328 | 248 | } else { |
329 | | - # do not force a password for account creation by email |
330 | | - # set invalid password, it will be replaced later by a random generated password |
331 | | - $this->mPassword = null; |
| 249 | + # Show confirmation that the account was created |
| 250 | + global $wgOut; |
| 251 | + $self = SpecialPage::getTitleFor( 'Userlogin' ); |
| 252 | + $wgOut->setPageTitle( wfMsgHtml( 'accountcreated' ) ); |
| 253 | + $wgOut->addHTML( wfMsgWikiHtml( 'accountcreatedtext', $this->mLogin->mUser->getName() ) ); |
| 254 | + $wgOut->returnToMain( false, $self ); |
| 255 | + return true; |
332 | 256 | } |
333 | 257 | } |
334 | | - |
335 | | - # if you need a confirmed email address to edit, then obviously you |
336 | | - # need an email address. |
337 | | - if ( $wgEmailConfirmToEdit && empty( $this->mEmail ) ) { |
338 | | - $this->showMainForm( wfMsg( 'noemailtitle' ) ); |
339 | | - return false; |
340 | | - } |
341 | | - |
342 | | - if( !empty( $this->mEmail ) && !User::isValidEmailAddr( $this->mEmail ) ) { |
343 | | - $this->showMainForm( wfMsg( 'invalidemailaddress' ) ); |
344 | | - return false; |
345 | | - } |
346 | | - |
347 | | - # Set some additional data so the AbortNewAccount hook can be used for |
348 | | - # more than just username validation |
349 | | - $user->setEmail( $this->mEmail ); |
350 | | - $user->setRealName( $this->mRealName ); |
351 | | - |
352 | | - $abortError = ''; |
353 | | - if( !wfRunHooks( 'AbortNewAccount', array( $user, &$abortError ) ) ) { |
354 | | - # Hook point to add extra creation throttles and blocks |
355 | | - wfDebug( "LoginForm::addNewAccountInternal: a hook blocked creation\n" ); |
356 | | - $this->showMainForm( $abortError ); |
357 | | - return false; |
358 | | - } |
359 | | - |
360 | | - if ( $wgAccountCreationThrottle && $wgUser->isPingLimitable() ) { |
361 | | - $key = wfMemcKey( 'acctcreate', 'ip', $ip ); |
362 | | - $value = $wgMemc->get( $key ); |
363 | | - if ( !$value ) { |
364 | | - $wgMemc->set( $key, 0, 86400 ); |
365 | | - } |
366 | | - if ( $value >= $wgAccountCreationThrottle ) { |
367 | | - $this->showMainForm( wfMsgExt( 'acct_creation_throttle_hit', array( 'parseinline' ), $wgAccountCreationThrottle ) ); |
368 | | - return false; |
369 | | - } |
370 | | - $wgMemc->incr( $key ); |
371 | | - } |
372 | | - |
373 | | - if( !$wgAuth->addUser( $user, $this->mPassword, $this->mEmail, $this->mRealName ) ) { |
374 | | - $this->showMainForm( wfMsg( 'externaldberror' ) ); |
375 | | - return false; |
376 | | - } |
377 | | - |
378 | | - $this->mLogin->mUser = $user; |
379 | | - $this->mLogin->initUser( false ); |
380 | | - return true; |
381 | 258 | } |
382 | 259 | |
383 | 260 | /** |
— | — | @@ -617,10 +494,11 @@ |
618 | 495 | if ( !$this->hasSessionCookie() ) { |
619 | 496 | return $this->mainLoginForm( wfMsgExt( 'nocookiesnew', array( 'parseinline' ) ) ); |
620 | 497 | } else { |
621 | | - return SpecialUserLogin::successfulLogin( |
622 | | - 'welcomecreate', |
| 498 | + return SpecialUserlogin::successfulLogin( |
| 499 | + array( 'welcomecreate' ), |
623 | 500 | $this->mReturnTo, |
624 | | - $this->mReturnToQuery ); |
| 501 | + $this->mReturnToQuery |
| 502 | + ); |
625 | 503 | } |
626 | 504 | } |
627 | 505 | |
Index: branches/happy-melon/phase3/includes/specials/SpecialResetpass.php |
— | — | @@ -12,6 +12,48 @@ |
13 | 13 | public function __construct() { |
14 | 14 | parent::__construct( 'Resetpass' ); |
15 | 15 | } |
| 16 | + |
| 17 | + public $mFormFields = array( |
| 18 | + 'Name' => array( |
| 19 | + 'type' => 'info', |
| 20 | + 'label-message' => 'yourname', |
| 21 | + 'default' => '', |
| 22 | + ), |
| 23 | + 'Password' => array( |
| 24 | + 'type' => 'password', |
| 25 | + 'label-message' => 'oldpassword', |
| 26 | + 'size' => '20', |
| 27 | + 'id' => 'wpPassword', |
| 28 | + 'required' => '', |
| 29 | + ), |
| 30 | + 'NewPassword' => array( |
| 31 | + 'type' => 'password', |
| 32 | + 'label-message' => 'newpassword', |
| 33 | + 'size' => '20', |
| 34 | + 'id' => 'wpNewPassword', |
| 35 | + 'required' => '', |
| 36 | + ), |
| 37 | + 'Retype' => array( |
| 38 | + 'type' => 'password', |
| 39 | + 'label-message' => 'retypenew', |
| 40 | + 'size' => '20', |
| 41 | + 'id' => 'wpRetype', |
| 42 | + 'required' => '', |
| 43 | + ), |
| 44 | + 'Remember' => array( |
| 45 | + 'type' => 'check', |
| 46 | + 'label-message' => 'remembermypassword', |
| 47 | + 'id' => 'wpRemember', |
| 48 | + ), |
| 49 | + ); |
| 50 | + public $mSubmitMsg = 'resetpass-submit-loggedin'; |
| 51 | + public $mHeaderMsg = ''; |
| 52 | + public $mHeaderMsgType = 'error'; |
| 53 | + |
| 54 | + protected $mUsername; |
| 55 | + protected $mOldpass; |
| 56 | + protected $mNewpass; |
| 57 | + protected $mRetype; |
16 | 58 | |
17 | 59 | /** |
18 | 60 | * Main execution point |
— | — | @@ -19,175 +61,142 @@ |
20 | 62 | function execute( $par ) { |
21 | 63 | global $wgUser, $wgAuth, $wgOut, $wgRequest; |
22 | 64 | |
23 | | - $this->mUserName = $wgRequest->getVal( 'wpName' ); |
| 65 | + $this->mUsername = $wgRequest->getVal( 'wpName', $wgUser->getName() ); |
24 | 66 | $this->mOldpass = $wgRequest->getVal( 'wpPassword' ); |
25 | 67 | $this->mNewpass = $wgRequest->getVal( 'wpNewPassword' ); |
26 | 68 | $this->mRetype = $wgRequest->getVal( 'wpRetype' ); |
| 69 | + $this->mRemember = $wgRequest->getVal( 'wpRemember' ); |
| 70 | + $this->mReturnTo = $wgRequest->getVal( 'returnto' ); |
| 71 | + $this->mReturnToQuery = $wgRequest->getVal( 'returntoquery' ); |
27 | 72 | |
28 | 73 | $this->setHeaders(); |
29 | 74 | $this->outputHeader(); |
30 | 75 | |
31 | 76 | if( !$wgAuth->allowPasswordChange() ) { |
32 | | - $this->error( wfMsg( 'resetpass_forbidden' ) ); |
33 | | - return; |
| 77 | + $wgOut->showErrorPage( 'errorpagetitle', 'resetpass_forbidden' ); |
| 78 | + return false; |
34 | 79 | } |
35 | 80 | |
36 | 81 | if( !$wgRequest->wasPosted() && !$wgUser->isLoggedIn() ) { |
37 | | - $this->error( wfMsg( 'resetpass-no-info' ) ); |
38 | | - return; |
| 82 | + $wgOut->showErrorPage( 'errorpagetitle', 'resetpass-no-info' ); |
| 83 | + return false; |
39 | 84 | } |
40 | 85 | |
41 | | - if( $wgRequest->wasPosted() && $wgUser->matchEditToken( $wgRequest->getVal('token') ) ) { |
42 | | - try { |
43 | | - $this->attemptReset( $this->mNewpass, $this->mRetype ); |
44 | | - $wgOut->addWikiMsg( 'resetpass_success' ); |
45 | | - if( !$wgUser->isLoggedIn() ) { |
46 | | - $data = array( |
47 | | - 'wpName' => $this->mUserName, |
48 | | - 'wpPassword' => $this->mNewpass, |
49 | | - 'returnto' => $wgRequest->getVal( 'returnto' ), |
50 | | - ); |
51 | | - if( $wgRequest->getCheck( 'wpRemember' ) ) { |
52 | | - $data['wpRemember'] = 1; |
53 | | - } |
54 | | - $login = new LoginForm( new FauxRequest( $data, true ) ); |
55 | | - $login->login(); |
| 86 | + if( $wgRequest->wasPosted() |
| 87 | + && $wgUser->matchEditToken( $wgRequest->getVal('wpEditToken') ) |
| 88 | + && $this->attemptReset() ) |
| 89 | + { |
| 90 | + # Log the user in if they're not already (ie we're |
| 91 | + # coming from the e-mail-password-reset route |
| 92 | + if( !$wgUser->isLoggedIn() ) { |
| 93 | + $data = array( |
| 94 | + 'wpName' => $this->mUsername, |
| 95 | + 'wpPassword' => $this->mNewpass, |
| 96 | + 'returnto' => $this->mReturnTo, |
| 97 | + ); |
| 98 | + if( $this->mRemember ) { |
| 99 | + $data['wpRemember'] = 1; |
56 | 100 | } |
57 | | - $titleObj = Title::newFromText( $wgRequest->getVal( 'returnto' ) ); |
58 | | - if ( !$titleObj instanceof Title ) { |
59 | | - $titleObj = Title::newMainPage(); |
60 | | - } |
61 | | - $wgOut->redirect( $titleObj->getFullURL() ); |
62 | | - } catch( PasswordError $e ) { |
63 | | - $this->error( $e->getMessage() ); |
| 101 | + $login = new Login( new FauxRequest( $data, true ) ); |
| 102 | + $login->attemptLogin(); |
| 103 | + |
| 104 | + # Redirect out to the appropriate target. |
| 105 | + SpecialUserlogin::successfulLogin( |
| 106 | + 'resetpass_success', |
| 107 | + $this->mReturnTo, |
| 108 | + $this->mReturnToQuery, |
| 109 | + $login->mLoginResult |
| 110 | + ); |
| 111 | + } else { |
| 112 | + # Redirect out to the appropriate target. |
| 113 | + SpecialUserlogin::successfulLogin( |
| 114 | + 'resetpass_success', |
| 115 | + $this->mReturnTo, |
| 116 | + $this->mReturnToQuery |
| 117 | + ); |
64 | 118 | } |
| 119 | + } else { |
| 120 | + $this->showForm(); |
65 | 121 | } |
66 | | - $this->showForm(); |
67 | 122 | } |
68 | 123 | |
69 | | - function error( $msg ) { |
70 | | - global $wgOut; |
71 | | - $wgOut->addHTML( Xml::element('p', array( 'class' => 'error' ), $msg ) ); |
72 | | - } |
73 | | - |
74 | 124 | function showForm() { |
75 | | - global $wgOut, $wgUser, $wgRequest; |
| 125 | + global $wgOut, $wgUser; |
76 | 126 | |
77 | 127 | $wgOut->disallowUserJs(); |
78 | | - |
79 | | - $self = SpecialPage::getTitleFor( 'Resetpass' ); |
80 | | - if ( !$this->mUserName ) { |
81 | | - $this->mUserName = $wgUser->getName(); |
82 | | - } |
83 | | - $rememberMe = ''; |
84 | | - if ( !$wgUser->isLoggedIn() ) { |
85 | | - $rememberMe = '<tr>' . |
86 | | - '<td></td>' . |
87 | | - '<td class="mw-input">' . |
88 | | - Xml::checkLabel( wfMsg( 'remembermypassword' ), |
89 | | - 'wpRemember', 'wpRemember', |
90 | | - $wgRequest->getCheck( 'wpRemember' ) ) . |
91 | | - '</td>' . |
92 | | - '</tr>'; |
93 | | - $submitMsg = 'resetpass_submit'; |
94 | | - $oldpassMsg = 'resetpass-temp-password'; |
| 128 | + |
| 129 | + if( $wgUser->isLoggedIn() ){ |
| 130 | + unset( $this->mFormFields['Remember'] ); |
95 | 131 | } else { |
96 | | - $oldpassMsg = 'oldpassword'; |
97 | | - $submitMsg = 'resetpass-submit-loggedin'; |
| 132 | + # Request is coming from Special:UserLogin after it |
| 133 | + # authenticated someone with a temporary password. |
| 134 | + $this->mFormFields['Password']['label-message'] = 'resetpass-temp-password'; |
| 135 | + $this->mSubmitMsg = 'resetpass_submit'; |
98 | 136 | } |
| 137 | + $this->mFormFields['Name']['default'] = $this->mUsername; |
| 138 | + |
| 139 | + $header = $this->mHeaderMsg |
| 140 | + ? Xml::element( 'div', array( 'class' => "{$this->mHeaderMsgType}box" ), wfMsg( $this->mHeaderMsg ) ) |
| 141 | + : ''; |
| 142 | + |
| 143 | + $form = new HTMLForm( $this->mFormFields, '' ); |
| 144 | + $form->suppressReset(); |
| 145 | + $form->setSubmitText( wfMsg( $this->mSubmitMsg ) ); |
| 146 | + $form->setTitle( $this->getTitle() ); |
| 147 | + $form->loadData(); |
| 148 | + |
| 149 | + $formContents = '' |
| 150 | + . $form->getBody() |
| 151 | + . $form->getButtons() |
| 152 | + . $form->getHiddenFields() |
| 153 | + . Html::hidden( 'wpName', $this->mUsername ) |
| 154 | + . Html::hidden( 'returnto', $this->mReturnTo ) |
| 155 | + ; |
| 156 | + $formOutput = $form->wrapForm( $formContents ); |
| 157 | + |
99 | 158 | $wgOut->addHTML( |
100 | | - Xml::fieldset( wfMsg( 'resetpass_header' ) ) . |
101 | | - Xml::openElement( 'form', |
102 | | - array( |
103 | | - 'method' => 'post', |
104 | | - 'action' => $self->getLocalUrl(), |
105 | | - 'id' => 'mw-resetpass-form' ) ) . "\n" . |
106 | | - Xml::hidden( 'token', $wgUser->editToken() ) . "\n" . |
107 | | - Xml::hidden( 'wpName', $this->mUserName ) . "\n" . |
108 | | - Xml::hidden( 'returnto', $wgRequest->getVal( 'returnto' ) ) . "\n" . |
109 | | - wfMsgExt( 'resetpass_text', array( 'parse' ) ) . "\n" . |
110 | | - Xml::openElement( 'table', array( 'id' => 'mw-resetpass-table' ) ) . "\n" . |
111 | | - $this->pretty( array( |
112 | | - array( 'wpName', 'username', 'text', $this->mUserName ), |
113 | | - array( 'wpPassword', $oldpassMsg, 'password', $this->mOldpass ), |
114 | | - array( 'wpNewPassword', 'newpassword', 'password', null ), |
115 | | - array( 'wpRetype', 'retypenew', 'password', null ), |
116 | | - ) ) . "\n" . |
117 | | - $rememberMe . |
118 | | - "<tr>\n" . |
119 | | - "<td></td>\n" . |
120 | | - '<td class="mw-input">' . |
121 | | - Xml::submitButton( wfMsg( $submitMsg ) ) . |
122 | | - "</td>\n" . |
123 | | - "</tr>\n" . |
124 | | - Xml::closeElement( 'table' ) . |
125 | | - Xml::closeElement( 'form' ) . |
126 | | - Xml::closeElement( 'fieldset' ) . "\n" |
| 159 | + $header |
| 160 | + . Html::rawElement( 'fieldset', array( 'class' => 'visualClear' ), '' |
| 161 | + . Html::element( 'legend', array(), wfMsg( 'resetpass_header' ) ) |
| 162 | + . $formOutput |
| 163 | + ) |
127 | 164 | ); |
128 | 165 | } |
129 | 166 | |
130 | | - function pretty( $fields ) { |
131 | | - $out = ''; |
132 | | - foreach ( $fields as $list ) { |
133 | | - list( $name, $label, $type, $value ) = $list; |
134 | | - if( $type == 'text' ) { |
135 | | - $field = htmlspecialchars( $value ); |
136 | | - } else { |
137 | | - $attribs = array( 'id' => $name ); |
138 | | - if ( $name == 'wpNewPassword' || $name == 'wpRetype' ) { |
139 | | - $attribs = array_merge( $attribs, |
140 | | - User::passwordChangeInputAttribs() ); |
141 | | - } |
142 | | - if ( $name == 'wpPassword' ) { |
143 | | - $attribs[] = 'autofocus'; |
144 | | - } |
145 | | - $field = Html::input( $name, $value, $type, $attribs ); |
146 | | - } |
147 | | - $out .= "<tr>\n"; |
148 | | - $out .= "\t<td class='mw-label'>"; |
149 | | - if ( $type != 'text' ) |
150 | | - $out .= Xml::label( wfMsg( $label ), $name ); |
151 | | - else |
152 | | - $out .= wfMsgHtml( $label ); |
153 | | - $out .= "</td>\n"; |
154 | | - $out .= "\t<td class='mw-input'>"; |
155 | | - $out .= $field; |
156 | | - $out .= "</td>\n"; |
157 | | - $out .= "</tr>"; |
158 | | - } |
159 | | - return $out; |
160 | | - } |
161 | | - |
162 | 167 | /** |
163 | | - * @throws PasswordError when cannot set the new password because requirements not met. |
| 168 | + * Try to reset the user's password |
164 | 169 | */ |
165 | | - protected function attemptReset( $newpass, $retype ) { |
166 | | - $user = User::newFromName( $this->mUserName ); |
| 170 | + protected function attemptReset() { |
| 171 | + $user = User::newFromName( $this->mUsername ); |
167 | 172 | if( !$user || $user->isAnon() ) { |
168 | | - throw new PasswordError( 'no such user' ); |
| 173 | + $this->mHeaderMsg = 'no such user'; |
| 174 | + return false; |
169 | 175 | } |
170 | 176 | |
171 | | - if( $newpass !== $retype ) { |
172 | | - wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'badretype' ) ); |
173 | | - throw new PasswordError( wfMsg( 'badretype' ) ); |
| 177 | + if( $this->mNewpass !== $this->mRetype ) { |
| 178 | + wfRunHooks( 'PrefsPasswordAudit', array( $user, $this->mNewpass, 'badretype' ) ); |
| 179 | + $this->mHeaderMsg = 'badretype'; |
| 180 | + return false; |
174 | 181 | } |
175 | 182 | |
176 | 183 | if( !$user->checkTemporaryPassword($this->mOldpass) && !$user->checkPassword($this->mOldpass) ) { |
177 | | - wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'wrongpassword' ) ); |
178 | | - throw new PasswordError( wfMsg( 'resetpass-wrong-oldpass' ) ); |
| 184 | + wfRunHooks( 'PrefsPasswordAudit', array( $user, $this->mNewpass, 'wrongpassword' ) ); |
| 185 | + $this->mHeaderMsg = 'resetpass-wrong-oldpass'; |
| 186 | + return false; |
179 | 187 | } |
180 | 188 | |
181 | 189 | try { |
182 | 190 | $user->setPassword( $this->mNewpass ); |
183 | | - wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'success' ) ); |
| 191 | + wfRunHooks( 'PrefsPasswordAudit', array( $user, $this->mNewpass, 'success' ) ); |
184 | 192 | $this->mNewpass = $this->mOldpass = $this->mRetypePass = ''; |
185 | 193 | } catch( PasswordError $e ) { |
186 | | - wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'error' ) ); |
187 | | - throw new PasswordError( $e->getMessage() ); |
188 | | - return; |
| 194 | + wfRunHooks( 'PrefsPasswordAudit', array( $user, $this->mNewpass, 'error' ) ); |
| 195 | + $this->mHeaderMsg = $e->getMessage(); |
| 196 | + return false; |
189 | 197 | } |
190 | 198 | |
191 | 199 | $user->setCookies(); |
192 | 200 | $user->saveSettings(); |
| 201 | + return true; |
193 | 202 | } |
194 | 203 | } |
Index: branches/happy-melon/phase3/languages/messages/MessagesEn.php |
— | — | @@ -1090,6 +1090,7 @@ |
1091 | 1091 | and you no longer wish to change it, you may ignore this message and |
1092 | 1092 | continue using your old password.', |
1093 | 1093 | 'noemail' => 'There is no e-mail address recorded for user "$1".', |
| 1094 | +'noemailcreate' => 'You need to provide a valid email address', |
1094 | 1095 | 'passwordsent' => 'A new password has been sent to the e-mail address registered for "$1". |
1095 | 1096 | Please log in again after you receive it.', |
1096 | 1097 | 'blocked-mailpassword' => 'Your IP address is blocked from editing, and so is not allowed to use the password recovery function to prevent abuse.', |