MediaWiki  master
SpecialChangeEmail.php
Go to the documentation of this file.
1 <?php
26 
36  private $status;
37 
41  public function __construct( AuthManager $authManager ) {
42  parent::__construct( 'ChangeEmail', 'editmyprivateinfo' );
43 
44  $this->setAuthManager( $authManager );
45  }
46 
47  public function doesWrites() {
48  return true;
49  }
50 
54  public function isListed() {
55  return $this->getAuthManager()->allowsPropertyChange( 'emailaddress' );
56  }
57 
62  public function execute( $par ) {
63  $out = $this->getOutput();
64  $out->disallowUserJs();
65  $out->addModules( 'mediawiki.special.changeemail' );
66  parent::execute( $par );
67  }
68 
69  protected function getLoginSecurityLevel() {
70  return $this->getName();
71  }
72 
73  protected function checkExecutePermissions( User $user ) {
74  if ( !$this->getAuthManager()->allowsPropertyChange( 'emailaddress' ) ) {
75  throw new ErrorPageError( 'changeemail', 'cannotchangeemail' );
76  }
77 
78  $this->requireNamedUser( 'changeemail-no-info' );
79 
80  // This could also let someone check the current email address, so
81  // require both permissions.
82  if ( !$this->getAuthority()->isAllowed( 'viewmyprivateinfo' ) ) {
83  throw new PermissionsError( 'viewmyprivateinfo' );
84  }
85 
86  parent::checkExecutePermissions( $user );
87  }
88 
89  protected function getFormFields() {
90  $user = $this->getUser();
91 
92  return [
93  'Name' => [
94  'type' => 'info',
95  'label-message' => 'username',
96  'default' => $user->getName(),
97  ],
98  'OldEmail' => [
99  'type' => 'info',
100  'label-message' => 'changeemail-oldemail',
101  'default' => $user->getEmail() ?: $this->msg( 'changeemail-none' )->text(),
102  ],
103  'NewEmail' => [
104  'type' => 'email',
105  'label-message' => 'changeemail-newemail',
106  'autofocus' => true,
107  'maxlength' => 255,
108  'help-message' => 'changeemail-newemail-help',
109  ],
110  ];
111  }
112 
113  protected function getDisplayFormat() {
114  return 'ooui';
115  }
116 
117  protected function alterForm( HTMLForm $form ) {
118  $form->setId( 'mw-changeemail-form' );
119  $form->setTableId( 'mw-changeemail-table' );
120  $form->setSubmitTextMsg( 'changeemail-submit' );
121  $form->addHiddenFields( $this->getRequest()->getValues( 'returnto', 'returntoquery' ) );
122 
123  $form->addHeaderText( $this->msg( 'changeemail-header' )->parseAsBlock() );
124  $form->setSubmitID( 'change_email_submit' );
125  }
126 
127  public function onSubmit( array $data ) {
128  $this->status = $this->attemptChange( $this->getUser(), $data['NewEmail'] );
129 
130  return $this->status;
131  }
132 
133  public function onSuccess() {
134  $request = $this->getRequest();
135 
136  $returnTo = $request->getVal( 'returnto' );
137  $titleObj = $returnTo !== null ? Title::newFromText( $returnTo ) : null;
138  if ( !$titleObj instanceof Title ) {
139  $titleObj = Title::newMainPage();
140  }
141  $query = $request->getVal( 'returntoquery', '' );
142 
143  if ( $this->status->value === true ) {
144  $this->getOutput()->redirect( $titleObj->getFullUrlForRedirect( $query ) );
145  } elseif ( $this->status->value === 'eauth' ) {
146  # Notify user that a confirmation email has been sent...
147  $out = $this->getOutput();
148  $out->addHTML(
150  $out->msg( 'eauthentsent', $this->getUser()->getName() )->parse()
151  )
152  );
153  // just show the link to go back
154  $this->getOutput()->addReturnTo( $titleObj, wfCgiToArray( $query ) );
155  }
156  }
157 
164  private function attemptChange( User $user, $newAddr ) {
165  if ( $newAddr !== '' && !Sanitizer::validateEmail( $newAddr ) ) {
166  return Status::newFatal( 'invalidemailaddress' );
167  }
168 
169  $oldAddr = $user->getEmail();
170  if ( $newAddr === $oldAddr ) {
171  return Status::newFatal( 'changeemail-nochange' );
172  }
173 
174  if ( strlen( $newAddr ) > 255 ) {
175  return Status::newFatal( 'changeemail-maxlength' );
176  }
177 
178  // To prevent spam, rate limit adding a new address, but do
179  // not rate limit removing an address.
180  if ( $newAddr !== '' && $user->pingLimiter( 'changeemail' ) ) {
181  return Status::newFatal( 'actionthrottledtext' );
182  }
183 
184  $userLatest = $user->getInstanceForUpdate();
185  $status = $userLatest->setEmailWithConfirmation( $newAddr );
186  if ( !$status->isGood() ) {
187  return $status;
188  }
189 
190  LoggerFactory::getInstance( 'authentication' )->info(
191  'Changing email address for {user} from {oldemail} to {newemail}', [
192  'user' => $userLatest->getName(),
193  'oldemail' => $oldAddr,
194  'newemail' => $newAddr,
195  ]
196  );
197 
198  $this->getHookRunner()->onPrefsEmailAudit( $userLatest, $oldAddr, $newAddr );
199 
200  $userLatest->saveSettings();
201 
202  return $status;
203  }
204 
205  public function requiresUnblock() {
206  return false;
207  }
208 
209  protected function getGroupName() {
210  return 'users';
211  }
212 }
wfCgiToArray( $query)
This is the logical opposite of wfArrayToCgi(): it accepts a query string as its argument and returns...
An error page which can definitely be safely rendered using the OutputPage.
Special page which uses an HTMLForm to handle processing.
string null $par
The sub-page of the special page.
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition: HTMLForm.php:150
setTableId( $id)
Set the id of the <table> or outermost <div> element.
Definition: HTMLForm.php:1752
setSubmitTextMsg( $msg)
Set the text for the submit button to a message.
Definition: HTMLForm.php:1613
setId( $id)
Definition: HTMLForm.php:1763
setSubmitID( $t)
Set the id for the submit button.
Definition: HTMLForm.php:1660
addHeaderText( $msg, $section=null)
Add HTML to the header, inside the form.
Definition: HTMLForm.php:938
addHiddenFields(array $fields)
Add an array of hidden fields to the output.
Definition: HTMLForm.php:1152
static warningBox( $html, $className='')
Return a warning box.
Definition: Html.php:775
This serves as the entry point to the authentication system.
PSR-3 logger instance factory.
Show an error when a user tries to do something they do not have the necessary permissions for.
static validateEmail( $addr)
Does a string look like an e-mail address?
Definition: Sanitizer.php:1893
Let users change their email address.
doesWrites()
Indicates whether this special page may perform database writes.
requiresUnblock()
Whether this action cannot be executed by a blocked user.
getDisplayFormat()
Get display format for the form.
onSuccess()
Do something exciting on successful processing of the form, most likely to show a confirmation messag...
alterForm(HTMLForm $form)
Play with the HTMLForm if you need to more substantially.
getFormFields()
Get an HTMLForm descriptor array.
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
checkExecutePermissions(User $user)
Called from execute() to check if the given user can perform this action.
__construct(AuthManager $authManager)
execute( $par)
Main execution point.
getLoginSecurityLevel()
Tells if the special page does something security-sensitive and needs extra defense against a stolen ...
onSubmit(array $data)
Process the form on POST submission.
getName()
Get the name of this Special Page.
getOutput()
Get the OutputPage being used for this instance.
getUser()
Shortcut to get the User executing this instance.
requireNamedUser( $reasonMsg='exception-nologin-text', $titleMsg='exception-nologin')
If the user is not logged in or is a temporary user, throws UserNotLoggedIn.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getAuthority()
Shortcut to get the Authority executing this instance.
getRequest()
Get the WebRequest being used for this instance.
setAuthManager(AuthManager $authManager)
Set the injected AuthManager from the special page constructor.
static newFatal( $message,... $parameters)
Factory function for fatal errors.
Definition: StatusValue.php:73
isGood()
Returns whether the operation completed and didn't have any error or warnings.
Represents a title within MediaWiki.
Definition: Title.php:52
static newMainPage(MessageLocalizer $localizer=null)
Create a new Title for the Main Page.
Definition: Title.php:703
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:373
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:70
getName()
Get the user name, or the IP of an anonymous user.
Definition: User.php:1670
pingLimiter( $action='edit', $incrBy=1)
Primitive rate limits: enforce maximum actions per time period to put a brake on flooding.
Definition: User.php:1469
getEmail()
Get the user's e-mail address.
Definition: User.php:1988
getInstanceForUpdate()
Get a new instance of this user that was loaded from the primary DB via a locking read.
Definition: User.php:3415