Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 88 |
|
0.00% |
0 / 14 |
CRAP | |
0.00% |
0 / 1 |
SpecialChangeEmail | |
0.00% |
0 / 87 |
|
0.00% |
0 / 14 |
812 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
doesWrites | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
isListed | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
execute | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
getLoginSecurityLevel | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
checkExecutePermissions | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
12 | |||
getFormFields | |
0.00% |
0 / 20 |
|
0.00% |
0 / 1 |
6 | |||
getDisplayFormat | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
alterForm | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
2 | |||
onSubmit | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
onSuccess | |
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
30 | |||
attemptChange | |
0.00% |
0 / 25 |
|
0.00% |
0 / 1 |
72 | |||
requiresUnblock | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getGroupName | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | /** |
3 | * Implements Special:ChangeEmail |
4 | * |
5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation; either version 2 of the License, or |
8 | * (at your option) any later version. |
9 | * |
10 | * This program is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * GNU General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU General Public License along |
16 | * with this program; if not, write to the Free Software Foundation, Inc., |
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
18 | * http://www.gnu.org/copyleft/gpl.html |
19 | * |
20 | * @file |
21 | * @ingroup SpecialPage |
22 | */ |
23 | |
24 | namespace MediaWiki\Specials; |
25 | |
26 | use ErrorPageError; |
27 | use MediaWiki\Auth\AuthManager; |
28 | use MediaWiki\Html\Html; |
29 | use MediaWiki\HTMLForm\HTMLForm; |
30 | use MediaWiki\Logger\LoggerFactory; |
31 | use MediaWiki\Parser\Sanitizer; |
32 | use MediaWiki\SpecialPage\FormSpecialPage; |
33 | use MediaWiki\Status\Status; |
34 | use MediaWiki\Title\Title; |
35 | use MediaWiki\User\User; |
36 | use PermissionsError; |
37 | |
38 | /** |
39 | * Let users change their email address. |
40 | * |
41 | * @ingroup SpecialPage |
42 | */ |
43 | class SpecialChangeEmail extends FormSpecialPage { |
44 | /** |
45 | * @var Status |
46 | */ |
47 | private $status; |
48 | |
49 | /** |
50 | * @param AuthManager $authManager |
51 | */ |
52 | public function __construct( AuthManager $authManager ) { |
53 | parent::__construct( 'ChangeEmail', 'editmyprivateinfo' ); |
54 | |
55 | $this->setAuthManager( $authManager ); |
56 | } |
57 | |
58 | public function doesWrites() { |
59 | return true; |
60 | } |
61 | |
62 | /** |
63 | * @return bool |
64 | */ |
65 | public function isListed() { |
66 | return $this->getAuthManager()->allowsPropertyChange( 'emailaddress' ); |
67 | } |
68 | |
69 | /** |
70 | * Main execution point |
71 | * @param string|null $par |
72 | */ |
73 | public function execute( $par ) { |
74 | $out = $this->getOutput(); |
75 | $out->disallowUserJs(); |
76 | $out->addModules( 'mediawiki.special.changeemail' ); |
77 | parent::execute( $par ); |
78 | } |
79 | |
80 | protected function getLoginSecurityLevel() { |
81 | return $this->getName(); |
82 | } |
83 | |
84 | protected function checkExecutePermissions( User $user ) { |
85 | if ( !$this->getAuthManager()->allowsPropertyChange( 'emailaddress' ) ) { |
86 | throw new ErrorPageError( 'changeemail', 'cannotchangeemail' ); |
87 | } |
88 | |
89 | $this->requireNamedUser( 'changeemail-no-info' ); |
90 | |
91 | // This could also let someone check the current email address, so |
92 | // require both permissions. |
93 | if ( !$this->getAuthority()->isAllowed( 'viewmyprivateinfo' ) ) { |
94 | throw new PermissionsError( 'viewmyprivateinfo' ); |
95 | } |
96 | |
97 | parent::checkExecutePermissions( $user ); |
98 | } |
99 | |
100 | protected function getFormFields() { |
101 | $user = $this->getUser(); |
102 | |
103 | return [ |
104 | 'Name' => [ |
105 | 'type' => 'info', |
106 | 'label-message' => 'username', |
107 | 'default' => $user->getName(), |
108 | ], |
109 | 'OldEmail' => [ |
110 | 'type' => 'info', |
111 | 'label-message' => 'changeemail-oldemail', |
112 | 'default' => $user->getEmail() ?: $this->msg( 'changeemail-none' )->text(), |
113 | ], |
114 | 'NewEmail' => [ |
115 | 'type' => 'email', |
116 | 'label-message' => 'changeemail-newemail', |
117 | 'autofocus' => true, |
118 | 'maxlength' => 255, |
119 | 'help-message' => 'changeemail-newemail-help', |
120 | ], |
121 | ]; |
122 | } |
123 | |
124 | protected function getDisplayFormat() { |
125 | return 'ooui'; |
126 | } |
127 | |
128 | protected function alterForm( HTMLForm $form ) { |
129 | $form->setId( 'mw-changeemail-form' ); |
130 | $form->setTableId( 'mw-changeemail-table' ); |
131 | $form->setSubmitTextMsg( 'changeemail-submit' ); |
132 | $form->addHiddenFields( $this->getRequest()->getValues( 'returnto', 'returntoquery' ) ); |
133 | |
134 | $form->addHeaderHtml( $this->msg( 'changeemail-header' )->parseAsBlock() ); |
135 | $form->setSubmitID( 'change_email_submit' ); |
136 | } |
137 | |
138 | public function onSubmit( array $data ) { |
139 | $this->status = $this->attemptChange( $this->getUser(), $data['NewEmail'] ); |
140 | |
141 | return $this->status; |
142 | } |
143 | |
144 | public function onSuccess() { |
145 | $request = $this->getRequest(); |
146 | |
147 | $returnTo = $request->getVal( 'returnto' ); |
148 | $titleObj = $returnTo !== null ? Title::newFromText( $returnTo ) : null; |
149 | if ( !$titleObj instanceof Title ) { |
150 | $titleObj = Title::newMainPage(); |
151 | } |
152 | $query = $request->getVal( 'returntoquery', '' ); |
153 | |
154 | if ( $this->status->value === true ) { |
155 | $this->getOutput()->redirect( $titleObj->getFullUrlForRedirect( $query ) ); |
156 | } elseif ( $this->status->value === 'eauth' ) { |
157 | # Notify user that a confirmation email has been sent... |
158 | $out = $this->getOutput(); |
159 | $out->addHTML( |
160 | Html::warningBox( |
161 | $out->msg( 'eauthentsent', $this->getUser()->getName() )->parse() |
162 | ) |
163 | ); |
164 | // just show the link to go back |
165 | $this->getOutput()->addReturnTo( $titleObj, wfCgiToArray( $query ) ); |
166 | } |
167 | } |
168 | |
169 | /** |
170 | * @param User $user |
171 | * @param string $newAddr |
172 | * |
173 | * @return Status |
174 | */ |
175 | private function attemptChange( User $user, $newAddr ) { |
176 | if ( $newAddr !== '' && !Sanitizer::validateEmail( $newAddr ) ) { |
177 | return Status::newFatal( 'invalidemailaddress' ); |
178 | } |
179 | |
180 | $oldAddr = $user->getEmail(); |
181 | if ( $newAddr === $oldAddr ) { |
182 | return Status::newFatal( 'changeemail-nochange' ); |
183 | } |
184 | |
185 | if ( strlen( $newAddr ) > 255 ) { |
186 | return Status::newFatal( 'changeemail-maxlength' ); |
187 | } |
188 | |
189 | // To prevent spam, rate limit adding a new address, but do |
190 | // not rate limit removing an address. |
191 | if ( $newAddr !== '' ) { |
192 | // Enforce permissions, user blocks, and rate limits |
193 | $status = $this->authorizeAction( 'changeemail' ); |
194 | if ( !$status->isGood() ) { |
195 | return Status::wrap( $status ); |
196 | } |
197 | } |
198 | |
199 | $userLatest = $user->getInstanceForUpdate(); |
200 | $status = $userLatest->setEmailWithConfirmation( $newAddr ); |
201 | if ( !$status->isGood() ) { |
202 | return $status; |
203 | } |
204 | |
205 | LoggerFactory::getInstance( 'authentication' )->info( |
206 | 'Changing email address for {user} from {oldemail} to {newemail}', [ |
207 | 'user' => $userLatest->getName(), |
208 | 'oldemail' => $oldAddr, |
209 | 'newemail' => $newAddr, |
210 | ] |
211 | ); |
212 | |
213 | $this->getHookRunner()->onPrefsEmailAudit( $userLatest, $oldAddr, $newAddr ); |
214 | |
215 | $userLatest->saveSettings(); |
216 | |
217 | return $status; |
218 | } |
219 | |
220 | public function requiresUnblock() { |
221 | return false; |
222 | } |
223 | |
224 | protected function getGroupName() { |
225 | return 'login'; |
226 | } |
227 | } |
228 | |
229 | /** @deprecated class alias since 1.41 */ |
230 | class_alias( SpecialChangeEmail::class, 'SpecialChangeEmail' ); |