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