/** * @param User $user * @param string $pass * @param string $newaddr * @return Status */ private function attemptChange(User $user, $pass, $newaddr) { global $wgAuth; if ($newaddr != '' && !Sanitizer::validateEmail($newaddr)) { return Status::newFatal('invalidemailaddress'); } if ($newaddr === $user->getEmail()) { return Status::newFatal('changeemail-nochange'); } $throttleInfo = LoginForm::incrementLoginThrottle($user->getName()); if ($throttleInfo) { $lang = $this->getLanguage(); return Status::newFatal('changeemail-throttled', $lang->formatDuration($throttleInfo['wait'])); } if ($this->getConfig()->get('RequirePasswordforEmailChange') && !$user->checkTemporaryPassword($pass) && !$user->checkPassword($pass)) { return Status::newFatal('wrongpassword'); } LoginForm::clearLoginThrottle($user->getName()); $oldaddr = $user->getEmail(); $status = $user->setEmailWithConfirmation($newaddr); if (!$status->isGood()) { return $status; } Hooks::run('PrefsEmailAudit', [$user, $oldaddr, $newaddr]); $user->saveSettings(); $wgAuth->updateExternalDB($user); return $status; }
/** * Checks the new password if it meets the requirements for passwords and set * it as a current password, otherwise set the passed Status object to fatal * and doesn't change anything * * @param string $oldpass The current (temporary) password. * @param string $newpass The password to set. * @param string $retype The string of the retype password field to check with newpass * @return Status */ protected function attemptReset($oldpass, $newpass, $retype) { $isSelf = $this->mUserName === $this->getUser()->getName(); if ($isSelf) { $user = $this->getUser(); } else { $user = User::newFromName($this->mUserName); } if (!$user || $user->isAnon()) { return Status::newFatal($this->msg('nosuchusershort', $this->mUserName)); } if ($newpass !== $retype) { Hooks::run('PrefsPasswordAudit', [$user, $newpass, 'badretype']); return Status::newFatal($this->msg('badretype')); } $throttleInfo = LoginForm::incrementLoginThrottle($this->mUserName); if ($throttleInfo) { return Status::newFatal($this->msg('changepassword-throttled')->durationParams($throttleInfo['wait'])); } // @todo Make these separate messages, since the message is written for both cases if (!$user->checkTemporaryPassword($oldpass) && !$user->checkPassword($oldpass)) { Hooks::run('PrefsPasswordAudit', [$user, $newpass, 'wrongpassword']); return Status::newFatal($this->msg('resetpass-wrong-oldpass')); } // User is resetting their password to their old password if ($oldpass === $newpass) { return Status::newFatal($this->msg('resetpass-recycled')); } // Do AbortChangePassword after checking mOldpass, so we don't leak information // by possibly aborting a new password before verifying the old password. $abortMsg = 'resetpass-abort-generic'; if (!Hooks::run('AbortChangePassword', [$user, $oldpass, $newpass, &$abortMsg])) { Hooks::run('PrefsPasswordAudit', [$user, $newpass, 'abortreset']); return Status::newFatal($this->msg($abortMsg)); } // Please reset throttle for successful logins, thanks! LoginForm::clearLoginThrottle($this->mUserName); try { $user->setPassword($newpass); Hooks::run('PrefsPasswordAudit', [$user, $newpass, 'success']); } catch (PasswordError $e) { Hooks::run('PrefsPasswordAudit', [$user, $newpass, 'error']); return Status::newFatal(new RawMessage($e->getMessage())); } if ($isSelf) { // This is needed to keep the user connected since // changing the password also modifies the user's token. $remember = $this->getRequest()->getCookie('Token') !== null; $user->setCookies(null, null, $remember); } $user->saveSettings(); $this->resetPasswordExpiration($user); return Status::newGood(); }