password.py 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. """
  2. flaskbb.auth.password
  3. ~~~~~~~~~~~~~~~~~~~~~
  4. Password reset manager
  5. :copyright: (c) 2014-2018 the FlaskBB Team.
  6. :license: BSD, see LICENSE for more details
  7. """
  8. from ...core.auth.password import ResetPasswordService as _ResetPasswordService
  9. from ...core.exceptions import StopValidation, ValidationError
  10. from ...core.tokens import Token, TokenActions, TokenError
  11. from ...email import send_reset_token
  12. class ResetPasswordService(_ResetPasswordService):
  13. def __init__(self, token_serializer, users, token_verifiers):
  14. self.token_serializer = token_serializer
  15. self.users = users
  16. self.token_verifiers = token_verifiers
  17. def initiate_password_reset(self, email):
  18. user = self.users.query.filter_by(email=email).first()
  19. if user is None:
  20. raise ValidationError('email', 'Invalid email')
  21. token = self.token_serializer.dumps(
  22. Token(user_id=user.id, operation=TokenActions.RESET_PASSWORD)
  23. )
  24. send_reset_token.delay(
  25. token=token, username=user.username, email=user.email
  26. )
  27. def reset_password(self, token, email, new_password):
  28. token = self.token_serializer.loads(token)
  29. if token.operation != TokenActions.RESET_PASSWORD:
  30. raise TokenError.invalid()
  31. self._verify_token(token, email)
  32. user = self.users.query.get(token.user_id)
  33. user.password = new_password
  34. def _verify_token(self, token, email):
  35. errors = []
  36. for verifier in self.token_verifiers:
  37. try:
  38. verifier(token, email=email)
  39. except ValidationError as e:
  40. errors.append((e.attribute, e.reason))
  41. if errors:
  42. raise StopValidation(errors)