An ebook/comic library service and web client
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.

127 lines
3.1 KiB

  1. """Service to handle user operations."""
  2. import logging
  3. from datetime import datetime
  4. from typing import Optional, Dict, Callable, Any
  5. from atheneum.db import db
  6. from atheneum.model import User
  7. from atheneum.utility import authentication_utility
  8. from atheneum.service.serialization_service import (
  9. BaseSerializer,
  10. register_serializer
  11. )
  12. LOGGER = logging.getLogger(__name__)
  13. class UserSerializer(BaseSerializer):
  14. """Serialize User model."""
  15. def _serializers(self) -> Dict[str, Callable[[], Any]]:
  16. """Define the fields and the accompanying serializer factory."""
  17. return {
  18. 'name': self.serialize_name,
  19. 'creationTime': self.serialize_creation_time,
  20. 'lastLoginTime': self.serialize_last_login_time,
  21. 'version': self.serialize_version,
  22. 'role': self.serialize_role,
  23. }
  24. def serialize_name(self) -> str:
  25. """User name."""
  26. return self.model.name
  27. def serialize_creation_time(self) -> datetime:
  28. """User creation time."""
  29. return self.model.creation_time
  30. def serialize_last_login_time(self) -> datetime:
  31. """User last login time."""
  32. return self.model.last_login_time
  33. def serialize_version(self) -> int:
  34. """User version."""
  35. return self.model.version
  36. def serialize_role(self) -> str:
  37. """User role."""
  38. return self.model.role
  39. register_serializer(User.__name__, UserSerializer)
  40. def register(name: str, password: str, role: str) -> User:
  41. """
  42. Register a new user.
  43. :param name: Desired user name. Must be unique and not already registered
  44. :param password: Password to be hashed and stored for the user
  45. :param role: Role to assign the user [ROLE_USER, ROLE_ADMIN]
  46. :return:
  47. """
  48. pw_hash, pw_revision = authentication_utility.get_password_hash(password)
  49. new_user = User(
  50. name=name,
  51. role=role,
  52. password_hash=pw_hash,
  53. password_revision=pw_revision,
  54. creation_time=datetime.now(),
  55. version=0)
  56. db.session.add(new_user)
  57. db.session.commit()
  58. LOGGER.info('Registered new user: %s with role: %s', name, role)
  59. return new_user
  60. def delete(user: User) -> bool:
  61. """
  62. Delete a user.
  63. :param user:
  64. :return:
  65. """
  66. existing_user = db.session.delete(user)
  67. if existing_user is None:
  68. db.session.commit()
  69. return True
  70. return False
  71. def update_last_login_time(user: User) -> None:
  72. """
  73. Bump the last login time for the user.
  74. :param user:
  75. :return:
  76. """
  77. if user is not None:
  78. user.last_login_time = datetime.now()
  79. db.session.commit()
  80. def update_password(user: User, password: str) -> None:
  81. """
  82. Change the user password.
  83. :param user:
  84. :param password:
  85. :return:
  86. """
  87. pw_hash, pw_revision = authentication_utility.get_password_hash(
  88. password)
  89. user.password_hash = pw_hash
  90. user.password_revision = pw_revision
  91. db.session.commit()
  92. def find_by_name(name: str) -> Optional[User]:
  93. """
  94. Find a user by name.
  95. :param name:
  96. :return:
  97. """
  98. return User.query.filter_by(name=name).first()