From 983ddd2c7e2df3b9974b885a9815d447daee9eff Mon Sep 17 00:00:00 2001 From: Chad Horohoe Date: Fri, 20 Feb 2009 18:35:49 +0000 Subject: [PATCH] ChangePassword fixes: * (bug 15876) Allow on-wiki password resets. Needs 'reset-passwords' right, given by default to nobody (commented in DefaultSettings) * Stronger username checking. If we're not allowed to change other people's passwords, don't even attempt it --- RELEASE-NOTES | 2 + includes/DefaultSettings.php | 2 + includes/User.php | 1 + includes/specials/SpecialResetpass.php | 65 +++++++++++++++----------- languages/messages/MessagesEn.php | 1 + maintenance/language/messages.inc | 1 + 6 files changed, 46 insertions(+), 26 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index a6d1e2cf65..c22e4fc91e 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -113,6 +113,8 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN * Special:ListUsers: Sort list of usergroups by alphabet * (bug 16762) Special:Movepage now shows a list of subpages when possible * (bug 17585) Hide legend on Special:Specialpages from non-privileged users +* (bug 15876) Users with 'reset-passwords' right can change the passwords of + other users. === Bug fixes in 1.15 === * (bug 16968) Special:Upload no longer throws useless warnings. diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index 6b7addc68d..c54427b06a 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -1255,6 +1255,8 @@ $wgGroupPermissions['sysop']['movefile'] = true; // Permission to change users' group assignments $wgGroupPermissions['bureaucrat']['userrights'] = true; $wgGroupPermissions['bureaucrat']['noratelimit'] = true; +// Permission to change users' passwords +# $wgGroupPermissions['bureaucrat']['reset-passwords'] = true; // Permission to change users' groups assignments across wikis #$wgGroupPermissions['bureaucrat']['userrights-interwiki'] = true; diff --git a/includes/User.php b/includes/User.php index 81246a1190..cc57c2ba62 100644 --- a/includes/User.php +++ b/includes/User.php @@ -162,6 +162,7 @@ class User { 'proxyunbannable', 'purge', 'read', + 'reset-passwords', 'reupload', 'reupload-shared', 'rollback', diff --git a/includes/specials/SpecialResetpass.php b/includes/specials/SpecialResetpass.php index 059f8dbd53..60453bba9a 100644 --- a/includes/specials/SpecialResetpass.php +++ b/includes/specials/SpecialResetpass.php @@ -9,6 +9,9 @@ * @ingroup SpecialPage */ class SpecialResetpass extends SpecialPage { + + private $mSelfChange = true; // Usually, but sometimes not :) + public function __construct() { parent::__construct( 'Resetpass' ); } @@ -19,7 +22,7 @@ class SpecialResetpass extends SpecialPage { function execute( $par ) { global $wgUser, $wgAuth, $wgOut, $wgRequest; - $this->mUserName = $wgRequest->getVal( 'wpName' ); + $this->mUserName = $wgRequest->getVal( 'wpName', $par ); $this->mOldpass = $wgRequest->getVal( 'wpPassword' ); $this->mNewpass = $wgRequest->getVal( 'wpNewPassword' ); $this->mRetype = $wgRequest->getVal( 'wpRetype' ); @@ -31,17 +34,33 @@ class SpecialResetpass extends SpecialPage { $this->error( wfMsg( 'resetpass_forbidden' ) ); return; } + + // Default to our own username when not given one + if ( !$this->mUserName ) { + $this->mUserName = $wgUser->getName(); + } + + // Are we changing our own? + if ( $wgUser->getName() != $this->mUserName ) { + $this->mSelfChange = false; // We're changing someone else + } if( !$wgRequest->wasPosted() && !$wgUser->isLoggedIn() ) { $this->error( wfMsg( 'resetpass-no-info' ) ); return; } + if ( !$this->mSelfChange && !$wgUser->isAllowed( 'reset-passwords' ) ) { + $this->error( wfMsg( 'resetpass-no-others' ) ); + return; + } + if( $wgRequest->wasPosted() && $wgUser->matchEditToken( $wgRequest->getVal('token') ) ) { try { $this->attemptReset( $this->mNewpass, $this->mRetype ); $wgOut->addWikiMsg( 'resetpass_success' ); - if( !$wgUser->isLoggedIn() ) { + // Only attempt this login session if we're changing our own password + if( $this->mSelfChange && !$wgUser->isLoggedIn() ) { $data = array( 'action' => 'submitlogin', 'wpName' => $this->mUserName, @@ -77,9 +96,7 @@ class SpecialResetpass extends SpecialPage { $wgOut->disallowUserJs(); $self = SpecialPage::getTitleFor( 'Resetpass' ); - if ( !$this->mUserName ) { - $this->mUserName = $wgUser->getName(); - } + $rememberMe = ''; if ( !$wgUser->isLoggedIn() ) { $rememberMe = '' . @@ -104,15 +121,14 @@ class SpecialResetpass extends SpecialPage { 'action' => $self->getLocalUrl(), 'id' => 'mw-resetpass-form' ) ) . Xml::hidden( 'token', $wgUser->editToken() ) . - Xml::hidden( 'wpName', $this->mUserName ) . Xml::hidden( 'returnto', $wgRequest->getVal( 'returnto' ) ) . wfMsgExt( 'resetpass_text', array( 'parse' ) ) . Xml::openElement( 'table', array( 'id' => 'mw-resetpass-table' ) ) . $this->pretty( array( - array( 'wpName', 'username', 'text', $this->mUserName ), - array( 'wpPassword', $oldpassMsg, 'password', $this->mOldpass ), - array( 'wpNewPassword', 'newpassword', 'password', '' ), - array( 'wpRetype', 'retypenew', 'password', '' ), + array( 'wpName', 'username', 'text', $this->mUserName, !$this->mSelfChange ), + array( 'wpPassword', $oldpassMsg, 'password', $this->mOldpass, $this->mSelfChange ), + array( 'wpNewPassword', 'newpassword', 'password', '', true ), + array( 'wpRetype', 'retypenew', 'password', '', true ), ) ) . $rememberMe . '' . @@ -130,21 +146,16 @@ class SpecialResetpass extends SpecialPage { function pretty( $fields ) { $out = ''; foreach( $fields as $list ) { - list( $name, $label, $type, $value ) = $list; - if( $type == 'text' ) { - $field = htmlspecialchars( $value ); - } else { - $field = Xml::input( $name, 20, $value, - array( 'id' => $name, 'type' => $type ) ); - } + list( $name, $label, $type, $value, $enabled ) = $list; + $params = array( 'id' => $name, 'type' => $type ); + if ( !$enabled ) + $params['disabled'] = 'disabled'; + $field = Xml::input( $name, 20, $value, $params ); $out .= ''; - $out .= ""; - if ( $type != 'text' ) - $out .= Xml::label( wfMsg( $label ), $name ); - else - $out .= wfMsg( $label ); + $out .= ''; + $out .= Xml::label( wfMsg( $label ), $name ); $out .= ''; - $out .= ""; + $out .= ''; $out .= $field; $out .= ''; $out .= ''; @@ -166,9 +177,11 @@ class SpecialResetpass extends SpecialPage { throw new PasswordError( wfMsg( 'badretype' ) ); } - if( !$user->checkTemporaryPassword($this->mOldpass) && !$user->checkPassword($this->mOldpass) ) { - wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'wrongpassword' ) ); - throw new PasswordError( wfMsg( 'resetpass-wrong-oldpass' ) ); + if ( $this->mSelfChange ) { + if( !$user->checkTemporaryPassword($this->mOldpass) && !$user->checkPassword($this->mOldpass) ) { + wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'wrongpassword' ) ); + throw new PasswordError( wfMsg( 'resetpass-wrong-oldpass' ) ); + } } try { diff --git a/languages/messages/MessagesEn.php b/languages/messages/MessagesEn.php index 582532effb..2e6a0f3ab9 100644 --- a/languages/messages/MessagesEn.php +++ b/languages/messages/MessagesEn.php @@ -1016,6 +1016,7 @@ You may have already successfully changed your password or requested a new tempo 'resetpass-wrong-oldpass' => 'Invalid temporary or current password. You may have already successfully changed your password or requested a new temporary password.', 'resetpass-temp-password' => 'Temporary password:', +'resetpass-no-others' => 'You cannot reset the password for other users.', # Edit page toolbar 'bold_sample' => 'Bold text', diff --git a/maintenance/language/messages.inc b/maintenance/language/messages.inc index 69360b035f..97fc834967 100644 --- a/maintenance/language/messages.inc +++ b/maintenance/language/messages.inc @@ -461,6 +461,7 @@ $wgMessageStructure = array( 'resetpass-submit-loggedin', 'resetpass-wrong-oldpass', 'resetpass-temp-password', + 'resetpass-no-others', ), 'toolbar' => array( 'bold_sample', -- 2.20.1