Index: trunk/phase3/maintenance/language/messages.inc |
— | — | @@ -461,6 +461,7 @@ |
462 | 462 | 'resetpass-submit-loggedin', |
463 | 463 | 'resetpass-wrong-oldpass', |
464 | 464 | 'resetpass-temp-password', |
| 465 | + 'resetpass-no-others', |
465 | 466 | ), |
466 | 467 | 'toolbar' => array( |
467 | 468 | 'bold_sample', |
Index: trunk/phase3/includes/User.php |
— | — | @@ -162,6 +162,7 @@ |
163 | 163 | 'proxyunbannable', |
164 | 164 | 'purge', |
165 | 165 | 'read', |
| 166 | + 'reset-passwords', |
166 | 167 | 'reupload', |
167 | 168 | 'reupload-shared', |
168 | 169 | 'rollback', |
Index: trunk/phase3/includes/DefaultSettings.php |
— | — | @@ -1255,6 +1255,8 @@ |
1256 | 1256 | // Permission to change users' group assignments |
1257 | 1257 | $wgGroupPermissions['bureaucrat']['userrights'] = true; |
1258 | 1258 | $wgGroupPermissions['bureaucrat']['noratelimit'] = true; |
| 1259 | +// Permission to change users' passwords |
| 1260 | +# $wgGroupPermissions['bureaucrat']['reset-passwords'] = true; |
1259 | 1261 | // Permission to change users' groups assignments across wikis |
1260 | 1262 | #$wgGroupPermissions['bureaucrat']['userrights-interwiki'] = true; |
1261 | 1263 | |
Index: trunk/phase3/includes/specials/SpecialResetpass.php |
— | — | @@ -9,6 +9,9 @@ |
10 | 10 | * @ingroup SpecialPage |
11 | 11 | */ |
12 | 12 | class SpecialResetpass extends SpecialPage { |
| 13 | + |
| 14 | + private $mSelfChange = true; // Usually, but sometimes not :) |
| 15 | + |
13 | 16 | public function __construct() { |
14 | 17 | parent::__construct( 'Resetpass' ); |
15 | 18 | } |
— | — | @@ -19,7 +22,7 @@ |
20 | 23 | function execute( $par ) { |
21 | 24 | global $wgUser, $wgAuth, $wgOut, $wgRequest; |
22 | 25 | |
23 | | - $this->mUserName = $wgRequest->getVal( 'wpName' ); |
| 26 | + $this->mUserName = $wgRequest->getVal( 'wpName', $par ); |
24 | 27 | $this->mOldpass = $wgRequest->getVal( 'wpPassword' ); |
25 | 28 | $this->mNewpass = $wgRequest->getVal( 'wpNewPassword' ); |
26 | 29 | $this->mRetype = $wgRequest->getVal( 'wpRetype' ); |
— | — | @@ -31,17 +34,33 @@ |
32 | 35 | $this->error( wfMsg( 'resetpass_forbidden' ) ); |
33 | 36 | return; |
34 | 37 | } |
| 38 | + |
| 39 | + // Default to our own username when not given one |
| 40 | + if ( !$this->mUserName ) { |
| 41 | + $this->mUserName = $wgUser->getName(); |
| 42 | + } |
| 43 | + |
| 44 | + // Are we changing our own? |
| 45 | + if ( $wgUser->getName() != $this->mUserName ) { |
| 46 | + $this->mSelfChange = false; // We're changing someone else |
| 47 | + } |
35 | 48 | |
36 | 49 | if( !$wgRequest->wasPosted() && !$wgUser->isLoggedIn() ) { |
37 | 50 | $this->error( wfMsg( 'resetpass-no-info' ) ); |
38 | 51 | return; |
39 | 52 | } |
40 | 53 | |
| 54 | + if ( !$this->mSelfChange && !$wgUser->isAllowed( 'reset-passwords' ) ) { |
| 55 | + $this->error( wfMsg( 'resetpass-no-others' ) ); |
| 56 | + return; |
| 57 | + } |
| 58 | + |
41 | 59 | if( $wgRequest->wasPosted() && $wgUser->matchEditToken( $wgRequest->getVal('token') ) ) { |
42 | 60 | try { |
43 | 61 | $this->attemptReset( $this->mNewpass, $this->mRetype ); |
44 | 62 | $wgOut->addWikiMsg( 'resetpass_success' ); |
45 | | - if( !$wgUser->isLoggedIn() ) { |
| 63 | + // Only attempt this login session if we're changing our own password |
| 64 | + if( $this->mSelfChange && !$wgUser->isLoggedIn() ) { |
46 | 65 | $data = array( |
47 | 66 | 'action' => 'submitlogin', |
48 | 67 | 'wpName' => $this->mUserName, |
— | — | @@ -77,9 +96,7 @@ |
78 | 97 | $wgOut->disallowUserJs(); |
79 | 98 | |
80 | 99 | $self = SpecialPage::getTitleFor( 'Resetpass' ); |
81 | | - if ( !$this->mUserName ) { |
82 | | - $this->mUserName = $wgUser->getName(); |
83 | | - } |
| 100 | + |
84 | 101 | $rememberMe = ''; |
85 | 102 | if ( !$wgUser->isLoggedIn() ) { |
86 | 103 | $rememberMe = '<tr>' . |
— | — | @@ -104,15 +121,14 @@ |
105 | 122 | 'action' => $self->getLocalUrl(), |
106 | 123 | 'id' => 'mw-resetpass-form' ) ) . |
107 | 124 | Xml::hidden( 'token', $wgUser->editToken() ) . |
108 | | - Xml::hidden( 'wpName', $this->mUserName ) . |
109 | 125 | Xml::hidden( 'returnto', $wgRequest->getVal( 'returnto' ) ) . |
110 | 126 | wfMsgExt( 'resetpass_text', array( 'parse' ) ) . |
111 | 127 | Xml::openElement( 'table', array( 'id' => 'mw-resetpass-table' ) ) . |
112 | 128 | $this->pretty( array( |
113 | | - array( 'wpName', 'username', 'text', $this->mUserName ), |
114 | | - array( 'wpPassword', $oldpassMsg, 'password', $this->mOldpass ), |
115 | | - array( 'wpNewPassword', 'newpassword', 'password', '' ), |
116 | | - array( 'wpRetype', 'retypenew', 'password', '' ), |
| 129 | + array( 'wpName', 'username', 'text', $this->mUserName, !$this->mSelfChange ), |
| 130 | + array( 'wpPassword', $oldpassMsg, 'password', $this->mOldpass, $this->mSelfChange ), |
| 131 | + array( 'wpNewPassword', 'newpassword', 'password', '', true ), |
| 132 | + array( 'wpRetype', 'retypenew', 'password', '', true ), |
117 | 133 | ) ) . |
118 | 134 | $rememberMe . |
119 | 135 | '<tr>' . |
— | — | @@ -130,21 +146,16 @@ |
131 | 147 | function pretty( $fields ) { |
132 | 148 | $out = ''; |
133 | 149 | foreach( $fields as $list ) { |
134 | | - list( $name, $label, $type, $value ) = $list; |
135 | | - if( $type == 'text' ) { |
136 | | - $field = htmlspecialchars( $value ); |
137 | | - } else { |
138 | | - $field = Xml::input( $name, 20, $value, |
139 | | - array( 'id' => $name, 'type' => $type ) ); |
140 | | - } |
| 150 | + list( $name, $label, $type, $value, $enabled ) = $list; |
| 151 | + $params = array( 'id' => $name, 'type' => $type ); |
| 152 | + if ( !$enabled ) |
| 153 | + $params['disabled'] = 'disabled'; |
| 154 | + $field = Xml::input( $name, 20, $value, $params ); |
141 | 155 | $out .= '<tr>'; |
142 | | - $out .= "<td class='mw-label'>"; |
143 | | - if ( $type != 'text' ) |
144 | | - $out .= Xml::label( wfMsg( $label ), $name ); |
145 | | - else |
146 | | - $out .= wfMsg( $label ); |
| 156 | + $out .= '<td class="mw-label">'; |
| 157 | + $out .= Xml::label( wfMsg( $label ), $name ); |
147 | 158 | $out .= '</td>'; |
148 | | - $out .= "<td class='mw-input'>"; |
| 159 | + $out .= '<td class="mw-input">'; |
149 | 160 | $out .= $field; |
150 | 161 | $out .= '</td>'; |
151 | 162 | $out .= '</tr>'; |
— | — | @@ -166,9 +177,11 @@ |
167 | 178 | throw new PasswordError( wfMsg( 'badretype' ) ); |
168 | 179 | } |
169 | 180 | |
170 | | - if( !$user->checkTemporaryPassword($this->mOldpass) && !$user->checkPassword($this->mOldpass) ) { |
171 | | - wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'wrongpassword' ) ); |
172 | | - throw new PasswordError( wfMsg( 'resetpass-wrong-oldpass' ) ); |
| 181 | + if ( $this->mSelfChange ) { |
| 182 | + if( !$user->checkTemporaryPassword($this->mOldpass) && !$user->checkPassword($this->mOldpass) ) { |
| 183 | + wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'wrongpassword' ) ); |
| 184 | + throw new PasswordError( wfMsg( 'resetpass-wrong-oldpass' ) ); |
| 185 | + } |
173 | 186 | } |
174 | 187 | |
175 | 188 | try { |
Index: trunk/phase3/languages/messages/MessagesEn.php |
— | — | @@ -1016,6 +1016,7 @@ |
1017 | 1017 | 'resetpass-wrong-oldpass' => 'Invalid temporary or current password. |
1018 | 1018 | You may have already successfully changed your password or requested a new temporary password.', |
1019 | 1019 | 'resetpass-temp-password' => 'Temporary password:', |
| 1020 | +'resetpass-no-others' => 'You cannot reset the password for other users.', |
1020 | 1021 | |
1021 | 1022 | # Edit page toolbar |
1022 | 1023 | 'bold_sample' => 'Bold text', |
Index: trunk/phase3/RELEASE-NOTES |
— | — | @@ -113,6 +113,8 @@ |
114 | 114 | * Special:ListUsers: Sort list of usergroups by alphabet |
115 | 115 | * (bug 16762) Special:Movepage now shows a list of subpages when possible |
116 | 116 | * (bug 17585) Hide legend on Special:Specialpages from non-privileged users |
| 117 | +* (bug 15876) Users with 'reset-passwords' right can change the passwords of |
| 118 | + other users. |
117 | 119 | |
118 | 120 | === Bug fixes in 1.15 === |
119 | 121 | * (bug 16968) Special:Upload no longer throws useless warnings. |