user.py 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. # -*- coding: utf-8 -*-
  2. import threading
  3. import transaction
  4. import typing as typing
  5. from sqlalchemy.orm import Session
  6. from tracim import CFG
  7. from tracim.models.auth import User
  8. from tracim.models.auth import Group
  9. from sqlalchemy.orm.exc import NoResultFound
  10. from tracim.exceptions import WrongUserPassword, UserNotExist
  11. from tracim.exceptions import AuthenticationFailed
  12. from tracim.models.context_models import UserInContext
  13. class UserApi(object):
  14. def __init__(
  15. self,
  16. current_user: typing.Optional[User],
  17. session: Session,
  18. config: CFG,
  19. ) -> None:
  20. self._session = session
  21. self._user = current_user
  22. self._config = config
  23. def _base_query(self):
  24. return self._session.query(User)
  25. def get_user_with_context(self, user: User) -> UserInContext:
  26. """
  27. Return UserInContext object from User
  28. """
  29. user = UserInContext(
  30. user=user,
  31. dbsession=self._session,
  32. config=self._config,
  33. )
  34. return user
  35. # Getters
  36. def get_one(self, user_id: int) -> User:
  37. """
  38. Get one user by user id
  39. """
  40. try:
  41. user = self._base_query().filter(User.user_id == user_id).one()
  42. except NoResultFound:
  43. raise UserNotExist()
  44. return user
  45. def get_one_by_email(self, email: str) -> User:
  46. """
  47. Get one user by email
  48. :param email: Email of the user
  49. :return: one user
  50. """
  51. try:
  52. user = self._base_query().filter(User.email == email).one()
  53. except NoResultFound:
  54. raise UserNotExist()
  55. return user
  56. # FIXME - G.M - 24-04-2018 - Duplicate method with get_one.
  57. def get_one_by_id(self, id: int) -> User:
  58. return self.get_one(user_id=id)
  59. def get_current_user(self) -> User:
  60. """
  61. Get current_user
  62. """
  63. if not self._user:
  64. raise UserNotExist()
  65. return self._user
  66. def get_all(self) -> typing.Iterable[User]:
  67. return self._session.query(User).order_by(User.display_name).all()
  68. # Check methods
  69. def user_with_email_exists(self, email: str) -> bool:
  70. try:
  71. self.get_one_by_email(email)
  72. return True
  73. # TODO - G.M - 09-04-2018 - Better exception
  74. except:
  75. return False
  76. def authenticate_user(self, email: str, password: str) -> User:
  77. """
  78. Authenticate user with email and password, raise AuthenticationFailed
  79. if uncorrect.
  80. :param email: email of the user
  81. :param password: cleartext password of the user
  82. :return: User who was authenticated.
  83. """
  84. try:
  85. user = self.get_one_by_email(email)
  86. if user.validate_password(password):
  87. return user
  88. else:
  89. raise WrongUserPassword()
  90. except (WrongUserPassword, NoResultFound, UserNotExist):
  91. raise AuthenticationFailed()
  92. # Actions
  93. def update(
  94. self,
  95. user: User,
  96. name: str=None,
  97. email: str=None,
  98. do_save=True,
  99. timezone: str='',
  100. ) -> None:
  101. if name is not None:
  102. user.display_name = name
  103. if email is not None:
  104. user.email = email
  105. user.timezone = timezone
  106. if do_save:
  107. self.save(user)
  108. def create_user(self, email=None, groups=[], save_now=False) -> User:
  109. user = User()
  110. if email:
  111. user.email = email
  112. for group in groups:
  113. user.groups.append(group)
  114. self._session.add(user)
  115. if save_now:
  116. self._session.flush()
  117. return user
  118. def save(self, user: User):
  119. self._session.flush()
  120. def execute_created_user_actions(self, created_user: User) -> None:
  121. """
  122. Execute actions when user just been created
  123. :return:
  124. """
  125. # NOTE: Cyclic import
  126. # TODO - G.M - 28-03-2018 - [Calendar] Reenable Calendar stuff
  127. #from tracim.lib.calendar import CalendarManager
  128. #from tracim.model.organisational import UserCalendar
  129. # TODO - G.M - 04-04-2018 - [auth]
  130. # Check if this is already needed with
  131. # new auth system
  132. created_user.ensure_auth_token(
  133. session=self._session,
  134. validity_seconds=self._config.USER_AUTH_TOKEN_VALIDITY
  135. )
  136. # Ensure database is up-to-date
  137. self._session.flush()
  138. transaction.commit()
  139. # TODO - G.M - 28-03-2018 - [Calendar] Reenable Calendar stuff
  140. # calendar_manager = CalendarManager(created_user)
  141. # calendar_manager.create_then_remove_fake_event(
  142. # calendar_class=UserCalendar,
  143. # related_object_id=created_user.user_id,
  144. # )