* Changed password hash format, see wikitech-l
[lhc/web/wiklou.git] / includes / SpecialResetpass.php
1 <?php
2 /**
3 * @file
4 * @ingroup SpecialPage
5 */
6
7 /** Constructor */
8 function wfSpecialResetpass( $par ) {
9 $form = new PasswordResetForm();
10 $form->execute( $par );
11 }
12
13 /**
14 * Let users recover their password.
15 * @ingroup SpecialPage
16 */
17 class PasswordResetForm extends SpecialPage {
18 function __construct( $name=null, $reset=null ) {
19 if( $name !== null ) {
20 $this->mName = $name;
21 $this->mTemporaryPassword = $reset;
22 } else {
23 global $wgRequest;
24 $this->mName = $wgRequest->getVal( 'wpName' );
25 $this->mTemporaryPassword = $wgRequest->getVal( 'wpPassword' );
26 }
27 }
28
29 /**
30 * Main execution point
31 */
32 function execute( $par ) {
33 global $wgUser, $wgAuth, $wgOut, $wgRequest;
34
35 if( !$wgAuth->allowPasswordChange() ) {
36 $this->error( wfMsg( 'resetpass_forbidden' ) );
37 return;
38 }
39
40 if( $this->mName === null && !$wgRequest->wasPosted() ) {
41 $this->error( wfMsg( 'resetpass_missing' ) );
42 return;
43 }
44
45 if( $wgRequest->wasPosted() && $wgUser->matchEditToken( $wgRequest->getVal( 'token' ) ) ) {
46 $newpass = $wgRequest->getVal( 'wpNewPassword' );
47 $retype = $wgRequest->getVal( 'wpRetype' );
48 try {
49 $this->attemptReset( $newpass, $retype );
50 $wgOut->addWikiMsg( 'resetpass_success' );
51
52 $data = array(
53 'action' => 'submitlogin',
54 'wpName' => $this->mName,
55 'wpPassword' => $newpass,
56 'returnto' => $wgRequest->getVal( 'returnto' ),
57 );
58 if( $wgRequest->getCheck( 'wpRemember' ) ) {
59 $data['wpRemember'] = 1;
60 }
61 $login = new LoginForm( new FauxRequest( $data, true ) );
62 $login->execute();
63
64 return;
65 } catch( PasswordError $e ) {
66 $this->error( $e->getMessage() );
67 }
68 }
69 $this->showForm();
70 }
71
72 function error( $msg ) {
73 global $wgOut;
74 $wgOut->addHtml( '<div class="errorbox">' .
75 htmlspecialchars( $msg ) .
76 '</div>' );
77 }
78
79 function showForm() {
80 global $wgOut, $wgUser, $wgRequest;
81
82 $wgOut->disallowUserJs();
83
84 $self = SpecialPage::getTitleFor( 'Resetpass' );
85 $form =
86 '<div id="userloginForm">' .
87 wfOpenElement( 'form',
88 array(
89 'method' => 'post',
90 'action' => $self->getLocalUrl() ) ) .
91 '<h2>' . wfMsgHtml( 'resetpass_header' ) . '</h2>' .
92 '<div id="userloginprompt">' .
93 wfMsgExt( 'resetpass_text', array( 'parse' ) ) .
94 '</div>' .
95 '<table>' .
96 wfHidden( 'token', $wgUser->editToken() ) .
97 wfHidden( 'wpName', $this->mName ) .
98 wfHidden( 'wpPassword', $this->mTemporaryPassword ) .
99 wfHidden( 'returnto', $wgRequest->getVal( 'returnto' ) ) .
100 $this->pretty( array(
101 array( 'wpName', 'username', 'text', $this->mName ),
102 array( 'wpNewPassword', 'newpassword', 'password', '' ),
103 array( 'wpRetype', 'yourpasswordagain', 'password', '' ),
104 ) ) .
105 '<tr>' .
106 '<td></td>' .
107 '<td>' .
108 Xml::checkLabel( wfMsg( 'remembermypassword' ),
109 'wpRemember', 'wpRemember',
110 $wgRequest->getCheck( 'wpRemember' ) ) .
111 '</td>' .
112 '</tr>' .
113 '<tr>' .
114 '<td></td>' .
115 '<td>' .
116 wfSubmitButton( wfMsgHtml( 'resetpass_submit' ) ) .
117 '</td>' .
118 '</tr>' .
119 '</table>' .
120 wfCloseElement( 'form' ) .
121 '</div>';
122 $wgOut->addHtml( $form );
123 }
124
125 function pretty( $fields ) {
126 $out = '';
127 foreach( $fields as $list ) {
128 list( $name, $label, $type, $value ) = $list;
129 if( $type == 'text' ) {
130 $field = '<tt>' . htmlspecialchars( $value ) . '</tt>';
131 } else {
132 $field = Xml::input( $name, 20, $value,
133 array( 'id' => $name, 'type' => $type ) );
134 }
135 $out .= '<tr>';
136 $out .= '<td align="right">';
137 $out .= Xml::label( wfMsg( $label ), $name );
138 $out .= '</td>';
139 $out .= '<td>';
140 $out .= $field;
141 $out .= '</td>';
142 $out .= '</tr>';
143 }
144 return $out;
145 }
146
147 /**
148 * @throws PasswordError when cannot set the new password because requirements not met.
149 */
150 function attemptReset( $newpass, $retype ) {
151 $user = User::newFromName( $this->mName );
152 if( $user->isAnon() ) {
153 throw new PasswordError( 'no such user' );
154 }
155
156 if( !$user->checkTemporaryPassword( $this->mTemporaryPassword ) ) {
157 throw new PasswordError( wfMsg( 'resetpass_bad_temporary' ) );
158 }
159
160 if( $newpass !== $retype ) {
161 throw new PasswordError( wfMsg( 'badretype' ) );
162 }
163
164 $user->setPassword( $newpass );
165 $user->saveSettings();
166 }
167 }