/** * Save the associated user model * * Also, this clears out all password resets associated with the given user, * if successful. * @return type */ public function save() { if ($this->validate()) { $this->userModel->password = PasswordUtil::createHash($this->password); PasswordReset::model()->deleteAllByAttributes(array('userId' => $this->userModel->id)); return $this->userModel->update(array('password')); } return false; }
public function testSave() { $user = $this->user('testUser'); $form = new PasswordResetForm($user); $password = '******'; $form->password = $password; $form->confirm = $form->password; $form->save(); $user->refresh(); $this->assertTrue(PasswordUtil::validatePassword($password, $user->password)); $this->assertEquals(0, PasswordReset::model()->countByAttributes(array('userId' => $user->id))); }
public function testBeforeSave() { // Fixture data should contain five expired reset requests, which should // be cleared out in beforeSave() $n0 = PasswordReset::model()->countByAttributes(array('ip' => '127.0.0.1')); $reset = new PasswordReset(); $reset->email = $this->user('testUser')->emailAddress; $reset->ip = '127.0.0.1'; $reset->beforeSave(); $n1 = PasswordReset::model()->countByAttributes(array('ip' => '127.0.0.1')); $this->assertEquals($this->user('testUser')->id, $reset->userId); $this->assertEquals(5, $n0 - $n1); }
public function testSave() { $user = $this->user('testUser'); $form = new PasswordResetForm($user); $password = '******'; $form->password = $password; $form->confirm = $form->password; $form->save(); $user->refresh(); $this->assertTrue(PasswordUtil::validatePassword($password, $user->password)); $this->assertEquals(0, PasswordReset::model()->countByAttributes(array('userId' => $user->id))); // Test validation as well, as a "bonus", since there needn't be any // fixture loading for it, and it thus saves a few seconds when running // the test: $form = new PasswordResetForm($user); $passwords = array(false => array('n#6', 'ninininini'), true => array('D83*@)1', 'this that and the next thing')); foreach ($passwords as $good => $passes) { foreach ($passes as $pass) { $form->password = $pass; $form->confirm = $pass; $this->assertEquals($good, $form->validate(array('password'))); } } }
/** * Reset a user's password via a really basic email verification process * * @param type $id ID/key of the password recovery record */ public function actionResetPassword($id = null) { if (!Yii::app()->user->isGuest) { $this->redirect(array('/profile/changePassword', 'id' => Yii::app()->user->id)); } $this->layout = '//layouts/login'; $scenario = 'new'; $title = Yii::t('app', 'Reset Password'); $this->pageTitle = $title; $message = Yii::t('app', 'Enter the email address associated with your user account to request a new password and username reminder.'); $request = new PasswordReset(); $resetForm = null; if (isset($_POST['PasswordReset'])) { // Submitting a password reset request $request->setAttributes($_POST['PasswordReset']); if ($request->save()) { $request->setScenario('afterSave'); if (!$request->validate(array('email'))) { // Create a new model. It is done this way (adding the // validation error to a new model) so that there is a trail // of reset request attempts that can be counted to determine // if the user has made too many. $oldRequest = $request; $request = new $request(); $request->setAttributes($oldRequest->getAttributes(array('email')), false); $request->addErrors($oldRequest->getErrors()); } else { // A user with the corresponding email was found. Attempt to // send the email and whatever happens, don't display the // form again. $scenario = 'message'; $mail = new EmailDeliveryBehavior(); $mail->credId = Credentials::model()->getDefaultUserAccount(Credentials::$sysUseId['systemNotificationEmail'], 'email'); // Compose the message & headers $message = Yii::t('users', "You have requested to reset the password for user {user} in {appName}.", array('{user}' => $request->user->alias, '{appName}' => Yii::app()->settings->appName)); $message .= ' ' . Yii::t('users', "To finish resetting your password, please open the following link: "); $message .= "<br /><br />" . $this->createAbsoluteUrl('/site/resetPassword') . '?' . http_build_query(array('id' => $request->id)); $message .= "<br /><br />" . Yii::t('users', "If you did not make this request, please disregard this email."); $recipients = array('to' => array(array('', $request->email))); // Send the email $status = $mail->deliverEmail($recipients, Yii::app()->settings->appName . " password reset", $message); // Set the response message accordingly. if ($status['code'] == 200) { $title = Yii::t('users', 'Almost Done!'); $message = Yii::t('users', 'Check your email at {email} for ' . 'further instructions to finish resetting your password.', array('{email}' => $request->email)); } else { $title = Yii::t('users', 'Could not send email.'); $message = Yii::t('users', 'Sending of the password reset verification email failed with message: {message}', array('{message}' => $status['message'])); } } } else { if ($request->limitReached) { $scenario = 'message'; $message = Yii::t('app', 'You have made too many requests to reset passwords. ' . 'Please wait one hour before trying again.'); } } } else { if ($id !== null) { // User might have arrived here through the link in a reset email. $scenario = 'apply'; $request = PasswordReset::model()->findByPk($id); if ($request instanceof PasswordReset && !$request->isExpired) { // Reset request record exists. $user = $request->user; if ($user instanceof User) { // ...and is valid (points to an existing user) // // Default message: the password entry form (initial request) $message = Yii::t('users', 'Enter a new password for user "{user}" ({name}):', array('{user}' => $user->alias, '{name}' => CHtml::encode($user->firstName . ' ' . $user->lastName))); $resetForm = new PasswordResetForm($user); if (isset($_POST['PasswordResetForm'])) { // Handle the form submission: $resetForm->setAttributes($_POST['PasswordResetForm']); if ($resetForm->save()) { // Done, success. $scenario = 'message'; $title = Yii::t('users', 'Password Has Been Reset'); $message = Yii::t('users', 'You should now have access ' . 'as "{user}" with the new password specified.', array('{user}' => $user->alias)); } } } else { // Invalid request record; it does not correspond to an // existing user, i.e. it's an "attempt" (entering an email // address to see if that sticks). $scenario = 'message'; $title = Yii::t('users', 'Access Denied'); $message = Yii::t('users', 'Invalid reset key.'); } } else { $scenario = 'message'; $title = Yii::t('users', 'Access Denied'); if ($request->isExpired) { $message = Yii::t('users', 'The password reset link has expired.'); } else { $message = Yii::t('users', 'Invalid reset link.'); } } } } $this->render('resetPassword', compact('scenario', 'title', 'message', 'request', 'resetForm')); }