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.

179 lines
5.1 KiB

  1. """Service to handle user_token operations."""
  2. import uuid
  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, UserToken
  7. from atheneum.service.transformation_service import (
  8. BaseTransformer,
  9. register_transformer
  10. )
  11. class UserTokenTransformer(BaseTransformer):
  12. """Serialize User model."""
  13. type = UserToken
  14. def _deserializers(
  15. self) -> Dict[str, Callable[[UserToken, Any], None]]:
  16. """Define the fields and the accompanying serializer factory."""
  17. return {
  18. 'token': self.deserialize_token,
  19. 'note': self.deserialize_note,
  20. 'enabled': self.deserialize_enabled,
  21. 'expirationTime': self.deserialize_expiration_time,
  22. 'creationTime': self.deserialize_creation_time,
  23. 'lastUsageTime': self.deserialize_last_usage_time,
  24. 'version': self.deserialize_version
  25. }
  26. def _serializers(self) -> Dict[str, Callable[[], Any]]:
  27. """Define the fields and the accompanying serializer factory."""
  28. return {
  29. 'token': self.serialize_token,
  30. 'note': self.serialize_note,
  31. 'enabled': self.serialize_enabled,
  32. 'expirationTime': self.serialize_expiration_time,
  33. 'creationTime': self.serialize_creation_time,
  34. 'lastUsageTime': self.serialize_last_usage_time,
  35. 'version': self.serialize_version
  36. }
  37. def serialize_token(self) -> str:
  38. """User token."""
  39. return self.model.token
  40. @staticmethod
  41. def deserialize_token(model: UserToken, token: str) -> None:
  42. """User token."""
  43. model.token = token
  44. def serialize_note(self) -> str:
  45. """User token note."""
  46. return self.model.note
  47. @staticmethod
  48. def deserialize_note(model: UserToken, note: str) -> None:
  49. """User token note."""
  50. model.note = note
  51. def serialize_enabled(self) -> bool:
  52. """User token enabled."""
  53. return self.model.enabled
  54. @staticmethod
  55. def deserialize_enabled(model: UserToken, enabled: bool) -> None:
  56. """User token enabled."""
  57. model.enabled = enabled
  58. def serialize_expiration_time(self) -> datetime:
  59. """User token expiration time."""
  60. return self.model.expiration_time
  61. @staticmethod
  62. def deserialize_expiration_time(
  63. model: UserToken, expiration_time: datetime) -> None:
  64. """User token expiration time."""
  65. model.expiration_time = expiration_time
  66. def serialize_creation_time(self) -> datetime:
  67. """User token creation time."""
  68. return self.model.creation_time
  69. @staticmethod
  70. def deserialize_creation_time(
  71. model: UserToken, creation_time: datetime) -> None:
  72. """User token creation time."""
  73. model.creation_time = creation_time
  74. def serialize_last_usage_time(self) -> datetime:
  75. """User token last usage time."""
  76. return self.model.last_usage_time
  77. @staticmethod
  78. def deserialize_last_usage_time(
  79. model: UserToken, last_usage_time: datetime) -> None:
  80. """User token last usage time."""
  81. model.last_usage_time = last_usage_time
  82. def serialize_version(self) -> int:
  83. """User token version."""
  84. return self.model.version
  85. @staticmethod
  86. def deserialize_version(model: UserToken, version: int) -> None:
  87. """User token version."""
  88. model.version = version
  89. register_transformer(UserToken.__name__, UserTokenTransformer)
  90. def generate_token() -> uuid.UUID:
  91. """
  92. Generate a unique token.
  93. :return:
  94. """
  95. return uuid.uuid4()
  96. def create(
  97. user: User,
  98. note: Optional[str] = None,
  99. enabled: bool = True,
  100. expiration_time: Optional[datetime] = None) -> UserToken:
  101. """
  102. Create and save a UserToken.
  103. :param user: The User object to bind the token to
  104. :param note: An optional field to store additional information about a
  105. token
  106. :param enabled: A boolean to indicate whether a token can be considered
  107. eligible for authentication
  108. :param expiration_time: An optional argument to determine when the token
  109. becomes invalid as a means of authentication. Defaults to None, which means
  110. no expiration
  111. :return:
  112. """
  113. token = generate_token()
  114. user_token = UserToken(
  115. user_id=user.id,
  116. token=token.__str__(),
  117. note=note,
  118. enabled=enabled,
  119. creation_time=datetime.now(),
  120. expiration_time=expiration_time,
  121. version=0)
  122. db.session.add(user_token)
  123. db.session.commit()
  124. return user_token
  125. def delete(user_token: UserToken) -> bool:
  126. """
  127. Delete a user_token.
  128. :param user_token:
  129. :return:
  130. """
  131. existing_user_token = db.session.delete(user_token)
  132. if existing_user_token is None:
  133. db.session.commit()
  134. return True
  135. return False
  136. def find_by_user_and_token(user: User, token: str) -> Optional[UserToken]:
  137. """
  138. Lookup a user_token by user and token string.
  139. :param user:
  140. :param token:
  141. :return:
  142. """
  143. return UserToken.query.filter_by(user_id=user.id, token=token).first()