1 | <?php |
||
18 | class ChangePasswordHandler extends RequestHandler |
||
19 | { |
||
20 | /** |
||
21 | * @var Authenticator |
||
22 | */ |
||
23 | protected $authenticator; |
||
24 | |||
25 | /** |
||
26 | * @var string |
||
27 | */ |
||
28 | protected $link; |
||
29 | |||
30 | /** |
||
31 | * @var array Allowed Actions |
||
32 | */ |
||
33 | private static $allowed_actions = [ |
||
34 | 'changepassword', |
||
35 | 'changePasswordForm', |
||
36 | ]; |
||
37 | |||
38 | /** |
||
39 | * @var array URL Handlers. All should point to changepassword |
||
40 | */ |
||
41 | private static $url_handlers = [ |
||
42 | '' => 'changepassword', |
||
43 | ]; |
||
44 | |||
45 | /** |
||
46 | * @param string $link The URL to recreate this request handler |
||
47 | * @param MemberAuthenticator $authenticator |
||
48 | */ |
||
49 | public function __construct($link, MemberAuthenticator $authenticator) |
||
55 | |||
56 | /** |
||
57 | * Handle the change password request |
||
58 | * @todo this could use some spring cleaning |
||
59 | * |
||
60 | * @return array|HTTPResponse |
||
61 | */ |
||
62 | public function changepassword() |
||
145 | |||
146 | |||
147 | /** |
||
148 | * @param Member $member |
||
149 | * @param string $token |
||
150 | */ |
||
151 | protected function setSessionToken($member, $token) |
||
162 | |||
163 | /** |
||
164 | * Return a link to this request handler. |
||
165 | * The link returned is supplied in the constructor |
||
166 | * @param null $action |
||
167 | * @return string |
||
168 | */ |
||
169 | public function link($action = null) |
||
177 | |||
178 | /** |
||
179 | * Factory method for the lost password form |
||
180 | * |
||
181 | * @skipUpgrade |
||
182 | * @return ChangePasswordForm Returns the lost password form |
||
183 | */ |
||
184 | public function changePasswordForm() |
||
191 | |||
192 | /** |
||
193 | * Change the password |
||
194 | * |
||
195 | * @param array $data The user submitted data |
||
196 | * @param ChangePasswordForm $form |
||
197 | * @return HTTPResponse |
||
198 | */ |
||
199 | public function doChangePassword(array $data, $form) |
||
200 | { |
||
201 | $member = Security::getCurrentUser(); |
||
202 | // The user was logged in, check the current password |
||
203 | $oldPassword = isset($data['OldPassword']) ? $data['OldPassword'] : null; |
||
204 | if ($member && !$this->checkPassword($member, $oldPassword)) { |
||
205 | $form->sessionMessage( |
||
206 | _t( |
||
207 | 'SilverStripe\\Security\\Member.ERRORPASSWORDNOTMATCH', |
||
208 | 'Your current password does not match, please try again' |
||
209 | ), |
||
210 | 'bad' |
||
211 | ); |
||
212 | |||
213 | // redirect back to the form, instead of using redirectBack() which could send the user elsewhere. |
||
214 | return $this->redirectBackToForm(); |
||
215 | } |
||
216 | |||
217 | if (!$member) { |
||
218 | if (Session::get('AutoLoginHash')) { |
||
219 | $member = Member::member_from_autologinhash(Session::get('AutoLoginHash')); |
||
220 | } |
||
221 | |||
222 | // The user is not logged in and no valid auto login hash is available |
||
223 | if (!$member) { |
||
224 | Session::clear('AutoLoginHash'); |
||
225 | |||
226 | return $this->redirect($this->addBackURLParam(Security::singleton()->Link('login'))); |
||
227 | } |
||
228 | } |
||
229 | |||
230 | // Check the new password |
||
231 | if (empty($data['NewPassword1'])) { |
||
232 | $form->sessionMessage( |
||
233 | _t( |
||
234 | 'SilverStripe\\Security\\Member.EMPTYNEWPASSWORD', |
||
235 | "The new password can't be empty, please try again" |
||
236 | ), |
||
237 | 'bad' |
||
238 | ); |
||
239 | |||
240 | // redirect back to the form, instead of using redirectBack() which could send the user elsewhere. |
||
241 | return $this->redirectBackToForm(); |
||
242 | } |
||
243 | |||
244 | // Fail if passwords do not match |
||
245 | if ($data['NewPassword1'] !== $data['NewPassword2']) { |
||
246 | $form->sessionMessage( |
||
247 | _t( |
||
248 | 'SilverStripe\\Security\\Member.ERRORNEWPASSWORD', |
||
249 | 'You have entered your new password differently, try again' |
||
250 | ), |
||
251 | 'bad' |
||
252 | ); |
||
253 | |||
254 | // redirect back to the form, instead of using redirectBack() which could send the user elsewhere. |
||
255 | return $this->redirectBackToForm(); |
||
256 | } |
||
257 | |||
258 | // Check if the new password is accepted |
||
259 | $validationResult = $member->changePassword($data['NewPassword1']); |
||
260 | if (!$validationResult->isValid()) { |
||
261 | $form->setSessionValidationResult($validationResult); |
||
262 | |||
263 | return $this->redirectBackToForm(); |
||
264 | } |
||
265 | |||
266 | // Clear locked out status |
||
267 | $member->LockedOutUntil = null; |
||
268 | $member->FailedLoginCount = null; |
||
269 | // Clear the members login hashes |
||
270 | $member->AutoLoginHash = null; |
||
271 | $member->AutoLoginExpired = DBDatetime::create()->now(); |
||
272 | $member->write(); |
||
273 | |||
274 | if ($member->canLogIn()) { |
||
275 | /** @var IdentityStore $identityStore */ |
||
276 | $identityStore = Injector::inst()->get(IdentityStore::class); |
||
277 | $identityStore->logIn($member, false, $this->getRequest()); |
||
278 | } |
||
279 | |||
280 | // TODO Add confirmation message to login redirect |
||
281 | Session::clear('AutoLoginHash'); |
||
282 | |||
283 | // Redirect to backurl |
||
284 | $backURL = $this->getBackURL(); |
||
285 | if ($backURL) { |
||
286 | return $this->redirect($backURL); |
||
287 | } |
||
288 | |||
289 | // Redirect to default location - the login form saying "You are logged in as..." |
||
290 | $url = Security::singleton()->Link('login'); |
||
291 | |||
292 | return $this->redirect($url); |
||
293 | } |
||
294 | |||
295 | /** |
||
296 | * Something went wrong, go back to the changepassword |
||
297 | * |
||
298 | * @return HTTPResponse |
||
299 | */ |
||
300 | public function redirectBackToForm() |
||
307 | |||
308 | /** |
||
309 | * Check if password is ok |
||
310 | * |
||
311 | * @param Member $member |
||
312 | * @param string $password |
||
313 | * @return bool |
||
314 | */ |
||
315 | protected function checkPassword($member, $password) |
||
329 | } |
||
330 |
This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.
Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.