A multipurpose python flask API server and administration SPA
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

63 lines
1.7 KiB

  1. """Service to handle authentication."""
  2. import re
  3. from typing import Optional
  4. from nacl import pwhash
  5. from nacl.exceptions import InvalidkeyError
  6. from server import errors
  7. from server.model import User, UserToken
  8. from server.service import user_token_service
  9. def validate_password_strength(proposed_password: str) -> str:
  10. """Validate that a password meets minimum strength requirements."""
  11. # calculating the length
  12. length_error = len(proposed_password) < 8
  13. # searching for digits
  14. digit_error = re.search(r"\d", proposed_password) is None
  15. # searching for uppercase
  16. uppercase_error = re.search(r"[A-Z]", proposed_password) is None
  17. # searching for lowercase
  18. lowercase_error = re.search(r"[a-z]", proposed_password) is None
  19. if length_error or digit_error or uppercase_error or lowercase_error:
  20. raise errors.ValidationError(
  21. ' '.join(['The password must be at least 8 characters long.',
  22. 'Contain one or more digits,',
  23. 'one or more uppercase characters,',
  24. 'and one or more lowercase characters']))
  25. return proposed_password
  26. def is_valid_password(user: User, password: str) -> bool:
  27. """
  28. User password must pass pwhash verify.
  29. :param user:
  30. :param password:
  31. :return:
  32. """
  33. assert user
  34. try:
  35. return pwhash.verify(
  36. user.password_hash.encode('utf8'), password.encode('utf8'))
  37. except InvalidkeyError:
  38. pass
  39. return False
  40. def logout(user_token: Optional[UserToken] = None) -> None:
  41. """
  42. Remove a user_token associated with a client session.
  43. :param user_token:
  44. :return:
  45. """
  46. if user_token is not None:
  47. user_token_service.delete(user_token)