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