MediaWiki
REL1_19
|
00001 <?php 00029 class SpecialChangePassword extends UnlistedSpecialPage { 00030 public function __construct() { 00031 parent::__construct( 'ChangePassword' ); 00032 } 00033 00037 function execute( $par ) { 00038 global $wgAuth; 00039 00040 $this->checkReadOnly(); 00041 00042 $request = $this->getRequest(); 00043 $this->mUserName = trim( $request->getVal( 'wpName' ) ); 00044 $this->mOldpass = $request->getVal( 'wpPassword' ); 00045 $this->mNewpass = $request->getVal( 'wpNewPassword' ); 00046 $this->mRetype = $request->getVal( 'wpRetype' ); 00047 $this->mDomain = $request->getVal( 'wpDomain' ); 00048 00049 $this->setHeaders(); 00050 $this->outputHeader(); 00051 $this->getOutput()->disallowUserJs(); 00052 00053 $user = $this->getUser(); 00054 00055 if ( !$user->isLoggedIn() && !LoginForm::getLoginToken() ) { 00056 LoginForm::setLoginToken(); 00057 } 00058 00059 if( !$request->wasPosted() && !$user->isLoggedIn() ) { 00060 $this->error( $this->msg( 'resetpass-no-info' )->text() ); 00061 return; 00062 } 00063 00064 if( $request->wasPosted() && $request->getBool( 'wpCancel' ) ) { 00065 $this->doReturnTo(); 00066 return; 00067 } 00068 00069 if( $request->wasPosted() && $user->matchEditToken( $request->getVal( 'token' ) ) ) { 00070 try { 00071 if ( isset( $_SESSION['wsDomain'] ) ) { 00072 $this->mDomain = $_SESSION['wsDomain']; 00073 } 00074 $wgAuth->setDomain( $this->mDomain ); 00075 if( !$wgAuth->allowPasswordChange() ) { 00076 $this->error( $this->msg( 'resetpass_forbidden' )->text() ); 00077 return; 00078 } 00079 00080 if ( !$user->isLoggedIn() 00081 && $request->getVal( 'wpLoginOnChangeToken' ) !== LoginForm::getLoginToken() 00082 ) { 00083 // Potential CSRF (bug 62497) 00084 $this->error( $this->msg( 'sessionfailure' )->text() ); 00085 return false; 00086 } 00087 00088 $this->attemptReset( $this->mNewpass, $this->mRetype ); 00089 $this->getOutput()->addWikiMsg( 'resetpass_success' ); 00090 if( !$user->isLoggedIn() ) { 00091 LoginForm::setLoginToken(); 00092 $token = LoginForm::getLoginToken(); 00093 $data = array( 00094 'action' => 'submitlogin', 00095 'wpName' => $this->mUserName, 00096 'wpDomain' => $this->mDomain, 00097 'wpLoginToken' => $token, 00098 'wpPassword' => $this->mNewpass, 00099 'returnto' => $request->getVal( 'returnto' ), 00100 ); 00101 if( $request->getCheck( 'wpRemember' ) ) { 00102 $data['wpRemember'] = 1; 00103 } 00104 $login = new LoginForm( new FauxRequest( $data, true ) ); 00105 $login->setContext( $this->getContext() ); 00106 $login->execute( null ); 00107 } 00108 $this->doReturnTo(); 00109 } catch( PasswordError $e ) { 00110 $this->error( $e->getMessage() ); 00111 } 00112 } 00113 $this->showForm(); 00114 } 00115 00116 function doReturnTo() { 00117 $titleObj = Title::newFromText( $this->getRequest()->getVal( 'returnto' ) ); 00118 if ( !$titleObj instanceof Title ) { 00119 $titleObj = Title::newMainPage(); 00120 } 00121 $this->getOutput()->redirect( $titleObj->getFullURL() ); 00122 } 00123 00124 function error( $msg ) { 00125 $this->getOutput()->addHTML( Xml::element('p', array( 'class' => 'error' ), $msg ) ); 00126 } 00127 00128 function showForm() { 00129 global $wgCookieExpiration; 00130 00131 $user = $this->getUser(); 00132 if ( !$this->mUserName ) { 00133 $this->mUserName = $user->getName(); 00134 } 00135 $rememberMe = ''; 00136 if ( !$user->isLoggedIn() ) { 00137 $rememberMe = '<tr>' . 00138 '<td></td>' . 00139 '<td class="mw-input">' . 00140 Xml::checkLabel( 00141 $this->msg( 'remembermypassword' )->numParams( ceil( $wgCookieExpiration / ( 3600 * 24 ) ) )->text(), 00142 'wpRemember', 'wpRemember', 00143 $this->getRequest()->getCheck( 'wpRemember' ) ) . 00144 '</td>' . 00145 '</tr>'; 00146 $submitMsg = 'resetpass_submit'; 00147 $oldpassMsg = 'resetpass-temp-password'; 00148 } else { 00149 $oldpassMsg = 'oldpassword'; 00150 $submitMsg = 'resetpass-submit-loggedin'; 00151 } 00152 $loginOnChangeToken = ''; 00153 if ( !$user->isLoggedIn() ) { 00154 $loginOnChangeToken = Html::hidden( 'wpLoginOnChangeToken', LoginForm::getLoginToken() ); 00155 } 00156 $this->getOutput()->addHTML( 00157 Xml::fieldset( $this->msg( 'resetpass_header' )->text() ) . 00158 Xml::openElement( 'form', 00159 array( 00160 'method' => 'post', 00161 'action' => $this->getTitle()->getLocalUrl(), 00162 'id' => 'mw-resetpass-form' ) ) . "\n" . 00163 Html::hidden( 'token', $user->getEditToken() ) . "\n" . 00164 Html::hidden( 'wpName', $this->mUserName ) . "\n" . 00165 Html::hidden( 'wpDomain', $this->mDomain ) . "\n" . 00166 Html::hidden( 'returnto', $this->getRequest()->getVal( 'returnto' ) ) . "\n" . 00167 $loginOnChangeToken . 00168 $this->msg( 'resetpass_text' )->parseAsBlock() . "\n" . 00169 Xml::openElement( 'table', array( 'id' => 'mw-resetpass-table' ) ) . "\n" . 00170 $this->pretty( array( 00171 array( 'wpName', 'username', 'text', $this->mUserName ), 00172 array( 'wpPassword', $oldpassMsg, 'password', $this->mOldpass ), 00173 array( 'wpNewPassword', 'newpassword', 'password', null ), 00174 array( 'wpRetype', 'retypenew', 'password', null ), 00175 ) ) . "\n" . 00176 $rememberMe . 00177 "<tr>\n" . 00178 "<td></td>\n" . 00179 '<td class="mw-input">' . 00180 Xml::submitButton( $this->msg( $submitMsg )->text() ) . 00181 Xml::submitButton( $this->msg( 'resetpass-submit-cancel' )->text(), array( 'name' => 'wpCancel' ) ) . 00182 "</td>\n" . 00183 "</tr>\n" . 00184 Xml::closeElement( 'table' ) . 00185 Xml::closeElement( 'form' ) . 00186 Xml::closeElement( 'fieldset' ) . "\n" 00187 ); 00188 } 00189 00190 function pretty( $fields ) { 00191 $out = ''; 00192 foreach ( $fields as $list ) { 00193 list( $name, $label, $type, $value ) = $list; 00194 if( $type == 'text' ) { 00195 $field = htmlspecialchars( $value ); 00196 } else { 00197 $attribs = array( 'id' => $name ); 00198 if ( $name == 'wpNewPassword' || $name == 'wpRetype' ) { 00199 $attribs = array_merge( $attribs, 00200 User::passwordChangeInputAttribs() ); 00201 } 00202 if ( $name == 'wpPassword' ) { 00203 $attribs[] = 'autofocus'; 00204 } 00205 $field = Html::input( $name, $value, $type, $attribs ); 00206 } 00207 $out .= "<tr>\n"; 00208 $out .= "\t<td class='mw-label'>"; 00209 if ( $type != 'text' ) 00210 $out .= Xml::label( $this->msg( $label )->text(), $name ); 00211 else 00212 $out .= $this->msg( $label )->escaped(); 00213 $out .= "</td>\n"; 00214 $out .= "\t<td class='mw-input'>"; 00215 $out .= $field; 00216 $out .= "</td>\n"; 00217 $out .= "</tr>"; 00218 } 00219 return $out; 00220 } 00221 00225 protected function attemptReset( $newpass, $retype ) { 00226 $user = User::newFromName( $this->mUserName ); 00227 if( !$user || $user->isAnon() ) { 00228 throw new PasswordError( $this->msg( 'nosuchusershort', $this->mUserName )->text() ); 00229 } 00230 00231 if( $newpass !== $retype ) { 00232 wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'badretype' ) ); 00233 throw new PasswordError( $this->msg( 'badretype' )->text() ); 00234 } 00235 00236 $throttleCount = LoginForm::incLoginThrottle( $this->mUserName ); 00237 if ( $throttleCount === true ) { 00238 throw new PasswordError( $this->msg( 'login-throttled' )->text() ); 00239 } 00240 00241 $abortMsg = 'resetpass-abort-generic'; 00242 if ( !wfRunHooks( 'AbortChangePassword', array( $user, $this->mOldpass, $newpass, &$abortMsg ) ) ) { 00243 wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'abortreset' ) ); 00244 throw new PasswordError( $this->msg( $abortMsg )->text() ); 00245 } 00246 00247 if( !$user->checkTemporaryPassword($this->mOldpass) && !$user->checkPassword($this->mOldpass) ) { 00248 wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'wrongpassword' ) ); 00249 throw new PasswordError( $this->msg( 'resetpass-wrong-oldpass' )->text() ); 00250 } 00251 00252 // Please reset throttle for successful logins, thanks! 00253 if ( $throttleCount ) { 00254 LoginForm::clearLoginThrottle( $this->mUserName ); 00255 } 00256 00257 try { 00258 $user->setPassword( $this->mNewpass ); 00259 wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'success' ) ); 00260 $this->mNewpass = $this->mOldpass = $this->mRetypePass = ''; 00261 } catch( PasswordError $e ) { 00262 wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'error' ) ); 00263 throw new PasswordError( $e->getMessage() ); 00264 } 00265 00266 $user->setCookies(); 00267 $user->saveSettings(); 00268 } 00269 }