revert r82283, loads of unrelated changes
authorHappy-melon <happy-melon@users.mediawiki.org>
Wed, 16 Feb 2011 19:51:25 +0000 (19:51 +0000)
committerHappy-melon <happy-melon@users.mediawiki.org>
Wed, 16 Feb 2011 19:51:25 +0000 (19:51 +0000)
RELEASE-NOTES
includes/AutoLoader.php
includes/HTMLForm.php
includes/OutputPage.php
includes/Skin.php
includes/User.php
includes/resourceloader/ResourceLoaderUserGroupsModule.php [deleted file]
includes/specials/SpecialResetpass.php
resources/Resources.php

index a33bffa..1e5d474 100644 (file)
@@ -72,8 +72,6 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
   (maintenance/fixDoubleRedirects.php)
 * (bug 23315) New body classes to allow easier styling of special pages
 * (bug 27159) Make email confirmation code expiration time configurable
-* CSS/JS for each user group is imported from MediaWiki:Sysop.js, 
-  MediaWiki:Autoconfirmed.css, etc.
 
 === Bug fixes in 1.18 ===
 * (bug 23119) WikiError class and subclasses are now marked as deprecated
index be99d84..198f279 100644 (file)
@@ -152,7 +152,6 @@ $wgAutoloadLocalClasses = array(
        'LinksUpdate' => 'includes/LinksUpdate.php',
        'LocalisationCache' => 'includes/LocalisationCache.php',
        'LocalisationCache_BulkLoad' => 'includes/LocalisationCache.php',
-       'Login' => 'includes/Login.php',
        'LogPage' => 'includes/LogPage.php',
        'LogPager' => 'includes/LogEventsList.php',
        'LogEventsList' => 'includes/LogEventsList.php',
@@ -212,7 +211,6 @@ $wgAutoloadLocalClasses = array(
        'ResourceLoaderFileModule' => 'includes/resourceloader/ResourceLoaderFileModule.php',
        'ResourceLoaderSiteModule' => 'includes/resourceloader/ResourceLoaderSiteModule.php',
        'ResourceLoaderUserModule' => 'includes/resourceloader/ResourceLoaderUserModule.php',
-       'ResourceLoaderUserGroupsModule' => 'includes/resourceloader/ResourceLoaderUserGroupsModule.php',
        'ResourceLoaderUserOptionsModule' => 'includes/resourceloader/ResourceLoaderUserOptionsModule.php',
        'ResourceLoaderStartUpModule' => 'includes/resourceloader/ResourceLoaderStartUpModule.php',
        'ReverseChronologicalPager' => 'includes/Pager.php',
@@ -581,7 +579,6 @@ $wgAutoloadLocalClasses = array(
        'AncientPagesPage' => 'includes/specials/SpecialAncientpages.php',
        'BrokenRedirectsPage' => 'includes/specials/SpecialBrokenRedirects.php',
        'ContribsPager' => 'includes/specials/SpecialContributions.php',
-       'SpecialCreateAccount' => 'includes/specials/SpecialCreateAccount.php',
        'DBLockForm' => 'includes/specials/SpecialLockdb.php',
        'DBUnlockForm' => 'includes/specials/SpecialUnlockdb.php',
        'DeadendPagesPage' => 'includes/specials/SpecialDeadendpages.php',
@@ -681,7 +678,6 @@ $wgAutoloadLocalClasses = array(
        'UnwatchedpagesPage' => 'includes/specials/SpecialUnwatchedpages.php',
        'UploadForm' => 'includes/specials/SpecialUpload.php',
        'UploadSourceField' => 'includes/specials/SpecialUpload.php',
-       'SpecialUserlogin' => 'includes/specials/SpecialUserlogin.php',
        'UserrightsPage' => 'includes/specials/SpecialUserrights.php',
        'UsersPager' => 'includes/specials/SpecialListusers.php',
        'WantedCategoriesPage' => 'includes/specials/SpecialWantedcategories.php',
index b138549..2472bc2 100644 (file)
@@ -109,7 +109,6 @@ class HTMLForm {
        protected $mButtons = array();
 
        protected $mWrapperLegend = false;
-       protected $mTokenAction = 'Edit';
 
        /**
         * Build a new HTMLForm from an array of field attributes
@@ -185,7 +184,7 @@ class HTMLForm {
                if ( !$class ) {
                        throw new MWException( "Descriptor with no class: " . print_r( $descriptor, true ) );
                }
-
+               
                $descriptor['fieldname'] = $fieldname;
 
                $obj = new $class( $descriptor );
@@ -211,15 +210,14 @@ class HTMLForm {
 
        /**
         * Try submitting, with edit token check first
-        * @return Status|boolean
+        * @return Status|boolean 
         */
        function tryAuthorizedSubmit() {
                global $wgUser, $wgRequest;
                $editToken = $wgRequest->getVal( 'wpEditToken' );
 
                $result = false;
-               # FIXME
-               if ( $wgRequest->wasPosted() ){#&& $this->getMethod() != 'post' || $wgUser->matchEditToken( $editToken ) ) {
+               if ( $this->getMethod() != 'post' || $wgUser->matchEditToken( $editToken ) ) {
                        $result = $this->trySubmit();
                }
                return $result;
@@ -251,11 +249,6 @@ class HTMLForm {
         *       display.
         */
        function trySubmit() {
-               # Check the session tokens
-               # FIXME
-               if ( false && !Token::match( null, $this->mTokenAction ) ) {
-                       return array( 'sessionfailure' );
-               }
                # Check for validation
                foreach ( $this->mFlatFields as $fieldname => $field ) {
                        if ( !empty( $field->mParams['nodata'] ) ) {
@@ -431,14 +424,9 @@ class HTMLForm {
                global $wgUser;
 
                $html = '';
+               
                if( $this->getMethod() == 'post' ){
-                       # FIXME
-                       $token = new Token( $this->mTokenAction );
-                       $html .= Html::hidden(
-                               "wp{$this->mTokenAction}Token",
-                               $token->set(),
-                               array( 'id' => 'wpEditToken' )
-                       ) . "\n";
+                       $html .= Html::hidden( 'wpEditToken', $wgUser->editToken(), array( 'id' => 'wpEditToken' ) ) . "\n";
                        $html .= Html::hidden( 'title', $this->getTitle()->getPrefixedText() ) . "\n";
                }
 
@@ -591,7 +579,6 @@ class HTMLForm {
                $this->mSubmitTooltip = $name;
        }
 
-
        /**
         * Set the id for the submit button.
         * @param $t String.  FIXME: Integrity is *not* validated
@@ -620,15 +607,6 @@ class HTMLForm {
        function setMessagePrefix( $p ) {
                $this->mMessagePrefix = $p;
        }
-       /**
-        * If you want to protect the form from CSRF by a token other than
-        * the usual wsEditToken, set something here.
-        * @see Token::set()
-        * @param $a
-        */
-       function setTokenAction( $a ){
-               $this->mTokenAction = ucfirst( $a );
-       }
 
        /**
         * Set the title for form submission
@@ -645,7 +623,7 @@ class HTMLForm {
        function getTitle() {
                return $this->mTitle;
        }
-
+       
        /**
         * Set the method used to submit the form
         * @param $method String
@@ -653,7 +631,7 @@ class HTMLForm {
        public function setMethod( $method='post' ){
                $this->mMethod = $method;
        }
-
+       
        public function getMethod(){
                return $this->mMethod;
        }
@@ -862,12 +840,12 @@ abstract class HTMLFormField {
                if ( isset( $params['name'] ) ) {
                        $this->mName = $params['name'];
                }
-
+               
                $validName = Sanitizer::escapeId( $this->mName );
                if ( $this->mName != $validName && !isset( $params['nodata'] ) ) {
                        throw new MWException( "Invalid name '{$this->mName}' passed to " . __METHOD__ );
                }
-
+               
                $this->mID = "mw-input-{$this->mName}";
 
                if ( isset( $params['default'] ) ) {
@@ -909,10 +887,10 @@ abstract class HTMLFormField {
                global $wgRequest;
 
                $errors = $this->validate( $value, $this->mParent->mFieldData );
-
+               
                $cellAttributes = array();
                $verticalLabel = false;
-
+               
                if ( !empty($this->mParams['vertical-label']) ) {
                        $cellAttributes['colspan'] = 2;
                        $verticalLabel = true;
@@ -930,9 +908,9 @@ abstract class HTMLFormField {
                        array( 'class' => 'mw-input' ) + $cellAttributes,
                        $this->getInputHTML( $value ) . "\n$errors"
                );
-
+               
                $fieldType = get_class( $this );
-
+               
                if ($verticalLabel) {
                        $html = Html::rawElement( 'tr',
                                array( 'class' => 'mw-htmlform-vertical-label' ), $label );
@@ -1161,11 +1139,11 @@ class HTMLFloatField extends HTMLTextField {
                if ( $p !== true ) {
                        return $p;
                }
-
+               
                $value = trim( $value );
 
                # http://dev.w3.org/html5/spec/common-microsyntaxes.html#real-numbers
-               # with the addition that a leading '+' sign is ok.
+               # with the addition that a leading '+' sign is ok. 
                if ( !preg_match( '/^((\+|\-)?\d+(\.\d+)?(E(\+|\-)?\d+)?)?$/i', $value ) ) {
                        return wfMsgExt( 'htmlform-float-invalid', 'parse' );
                }
@@ -1204,8 +1182,8 @@ class HTMLIntField extends HTMLFloatField {
                }
 
                # http://dev.w3.org/html5/spec/common-microsyntaxes.html#signed-integers
-               # with the addition that a leading '+' sign is ok. Note that leading zeros
-               # are fine, and will be left in the input, which is useful for things like
+               # with the addition that a leading '+' sign is ok. Note that leading zeros 
+               # are fine, and will be left in the input, which is useful for things like 
                # phone numbers when you know that they are integers (the HTML5 type=tel
                # input does not require its value to be numeric).  If you want a tidier
                # value to, eg, save in the DB, clean it up with intval().
@@ -1437,8 +1415,8 @@ class HTMLMultiSelectField extends HTMLFormField {
                        } else {
                                $thisAttribs = array( 'id' => "{$this->mID}-$info", 'value' => $info );
 
-                               $checkbox = Xml::check(
-                                       $this->mName . '[]',
+                               $checkbox = Xml::check( 
+                                       $this->mName . '[]', 
                                        in_array( $info, $value, true ),
                                        $attribs + $thisAttribs );
                                $checkbox .= '&#160;' . Html::rawElement( 'label', array( 'for' => "{$this->mID}-$info" ), $label );
@@ -1578,7 +1556,7 @@ class HTMLInfoField extends HTMLFormField {
 class HTMLHiddenField extends HTMLFormField {
        public function __construct( $params ) {
                parent::__construct( $params );
-
+               
                # Per HTML5 spec, hidden fields cannot be 'required'
                # http://dev.w3.org/html5/spec/states-of-the-type-attribute.html#hidden-state
                unset( $this->mParams['required'] );
@@ -1627,7 +1605,7 @@ class HTMLSubmitField extends HTMLFormField {
        protected function needsLabel() {
                return false;
        }
-
+       
        /**
         * Button cannot be invalid
         */
index f03e0e9..ca2acbf 100644 (file)
@@ -2555,29 +2555,28 @@ class OutputPage {
                // Legacy Scripts
                $scripts .= "\n" . $this->mScripts;
 
-               $userScripts = array( 'user.options' );
-
                // Add site JS if enabled
                if ( $wgUseSiteJs ) {
                        $scripts .= $this->makeResourceLoaderLink( $sk, 'site', ResourceLoaderModule::TYPE_SCRIPTS );
-                       if( $wgUser->isLoggedIn() ){
-                               $userScripts[] = 'user.groups';
-                       }
                }
 
-               // Add user JS if enabled
+               // Add user JS if enabled - trying to load user.options as a bundle if possible
+               $userOptionsAdded = false;
                if ( $wgAllowUserJs && $wgUser->isLoggedIn() ) {
                        $action = $wgRequest->getVal( 'action', 'view' );
                        if( $this->mTitle && $this->mTitle->isJsSubpage() && $sk->userCanPreview( $action ) ) {
                                # XXX: additional security check/prompt?
                                $scripts .= Html::inlineScript( "\n" . $wgRequest->getText( 'wpTextbox1' ) . "\n" ) . "\n";
                        } else {
-                               # FIXME: this means that User:Me/Common.js doesn't load when previewing
-                               # User:Me/Vector.js, and vice versa (bug26283)
-                               $userScripts[] = 'user';
+                               $scripts .= $this->makeResourceLoaderLink(
+                                       $sk, array( 'user', 'user.options' ), ResourceLoaderModule::TYPE_SCRIPTS
+                               );
+                               $userOptionsAdded = true;
                        }
                }
-               $scripts .= $this->makeResourceLoaderLink( $sk, $userScripts, ResourceLoaderModule::TYPE_SCRIPTS );
+               if ( !$userOptionsAdded ) {
+                       $scripts .= $this->makeResourceLoaderLink( $sk, 'user.options', ResourceLoaderModule::TYPE_SCRIPTS );
+               }
 
                return $scripts;
        }
index 57e535f..489bda8 100644 (file)
@@ -546,7 +546,7 @@ abstract class Skin extends Linker {
         * @private
         */
        function setupUserCss( OutputPage $out ) {
-               global $wgRequest, $wgUser;
+               global $wgRequest;
                global $wgUseSiteCss, $wgAllowUserCss, $wgAllowUserCssPrefs;
 
                wfProfileIn( __METHOD__ );
@@ -560,9 +560,6 @@ abstract class Skin extends Linker {
                // Per-site custom styles
                if ( $wgUseSiteCss ) {
                        $out->addModuleStyles( 'site' );
-                       if( $wgUser->isLoggedIn() ){
-                               $out->addModuleStyles( 'user.groups' );
-                       }
                }
 
                // Per-user custom styles
index de99114..701d4d5 100644 (file)
@@ -4,6 +4,12 @@
  * @file
  */
 
+/**
+ * Int Number of characters in user_token field.
+ * @ingroup Constants
+ */
+define( 'USER_TOKEN_LENGTH', 32 );
+
 /**
  * Int Serialized record version.
  * @ingroup Constants
@@ -35,6 +41,13 @@ class PasswordError extends MWException {
  * of the database.
  */
 class User {
+       /**
+        * Global constants made accessible as class constants so that autoloader
+        * magic can be used.
+        */
+       const USER_TOKEN_LENGTH = USER_TOKEN_LENGTH;
+       const MW_USER_VERSION = MW_USER_VERSION;
+       const EDIT_TOKEN_SUFFIX = EDIT_TOKEN_SUFFIX;
 
        /**
         * Array of Strings List of member variables which are saved to the
@@ -364,7 +377,7 @@ class User {
        /**
         * Create a new user object from a user row.
         * The row should have all fields from the user table in it.
-        * @param $row array A row from the user table
+        * @param $row Array A row from the user table
         * @return User
         */
        static function newFromRow( $row ) {
@@ -614,7 +627,6 @@ class User {
                if( !wfRunHooks( 'isValidPassword', array( $password, &$result, $this ) ) )
                        return $result;
 
-
                if ( $result === false ) {
                        if( strlen( $password ) < $wgMinimalPasswordLength ) {
                                return 'passwordtooshort';
@@ -1238,9 +1250,6 @@ class User {
                        // Deprecated, but kept for backwards-compatibility config
                        return false;
                }
-
-
-
                if( in_array( wfGetIP(), $wgRateLimitsExcludedIPs ) ) {
                        // No other good way currently to disable rate limits
                        // for specific IPs. :P
@@ -1777,7 +1786,7 @@ class User {
                        }
 
                        if( !$this->isValidPassword( $str ) ) {
-                               global $wgMinimalPasswordLength;
+                               global $wgMinimalPasswordLength;
                                $valid = $this->getPasswordValidity( $str );
                                if ( is_array( $valid ) ) {
                                        $message = array_shift( $valid );
@@ -1787,7 +1796,7 @@ class User {
                                        $params = array( $wgMinimalPasswordLength );
                                }
                                throw new PasswordError( wfMsgExt( $message, array( 'parsemag' ), $params ) );
-                       }
+                       }
                }
 
                if( !$wgAuth->setPassword( $this, $str ) ) {
@@ -2197,7 +2206,6 @@ class User {
        }
 
        /**
-
         * Check if user is allowed to access a feature / make an action
         * @param $action String action to be checked
         * @return Boolean: True if action is allowed, else false
@@ -2521,8 +2529,8 @@ class User {
                                'user_newpassword' => $this->mNewpassword,
                                'user_newpass_time' => $dbw->timestampOrNull( $this->mNewpassTime ),
                                'user_real_name' => $this->mRealName,
-                               'user_email' => $this->mEmail,
-                               'user_email_authenticated' => $dbw->timestampOrNull( $this->mEmailAuthenticated ),
+                               'user_email' => $this->mEmail,
+                               'user_email_authenticated' => $dbw->timestampOrNull( $this->mEmailAuthenticated ),
                                'user_options' => '',
                                'user_touched' => $dbw->timestamp( $this->mTouched ),
                                'user_token' => $this->mToken,
@@ -2581,6 +2589,7 @@ class User {
                }
                $dbw = wfGetDB( DB_MASTER );
                $seqVal = $dbw->nextSequenceValue( 'user_user_id_seq' );
+
                $fields = array(
                        'user_id' => $seqVal,
                        'user_name' => $name,
@@ -2792,7 +2801,7 @@ class User {
                // are shorter than this, doesn't mean people wont be able
                // to. Certain authentication plugins do NOT want to save
                // domain passwords in a mysql database, so we should
-               // check this (incase $wgAuth->strict() is false).
+               // check this (in case $wgAuth->strict() is false).
                if( !$this->isValidPassword( $password ) ) {
                        return false;
                }
@@ -2851,7 +2860,7 @@ class User {
                        return EDIT_TOKEN_SUFFIX;
                } else {
                        if( !isset( $_SESSION['wsEditToken'] ) ) {
-                               $token = $this->generateToken();
+                               $token = self::generateToken();
                                $_SESSION['wsEditToken'] = $token;
                        } else {
                                $token = $_SESSION['wsEditToken'];
@@ -2869,7 +2878,7 @@ class User {
         * @param $salt String Optional salt value
         * @return String The new random token
         */
-       function generateToken( $salt = '' ) {
+       public static function generateToken( $salt = '' ) {
                $token = dechex( mt_rand() ) . dechex( mt_rand() );
                return md5( $token . $salt );
        }
@@ -2977,7 +2986,7 @@ class User {
                $now = time();
                $expires = $now + $wgUserEmailConfirmationTokenExpiry;
                $expiration = wfTimestamp( TS_MW, $expires );
-               $token = wfGenerateToken( $this->mId . $this->mEmail . $expires );
+               $token = self::generateToken( $this->mId . $this->mEmail . $expires );
                $hash = md5( $token );
                $this->load();
                $this->mEmailToken = $hash;
@@ -3131,7 +3140,7 @@ class User {
         * Get the timestamp of account creation.
         *
         * @return String|Bool Timestamp of account creation, or false for
-        *                                non-existent/anonymous user accounts.
+        *     non-existent/anonymous user accounts.
         */
        public function getRegistration() {
                return $this->getId() > 0
@@ -3143,7 +3152,7 @@ class User {
         * Get the timestamp of the first edit
         *
         * @return String|Bool Timestamp of first edit, or false for
-        *                                non-existent/anonymous user accounts.
+        *     non-existent/anonymous user accounts.
         */
        public function getFirstEditTimestamp() {
                if( $this->getId() == 0 ) {
@@ -3333,9 +3342,9 @@ class User {
         *
         * @param $group String: the group to check for whether it can add/remove
         * @return Array array( 'add' => array( addablegroups ),
-        *  'remove' => array( removablegroups ),
-        *  'add-self' => array( addablegroups to self),
-        *  'remove-self' => array( removable groups from self) )
+        *     'remove' => array( removablegroups ),
+        *     'add-self' => array( addablegroups to self),
+        *     'remove-self' => array( removable groups from self) )
         */
        static function changeableByGroup( $group ) {
                global $wgAddGroups, $wgRemoveGroups, $wgGroupsAddToSelf, $wgGroupsRemoveFromSelf;
@@ -3573,27 +3582,31 @@ class User {
         * @param $byEmail Boolean: account made by email?
         * @param $reason String: user supplied reason
         */
-       public function addNewUserLogEntry( $creator, $byEmail = false ) {
-               global $wgUser, $wgNewUserLog;
+       public function addNewUserLogEntry( $byEmail = false, $reason = '' ) {
+               global $wgUser, $wgContLang, $wgNewUserLog;
                if( empty( $wgNewUserLog ) ) {
                        return true; // disabled
                }
 
-               $action = ( $creator == $wgUser )
-                       ? 'create2' # Safe to publish the creator
-                       : 'create'; # Creator is an IP, don't splash it all over Special:Log
-
-               $message = $byEmail
-                       ? wfMsgForContent( 'newuserlog-byemail' )
-                       : '';
-
+               if( $this->getName() == $wgUser->getName() ) {
+                       $action = 'create';
+               } else {
+                       $action = 'create2';
+                       if ( $byEmail ) {
+                               if ( $reason === '' ) {
+                                       $reason = wfMsgForContent( 'newuserlog-byemail' );
+                               } else {
+                                       $reason = $wgContLang->commaList( array(
+                                               $reason, wfMsgForContent( 'newuserlog-byemail' ) ) );
+                               }
+                       }
+               }
                $log = new LogPage( 'newusers' );
                $log->addEntry(
                        $action,
                        $this->getUserPage(),
-                       $message,
-                       array( $this->getId() ),
-                       $creator
+                       $reason,
+                       array( $this->getId() )
                );
                return true;
        }
@@ -3603,18 +3616,12 @@ class User {
         * Used by things like CentralAuth and perhaps other authplugins.
         */
        public function addNewUserLogEntryAutoCreate() {
-               global $wgNewUserLog;
-               if( empty( $wgNewUserLog ) ) {
+               global $wgNewUserLog, $wgLogAutocreatedAccounts;
+               if( !$wgNewUserLog || !$wgLogAutocreatedAccounts ) {
                        return true; // disabled
                }
                $log = new LogPage( 'newusers', false );
-               $log->addEntry(
-                       'autocreate',
-                       $this->getUserPage(),
-                       '',
-                       array( $this->getId() ),
-                       $this->getId()
-                       );
+               $log->addEntry( 'autocreate', $this->getUserPage(), '', array( $this->getId() ) );
                return true;
        }
 
diff --git a/includes/resourceloader/ResourceLoaderUserGroupsModule.php b/includes/resourceloader/ResourceLoaderUserGroupsModule.php
deleted file mode 100644 (file)
index c81a999..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-<?php
-/**
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @author Trevor Parscal
- * @author Roan Kattouw
- */
-
-/**
- * Module for user customizations
- */
-class ResourceLoaderUserGroupsModule extends ResourceLoaderWikiModule {
-
-       /* Protected Methods */
-       protected $origin = self::ORIGIN_USER_SITEWIDE;
-
-       protected function getPages( ResourceLoaderContext $context ) {
-               if ( $context->getUser() ) {
-                       $user = User::newFromName( $context->getUser() );
-                       if( $user instanceof User ){
-                               $pages = array();
-                               foreach( $user->getEffectiveGroups() as $group ){
-                                       if( in_array( $group, array( '*', 'user' ) ) ){
-                                               continue;
-                                       }
-                                       $g = ucfirst( $group );
-                                       $pages["MediaWiki:$g.js"] = array( 'type' => 'script' );
-                                       $pages["MediaWiki:$g.css"] = array( 'type' => 'style' );
-                               }
-                               return $pages;
-                       }
-               }
-               return array();
-       }
-       
-       /* Methods */
-       
-       public function getGroup() {
-               return 'user';
-       }
-       
-       public function getFlip( $context ) {
-               global $wgContLang;
-
-               return $wgContLang->getDir() !== $context->getDirection();
-       }
-}
index fd8bdd8..256cc90 100644 (file)
  * @ingroup SpecialPage
  */
 class SpecialResetpass extends SpecialPage {
-
-       public $mFormFields = array(
-               'NameInfo' => array(
-                       'type'          => 'info',
-                       'label-message' => 'yourname',
-                       'default'       => '',
-               ),
-               'Name' => array(
-                       'type'          => 'hidden',
-                       'name'          => 'wpName',
-                       'default'       => null,
-               ),
-               'OldPassword' => array(
-                       'type'          => 'password',
-                       'label-message' => 'oldpassword',
-                       'size'          => '20',
-                       'id'            => 'wpPassword',
-                       'required'      => '',
-               ),
-               'NewPassword' => array(
-                       'type'          => 'password',
-                       'label-message' => 'newpassword',
-                       'size'          => '20',
-                       'id'            => 'wpNewPassword',
-                       'required'      => '',
-               ),
-               'Retype' => array(
-                       'type'          => 'password',
-                       'label-message' => 'retypenew',
-                       'size'          => '20',
-                       'id'            => 'wpRetype',
-                       'required'      => '',
-               ),
-               'Remember' => array(
-                       'type'          => 'check',
-                       'id'            => 'wpRemember',
-               ),
-       );
-
-       protected $mUsername;
-       protected $mLogin;
-
        public function __construct() {
-               global $wgRequest, $wgUser, $wgLang, $wgCookieExpiration;
-
                parent::__construct( 'Resetpass' );
-               $this->mFormFields['Retype']['validation-callback'] = array( 'SpecialCreateAccount', 'formValidateRetype' );
-
-               $this->mUsername = $wgRequest->getVal( 'wpName', $wgUser->getName() );
-               $this->mReturnTo = $wgRequest->getVal( 'returnto' );
-               $this->mReturnToQuery = $wgRequest->getVal( 'returntoquery' );
-
-               $this->mFormFields['Remember']['label'] = wfMsgExt(
-                       'remembermypassword',
-                       'parseinline',
-                       $wgLang->formatNum( ceil( $wgCookieExpiration / 86400 ) )
-               );
        }
 
        /**
         * Main execution point
         */
-       public function execute( $par ) {
+       function execute( $par ) {
                global $wgUser, $wgAuth, $wgOut, $wgRequest;
 
                if ( wfReadOnly() ) {
@@ -97,134 +42,196 @@ class SpecialResetpass extends SpecialPage {
                        return;
                }
 
+               $this->mUserName = $wgRequest->getVal( 'wpName' );
+               $this->mOldpass = $wgRequest->getVal( 'wpPassword' );
+               $this->mNewpass = $wgRequest->getVal( 'wpNewPassword' );
+               $this->mRetype = $wgRequest->getVal( 'wpRetype' );
+               $this->mDomain = $wgRequest->getVal( 'wpDomain' );
+               
                $this->setHeaders();
                $this->outputHeader();
                $wgOut->disallowUserJs();
 
-               if( wfReadOnly() ){
-                       $wgOut->readOnlyPage();
-                       return false;
-               }
-               if( !$wgAuth->allowPasswordChange() ) {
-                       $wgOut->showErrorPage( 'errorpagetitle', 'resetpass_forbidden' );
-                       return false;
-               }
-
                if( !$wgRequest->wasPosted() && !$wgUser->isLoggedIn() ) {
-                       $wgOut->showErrorPage( 'errorpagetitle', 'resetpass-no-info' );
-                       return false;
+                       $this->error( wfMsg( 'resetpass-no-info' ) );
+                       return;
                }
 
-               $this->getForm()->show();
-
-       }
-
-       public function formSubmitCallback( $data ){
-               $data['Password'] = $data['OldPassword'];
-               $this->mLogin =  new Login( $data );
-               $result = $this->attemptReset( $data );
+               if( $wgRequest->wasPosted() && $wgRequest->getBool( 'wpCancel' ) ) {
+                       $this->doReturnTo();
+                       return;
+               }
 
-               if( $result === true ){
-                       # Log the user in if they're not already (ie we're
-                       # coming from the e-mail-password-reset route
-                       global $wgUser;
-                       if( !$wgUser->isLoggedIn() ) {
-                               $this->mLogin->attemptLogin( $data['NewPassword'] );
-                               # Redirect out to the appropriate target.
-                               SpecialUserlogin::successfulLogin(
-                                       'resetpass_success',
-                                       $this->mReturnTo,
-                                       $this->mReturnToQuery,
-                                       $this->mLogin->mLoginResult
-                               );
-                       } else {
-                               # Redirect out to the appropriate target.
-                               SpecialUserlogin::successfulLogin(
-                                       'resetpass_success',
-                                       $this->mReturnTo,
-                                       $this->mReturnToQuery
-                               );
+               if( $wgRequest->wasPosted() && $wgUser->matchEditToken( $wgRequest->getVal( 'token' ) ) ) {
+                       try {
+                               $wgAuth->setDomain( $this->mDomain );
+                               if( !$wgAuth->allowPasswordChange() ) {
+                                       $this->error( wfMsg( 'resetpass_forbidden' ) );
+                                       return;
+                               }
+
+                               $this->attemptReset( $this->mNewpass, $this->mRetype );
+                               $wgOut->addWikiMsg( 'resetpass_success' );
+                               if( !$wgUser->isLoggedIn() ) {
+                                       LoginForm::setLoginToken();
+                                       $token = LoginForm::getLoginToken();
+                                       $data = array(
+                                               'action'       => 'submitlogin',
+                                               'wpName'       => $this->mUserName,
+                                               'wpDomain'     => $this->mDomain,
+                                               'wpLoginToken' => $token,
+                                               'wpPassword'   => $this->mNewpass,
+                                               'returnto'     => $wgRequest->getVal( 'returnto' ),
+                                       );
+                                       if( $wgRequest->getCheck( 'wpRemember' ) ) {
+                                               $data['wpRemember'] = 1;
+                                       }
+                                       $login = new LoginForm( new FauxRequest( $data, true ) );
+                                       $login->execute( null );
+                               }
+                               $this->doReturnTo();
+                       } catch( PasswordError $e ) {
+                               $this->error( $e->getMessage() );
                        }
-                       return true;
-               } else {
-                       return $result;
                }
+               $this->showForm();
+       }
+       
+       function doReturnTo() {
+               global $wgRequest, $wgOut;
+               $titleObj = Title::newFromText( $wgRequest->getVal( 'returnto' ) );
+               if ( !$titleObj instanceof Title ) {
+                       $titleObj = Title::newMainPage();
+               }
+               $wgOut->redirect( $titleObj->getFullURL() );
+       }
+
+       function error( $msg ) {
+               global $wgOut;
+               $wgOut->addHTML( Xml::element('p', array( 'class' => 'error' ), $msg ) );
        }
 
-       public function getForm( $reset=false ) {
-               global $wgOut, $wgUser, $wgRequest;
+       function showForm() {
+               global $wgOut, $wgUser, $wgRequest, $wgLivePasswordStrengthChecks;
 
-               if( $reset || $wgRequest->getCheck( 'reset' ) ){
-                       # Request is coming from Special:UserLogin after it
-                       # authenticated someone with a temporary password.
-                       $this->mFormFields['OldPassword']['label-message'] = 'resetpass-temp-password';
+               if ( $wgLivePasswordStrengthChecks ) {
+                       $wgOut->addPasswordSecurity( 'wpNewPassword', 'wpRetype' );
+               }
+               $self = $this->getTitle();
+               if ( !$this->mUserName ) {
+                       $this->mUserName = $wgUser->getName();
+               }
+               $rememberMe = '';
+               if ( !$wgUser->isLoggedIn() ) {
+                       global $wgCookieExpiration, $wgLang;
+                       $rememberMe = '<tr>' .
+                               '<td></td>' .
+                               '<td class="mw-input">' .
+                                       Xml::checkLabel( 
+                                               wfMsgExt( 'remembermypassword', 'parsemag', $wgLang->formatNum( ceil( $wgCookieExpiration / ( 3600 * 24 ) ) ) ),
+                                               'wpRemember', 'wpRemember',
+                                               $wgRequest->getCheck( 'wpRemember' ) ) .
+                               '</td>' .
+                       '</tr>';
                        $submitMsg = 'resetpass_submit';
-                       $this->mFormFields['OldPassword']['default'] = $wgRequest->getText( 'wpPassword' );
-                       #perpetuate
-                       $this->mFormFields['reset'] = array(
-                               'type' => 'hidden',
-                               'default' => '1',
-                       );
+                       $oldpassMsg = 'resetpass-temp-password';
                } else {
-                       unset( $this->mFormFields['Remember'] );
+                       $oldpassMsg = 'oldpassword';
                        $submitMsg = 'resetpass-submit-loggedin';
                }
+               $wgOut->addHTML(
+                       Xml::fieldset( wfMsg( 'resetpass_header' ) ) .
+                       Xml::openElement( 'form',
+                               array(
+                                       'method' => 'post',
+                                       'action' => $self->getLocalUrl(),
+                                       'id' => 'mw-resetpass-form' ) ) . "\n" .
+                       Html::hidden( 'token', $wgUser->editToken() ) . "\n" .
+                       Html::hidden( 'wpName', $this->mUserName ) . "\n" .
+                       Html::hidden( 'wpDomain', $this->mDomain ) . "\n" .
+                       Html::hidden( 'returnto', $wgRequest->getVal( 'returnto' ) ) . "\n" .
+                       wfMsgExt( 'resetpass_text', array( 'parse' ) ) . "\n" .
+                       Xml::openElement( 'table', array( 'id' => 'mw-resetpass-table' ) ) . "\n" .
+                       $this->pretty( array(
+                               array( 'wpName', 'username', 'text', $this->mUserName, '' ),
+                               array( 'wpPassword', $oldpassMsg, 'password', $this->mOldpass, '' ),
+                               array( 'wpNewPassword', 'newpassword', 'password', null, '<div id="password-strength"></div>' ),
+                               array( 'wpRetype', 'retypenew', 'password', null, '<div id="password-retype"></div>' ),
+                       ) ) . "\n" .
+                       $rememberMe .
+                       "<tr>\n" .
+                               "<td></td>\n" .
+                               '<td class="mw-input">' .
+                                       Xml::submitButton( wfMsg( $submitMsg ) ) .
+                                       Xml::submitButton( wfMsg( 'resetpass-submit-cancel' ), array( 'name' => 'wpCancel' ) ) .
+                               "</td>\n" .
+                       "</tr>\n" .
+                       Xml::closeElement( 'table' ) .
+                       Xml::closeElement( 'form' ) .
+                       Xml::closeElement( 'fieldset' ) . "\n"
+               );
+       }
 
-               $this->mFormFields['Name']['default'] =
-               $this->mFormFields['NameInfo']['default'] = $this->mUsername;
-
-               $form = new HTMLForm( $this->mFormFields, '' );
-               $form->suppressReset();
-               $form->setSubmitText( wfMsg( $submitMsg ) );
-               $form->setTitle( $this->getTitle() );
-               $form->addHiddenField( 'returnto', $this->mReturnTo );
-               $form->setWrapperLegend( wfMsg( 'resetpass_header' ) );
-
-               $form->setSubmitCallback( array( $this, 'formSubmitCallback' ) );
-               $form->loadData();
-
-               return $form;
+       function pretty( $fields ) {
+               $out = '';
+               foreach ( $fields as $list ) {
+                       list( $name, $label, $type, $value, $extra ) = $list;
+                       if( $type == 'text' ) {
+                               $field = htmlspecialchars( $value );
+                       } else {
+                               $attribs = array( 'id' => $name );
+                               if ( $name == 'wpNewPassword' || $name == 'wpRetype' ) {
+                                       $attribs = array_merge( $attribs,
+                                               User::passwordChangeInputAttribs() );
+                               }
+                               if ( $name == 'wpPassword' ) {
+                                       $attribs[] = 'autofocus';
+                               }
+                               $field = Html::input( $name, $value, $type, $attribs );
+                       }
+                       $out .= "<tr>\n";
+                       $out .= "\t<td class='mw-label'>";
+                       if ( $type != 'text' )
+                               $out .= Xml::label( wfMsg( $label ), $name );
+                       else 
+                               $out .=  wfMsgHtml( $label );
+                       $out .= "</td>\n";
+                       $out .= "\t<td class='mw-input'>$field</td>\n";
+                       $out .= "\t<td>$extra</td>\n";
+                       $out .= "</tr>";
+               }
+               return $out;
        }
 
        /**
-        * Try to reset the user's password
+        * @throws PasswordError when cannot set the new password because requirements not met.
         */
-       protected function attemptReset( $data ) {
-
-               if(    !$data['Name']
-                       || !$data['OldPassword']
-                       || !$data['NewPassword']
-                       || !$data['Retype'] )
-               {
-                       return false;
+       protected function attemptReset( $newpass, $retype ) {
+               $user = User::newFromName( $this->mUserName );
+               if( !$user || $user->isAnon() ) {
+                       throw new PasswordError( 'no such user' );
                }
-
-               $user = $this->mLogin->getUser();
-               if( !( $user instanceof User ) ){
-                       return wfMsgExt( 'nosuchuser', 'parse' );
+               
+               if( $newpass !== $retype ) {
+                       wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'badretype' ) );
+                       throw new PasswordError( wfMsg( 'badretype' ) );
                }
 
-               if( $data['NewPassword'] !== $data['Retype'] ) {
-                       wfRunHooks( 'PrefsPasswordAudit', array( $user, $data['NewPassword'], 'badretype' ) );
-                       return wfMsgExt( 'badretype', 'parse' );
+               if( !$user->checkTemporaryPassword($this->mOldpass) && !$user->checkPassword($this->mOldpass) ) {
+                       wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'wrongpassword' ) );
+                       throw new PasswordError( wfMsg( 'resetpass-wrong-oldpass' ) );
                }
-
-               if( !$user->checkPassword( $data['OldPassword'] ) && !$user->checkTemporaryPassword( $data['OldPassword'] ) )
-               {
-                       wfRunHooks( 'PrefsPasswordAudit', array( $user, $data['NewPassword'], 'wrongpassword' ) );
-                       return wfMsgExt( 'resetpass-wrong-oldpass', 'parse' );
-               }
-
+               
                try {
-                       $user->setPassword( $data['NewPassword'] );
-                       wfRunHooks( 'PrefsPasswordAudit', array( $user, $data['NewPassword'], 'success' ) );
+                       $user->setPassword( $this->mNewpass );
+                       wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'success' ) );
+                       $this->mNewpass = $this->mOldpass = $this->mRetypePass = '';
                } catch( PasswordError $e ) {
-                       wfRunHooks( 'PrefsPasswordAudit', array( $user, $data['NewPassword'], 'error' ) );
-                       return $e->getMessage();
+                       wfRunHooks( 'PrefsPasswordAudit', array( $user, $newpass, 'error' ) );
+                       throw new PasswordError( $e->getMessage() );
                }
-
+               
                $user->setCookies();
                $user->saveSettings();
-               return true;
        }
 }
index 085462c..553c8ae 100644 (file)
@@ -8,7 +8,6 @@ return array(
        'startup' => array( 'class' => 'ResourceLoaderStartUpModule' ),
        'user' => array( 'class' => 'ResourceLoaderUserModule' ),
        'user.options' => array( 'class' => 'ResourceLoaderUserOptionsModule' ),
-       'user.groups' => array( 'class' => 'ResourceLoaderUserGroupsModule' ),
 
        /* Skins */