Use local context to get message instead of relying on global variables
[lhc/web/wiklou.git] / includes / specials / SpecialPasswordReset.php
index 5cdb1c0..b1189ad 100644 (file)
  */
 class SpecialPasswordReset extends FormSpecialPage {
 
+       /**
+        * @var Message
+        */
+       private $email;
+
+       /**
+        * @var Status
+        */
+       private $result;
+
        public function __construct() {
                parent::__construct( 'PasswordReset' );
        }
 
        public function userCanExecute( User $user ) {
+               return $this->canChangePassword( $user ) === true && parent::userCanExecute( $user );
+       }
+
+       public function checkExecutePermissions( User $user ) {
                $error = $this->canChangePassword( $user );
                if ( is_string( $error ) ) {
                        throw new ErrorPageError( 'internalerror', $error );
-               } else if ( !$error ) {
+               } elseif ( !$error ) {
                        throw new ErrorPageError( 'internalerror', 'resetpass_forbidden' );
                }
 
-               return parent::userCanExecute( $user );
+               return parent::checkExecutePermissions( $user );
        }
 
        protected function getFormFields() {
-               global $wgPasswordResetRoutes;
+               global $wgPasswordResetRoutes, $wgAuth;
                $a = array();
                if ( isset( $wgPasswordResetRoutes['username'] ) && $wgPasswordResetRoutes['username'] ) {
                        $a['Username'] = array(
@@ -60,6 +74,23 @@ class SpecialPasswordReset extends FormSpecialPage {
                        );
                }
 
+               if ( isset( $wgPasswordResetRoutes['domain'] ) && $wgPasswordResetRoutes['domain'] ) {
+                       $domains = $wgAuth->domainList();
+                       $a['Domain'] = array(
+                               'type' => 'select',
+                               'options' => $domains,
+                               'label-message' => 'passwordreset-domain',
+                       );
+               }
+
+               if( $this->getUser()->isAllowed( 'passwordreset' ) ){
+                       $a['Capture'] = array(
+                               'type' => 'check',
+                               'label-message' => 'passwordreset-capture',
+                               'help-message' => 'passwordreset-capture-help',
+                       );
+               }
+
                return $a;
        }
 
@@ -76,6 +107,9 @@ class SpecialPasswordReset extends FormSpecialPage {
                if ( isset( $wgPasswordResetRoutes['email'] ) && $wgPasswordResetRoutes['email'] ) {
                        $i++;
                }
+               if ( isset( $wgPasswordResetRoutes['domain'] ) && $wgPasswordResetRoutes['domain'] ) {
+                       $i++;
+               }
                return wfMessage( 'passwordreset-pretext', $i )->parseAsBlock();
        }
 
@@ -87,6 +121,25 @@ class SpecialPasswordReset extends FormSpecialPage {
         * @return Bool|Array
         */
        public function onSubmit( array $data ) {
+               global $wgAuth;
+
+               if ( isset( $data['Domain'] ) ) {
+                       if ( $wgAuth->validDomain( $data['Domain'] ) ) {
+                               $wgAuth->setDomain( $data['Domain'] );
+                       } else {
+                               $wgAuth->setDomain( 'invaliddomain' );
+                       }
+               }
+
+               if( isset( $data['Capture'] ) && !$this->getUser()->isAllowed( 'passwordreset' ) ){
+                       // The user knows they don't have the passwordreset permission, but they tried to spoof the form.  That's naughty
+                       throw new PermissionsError( 'passwordreset' );
+               }
+
+               /**
+                * @var $firstUser User
+                * @var $users User[]
+                */
 
                if ( isset( $data['Username'] ) && $data['Username'] !== '' ) {
                        $method = 'username';
@@ -178,15 +231,15 @@ class SpecialPasswordReset extends FormSpecialPage {
                        $password = $user->randomPassword();
                        $user->setNewpassword( $password );
                        $user->saveSettings();
-                       $passwords[] = wfMessage( 'passwordreset-emailelement', $user->getName(), $password );
+                       $passwords[] = wfMessage( 'passwordreset-emailelement', $user->getName(), $password )->plain(); // We'll escape the whole thing later
                }
                $passwordBlock = implode( "\n\n", $passwords );
 
                // Send in the user's language; which should hopefully be the same
                $userLanguage = $firstUser->getOption( 'language' );
 
-               $body = wfMessage( $msg )->inLanguage( $userLanguage );
-               $body->params(
+               $this->email = wfMessage( $msg )->inLanguage( $userLanguage );
+               $this->email->params(
                        $username,
                        $passwordBlock,
                        count( $passwords ),
@@ -196,18 +249,38 @@ class SpecialPasswordReset extends FormSpecialPage {
 
                $title = wfMessage( 'passwordreset-emailtitle' );
 
-               $result = $firstUser->sendMail( $title->text(), $body->text() );
+               $this->result = $firstUser->sendMail( $title->escaped(), $this->email->escaped() );
+
+               // Blank the email if the user is not supposed to see it
+               if( !isset( $data['Capture'] ) || !$data['Capture'] ) {
+                       $this->email = null;
+               }
 
-               if ( $result->isGood() ) {
+               if ( $this->result->isGood() ) {
+                       return true;
+               } elseif( isset( $data['Capture'] ) && $data['Capture'] ){
+                       // The email didn't send, but maybe they knew that and that's why they captured it
                        return true;
                } else {
                        // @todo FIXME: The email didn't send, but we have already set the password throttle
                        // timestamp, so they won't be able to try again until it expires...  :(
-                       return array( array( 'mailerror', $result->getMessage() ) );
+                       return array( array( 'mailerror', $this->result->getMessage() ) );
                }
        }
 
        public function onSuccess() {
+               if( $this->getUser()->isAllowed( 'passwordreset' ) && $this->email != null ){
+                       // @todo: Logging
+
+                       if( $this->result->isGood() ){
+                               $this->getOutput()->addWikiMsg( 'passwordreset-emailsent-capture' );
+                       } else {
+                               $this->getOutput()->addWikiMsg( 'passwordreset-emailerror-capture', $this->result->getMessage() );
+                       }
+
+                       $this->getOutput()->addHTML( Html::rawElement( 'pre', array(), $this->email->escaped() ) );
+               }
+
                $this->getOutput()->addWikiMsg( 'passwordreset-emailsent' );
                $this->getOutput()->returnToMain();
        }
@@ -241,9 +314,7 @@ class SpecialPasswordReset extends FormSpecialPage {
         * @return Bool
         */
        function isListed() {
-               global $wgUser;
-
-               if ( $this->canChangePassword( $wgUser ) === true ) {
+               if ( $this->canChangePassword( $this->getUser() ) === true ) {
                        return parent::isListed();
                }