MediaWiki REL1_40
SpecialChangeEmail.php
Go to the documentation of this file.
1<?php
28
38 private $status;
39
43 public function __construct( AuthManager $authManager ) {
44 parent::__construct( 'ChangeEmail', 'editmyprivateinfo' );
45
46 $this->setAuthManager( $authManager );
47 }
48
49 public function doesWrites() {
50 return true;
51 }
52
56 public function isListed() {
57 return $this->getAuthManager()->allowsPropertyChange( 'emailaddress' );
58 }
59
64 public function execute( $par ) {
65 $out = $this->getOutput();
66 $out->disallowUserJs();
67 $out->addModules( 'mediawiki.special.changeemail' );
68 parent::execute( $par );
69 }
70
71 protected function getLoginSecurityLevel() {
72 return $this->getName();
73 }
74
75 protected function checkExecutePermissions( User $user ) {
76 if ( !$this->getAuthManager()->allowsPropertyChange( 'emailaddress' ) ) {
77 throw new ErrorPageError( 'changeemail', 'cannotchangeemail' );
78 }
79
80 $this->requireNamedUser( 'changeemail-no-info' );
81
82 // This could also let someone check the current email address, so
83 // require both permissions.
84 if ( !$this->getAuthority()->isAllowed( 'viewmyprivateinfo' ) ) {
85 throw new PermissionsError( 'viewmyprivateinfo' );
86 }
87
88 parent::checkExecutePermissions( $user );
89 }
90
91 protected function getFormFields() {
92 $user = $this->getUser();
93
94 return [
95 'Name' => [
96 'type' => 'info',
97 'label-message' => 'username',
98 'default' => $user->getName(),
99 ],
100 'OldEmail' => [
101 'type' => 'info',
102 'label-message' => 'changeemail-oldemail',
103 'default' => $user->getEmail() ?: $this->msg( 'changeemail-none' )->text(),
104 ],
105 'NewEmail' => [
106 'type' => 'email',
107 'label-message' => 'changeemail-newemail',
108 'autofocus' => true,
109 'maxlength' => 255,
110 'help-message' => 'changeemail-newemail-help',
111 ],
112 ];
113 }
114
115 protected function getDisplayFormat() {
116 return 'ooui';
117 }
118
119 protected function alterForm( HTMLForm $form ) {
120 $form->setId( 'mw-changeemail-form' );
121 $form->setTableId( 'mw-changeemail-table' );
122 $form->setSubmitTextMsg( 'changeemail-submit' );
123 $form->addHiddenFields( $this->getRequest()->getValues( 'returnto', 'returntoquery' ) );
124
125 $form->addHeaderHtml( $this->msg( 'changeemail-header' )->parseAsBlock() );
126 $form->setSubmitID( 'change_email_submit' );
127 }
128
129 public function onSubmit( array $data ) {
130 $this->status = $this->attemptChange( $this->getUser(), $data['NewEmail'] );
131
132 return $this->status;
133 }
134
135 public function onSuccess() {
136 $request = $this->getRequest();
137
138 $returnTo = $request->getVal( 'returnto' );
139 $titleObj = $returnTo !== null ? Title::newFromText( $returnTo ) : null;
140 if ( !$titleObj instanceof Title ) {
141 $titleObj = Title::newMainPage();
142 }
143 $query = $request->getVal( 'returntoquery', '' );
144
145 if ( $this->status->value === true ) {
146 $this->getOutput()->redirect( $titleObj->getFullUrlForRedirect( $query ) );
147 } elseif ( $this->status->value === 'eauth' ) {
148 # Notify user that a confirmation email has been sent...
149 $out = $this->getOutput();
150 $out->addHTML(
151 Html::warningBox(
152 $out->msg( 'eauthentsent', $this->getUser()->getName() )->parse()
153 )
154 );
155 // just show the link to go back
156 $this->getOutput()->addReturnTo( $titleObj, wfCgiToArray( $query ) );
157 }
158 }
159
166 private function attemptChange( User $user, $newAddr ) {
167 if ( $newAddr !== '' && !Sanitizer::validateEmail( $newAddr ) ) {
168 return Status::newFatal( 'invalidemailaddress' );
169 }
170
171 $oldAddr = $user->getEmail();
172 if ( $newAddr === $oldAddr ) {
173 return Status::newFatal( 'changeemail-nochange' );
174 }
175
176 if ( strlen( $newAddr ) > 255 ) {
177 return Status::newFatal( 'changeemail-maxlength' );
178 }
179
180 // To prevent spam, rate limit adding a new address, but do
181 // not rate limit removing an address.
182 if ( $newAddr !== '' && $user->pingLimiter( 'changeemail' ) ) {
183 return Status::newFatal( 'actionthrottledtext' );
184 }
185
186 $userLatest = $user->getInstanceForUpdate();
187 $status = $userLatest->setEmailWithConfirmation( $newAddr );
188 if ( !$status->isGood() ) {
189 return $status;
190 }
191
192 LoggerFactory::getInstance( 'authentication' )->info(
193 'Changing email address for {user} from {oldemail} to {newemail}', [
194 'user' => $userLatest->getName(),
195 'oldemail' => $oldAddr,
196 'newemail' => $newAddr,
197 ]
198 );
199
200 $this->getHookRunner()->onPrefsEmailAudit( $userLatest, $oldAddr, $newAddr );
201
202 $userLatest->saveSettings();
203
204 return $status;
205 }
206
207 public function requiresUnblock() {
208 return false;
209 }
210
211 protected function getGroupName() {
212 return 'users';
213 }
214}
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:153
addHeaderHtml( $html, $section=null)
Add HTML to the header, inside the form.
Definition HTMLForm.php:895
setTableId( $id)
Set the id of the <table> or outermost <div> element.
setSubmitTextMsg( $msg)
Set the text for the submit button to a message.
setId( $id)
setSubmitID( $t)
Set the id for the submit button.
addHiddenFields(array $fields)
Add an array of hidden fields to the output Array values are discarded for security reasons (per WebR...
This serves as the entry point to the authentication system.
This class is a collection of static functions that serve two purposes:
Definition Html.php:55
PSR-3 logger instance factory.
Represents a title within MediaWiki.
Definition Title.php:82
Show an error when a user tries to do something they do not have the necessary permissions for.
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, default to requiresPost()
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 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.
isGood()
Returns whether the operation completed and didn't have any error or warnings.
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition Status.php:46
internal since 1.36
Definition User.php:71
getName()
Get the user name, or the IP of an anonymous user.
Definition User.php:1680
pingLimiter( $action='edit', $incrBy=1)
Primitive rate limits: enforce maximum actions per time period to put a brake on flooding.
Definition User.php:1479
getEmail()
Get the user's e-mail address.
Definition User.php:1998
getInstanceForUpdate()
Get a new instance of this user that was loaded from the primary DB via a locking read.
Definition User.php:3424