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.

177 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. @register_transformer
  12. class UserTokenTransformer(BaseTransformer):
  13. """Serialize User model."""
  14. type = UserToken
  15. def _deserializers(
  16. self) -> Dict[str, Callable[[UserToken, Any], None]]:
  17. """Define the fields and the accompanying serializer factory."""
  18. return {
  19. 'token': self.deserialize_token,
  20. 'note': self.deserialize_note,
  21. 'enabled': self.deserialize_enabled,
  22. 'expirationTime': self.deserialize_expiration_time,
  23. 'creationTime': self.deserialize_creation_time,
  24. 'lastUsageTime': self.deserialize_last_usage_time,
  25. 'version': self.deserialize_version
  26. }
  27. def _serializers(self) -> Dict[str, Callable[[], Any]]:
  28. """Define the fields and the accompanying serializer factory."""
  29. return {
  30. 'token': self.serialize_token,
  31. 'note': self.serialize_note,
  32. 'enabled': self.serialize_enabled,
  33. 'expirationTime': self.serialize_expiration_time,
  34. 'creationTime': self.serialize_creation_time,
  35. 'lastUsageTime': self.serialize_last_usage_time,
  36. 'version': self.serialize_version
  37. }
  38. def serialize_token(self) -> str:
  39. """User token."""
  40. return self.model.token
  41. @staticmethod
  42. def deserialize_token(model: UserToken, token: str) -> None:
  43. """User token."""
  44. model.token = token
  45. def serialize_note(self) -> str:
  46. """User token note."""
  47. return self.model.note
  48. @staticmethod
  49. def deserialize_note(model: UserToken, note: str) -> None:
  50. """User token note."""
  51. model.note = note
  52. def serialize_enabled(self) -> bool:
  53. """User token enabled."""
  54. return self.model.enabled
  55. @staticmethod
  56. def deserialize_enabled(model: UserToken, enabled: bool) -> None:
  57. """User token enabled."""
  58. model.enabled = enabled
  59. def serialize_expiration_time(self) -> datetime:
  60. """User token expiration time."""
  61. return self.model.expiration_time
  62. @staticmethod
  63. def deserialize_expiration_time(
  64. model: UserToken, expiration_time: datetime) -> None:
  65. """User token expiration time."""
  66. model.expiration_time = expiration_time
  67. def serialize_creation_time(self) -> datetime:
  68. """User token creation time."""
  69. return self.model.creation_time
  70. @staticmethod
  71. def deserialize_creation_time(
  72. model: UserToken, creation_time: datetime) -> None:
  73. """User token creation time."""
  74. model.creation_time = creation_time
  75. def serialize_last_usage_time(self) -> datetime:
  76. """User token last usage time."""
  77. return self.model.last_usage_time
  78. @staticmethod
  79. def deserialize_last_usage_time(
  80. model: UserToken, last_usage_time: datetime) -> None:
  81. """User token last usage time."""
  82. model.last_usage_time = last_usage_time
  83. def serialize_version(self) -> int:
  84. """User token version."""
  85. return self.model.version
  86. @staticmethod
  87. def deserialize_version(model: UserToken, version: int) -> None:
  88. """User token version."""
  89. model.version = version
  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()