예제 #1
0
 /**
  * @param int $userId
  * @param string $newPassword
  * @param null $resetPasswordToken token to expire if call is from password reset
  * @return bool
  * @throws PasswordChangeException
  */
 public function updatePassword($userId, $newPassword, $resetPasswordToken = null)
 {
     $transactionManager = new TransactionManager();
     try {
         //use a transaction as we would be updating more than one table
         $transaction = $transactionManager->get();
         $this->setTransaction($transaction);
         $user = User::findFirst($userId);
         if ($user == false) {
             $transaction->rollback(ErrorMessages::PASSWORD_UPDATE_FAILED);
         }
         $previousPassword = $user->password;
         $user->password = Utils::encryptPassword($newPassword);
         if (!$user->save()) {
             $transaction->rollback(ErrorMessages::PASSWORD_UPDATE_FAILED);
         }
         $userPasswordChange = new UserPasswordChange();
         $userPasswordChange->setTransaction($transaction);
         $userPasswordChange->setDateChanged(date("Y-m-d H:i:s"));
         $userPasswordChange->setUserId($userId);
         $userPasswordChange->setPasswordHash($previousPassword);
         if (!$userPasswordChange->save()) {
             $transaction->rollback(ErrorMessages::PASSWORD_UPDATE_FAILED);
         }
         if (!empty($resetPasswordToken) && !(new UserPasswordReset())->expireToken($resetPasswordToken)) {
             $transaction->rollback(ErrorMessages::TOKEN_EXPIRY_FAILED);
         }
         $transaction->commit();
         return true;
     } catch (TransactionFailed $e) {
         throw new PasswordChangeException($e->getMessage());
     }
 }
 /**
  * check if the new password does not correspond to the previous max passwords
  * We use max-1 in the query because we are assuming that the user's current password is
  * inclusive of the last max passwords used and this has already been checked above
  *
  * @param int $userId
  * @param string $newPassword
  * @param int $max
  * @throws PasswordChangeException
  */
 public static function validateNewPassword($userId, $newPassword, $max = self::MAX_PASSWORD_CHANGES_BEFORE_REUSE)
 {
     $recentPasswords = UserPasswordChange::query()->where("user_id = :user_id:")->bind(["user_id" => $userId])->orderBy("date_changed DESC")->limit($max - 1)->execute()->toArray();
     foreach ($recentPasswords as $aRecentPassword) {
         if (Utils::verifyPassword($newPassword, $aRecentPassword['password_hash'])) {
             throw new PasswordChangeException("You cannot use any of your last {$max} passwords");
         }
     }
 }