request.py 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import typing
  2. from pyramid.request import Request
  3. from sqlalchemy.orm.exc import NoResultFound
  4. from tracim.exceptions import NotAuthentificated
  5. from tracim.exceptions import WorkspaceNotFound
  6. from tracim.exceptions import ImmutableAttribute
  7. from tracim.lib.core.user import UserApi
  8. from tracim.lib.core.workspace import WorkspaceApi
  9. from tracim.lib.utils.authorization import JSONDecodeError
  10. from tracim.models import User
  11. from tracim.models.data import Workspace
  12. class TracimRequest(Request):
  13. """
  14. Request with tracim specific params/methods
  15. """
  16. def __init__(
  17. self,
  18. environ,
  19. charset=None,
  20. unicode_errors=None,
  21. decode_param_names=None,
  22. **kw
  23. ):
  24. super().__init__(
  25. environ,
  26. charset,
  27. unicode_errors,
  28. decode_param_names,
  29. **kw
  30. )
  31. self._current_workspace = None # type: Workspace
  32. self._current_user = None # type: User
  33. @property
  34. def current_workspace(self) -> Workspace:
  35. """
  36. Get current workspace of the request according to authentification and
  37. request headers (to retrieve workspace). Setted by default value the
  38. first time if not configured.
  39. :return: Workspace of the request
  40. """
  41. if self._current_workspace is None:
  42. self.current_workspace = get_workspace(self.current_user, self)
  43. return self._current_workspace
  44. @current_workspace.setter
  45. def current_workspace(self, workspace: Workspace) -> None:
  46. """
  47. Setting current_workspace
  48. :param workspace:
  49. :return:
  50. """
  51. if self._current_workspace is not None:
  52. raise ImmutableAttribute(
  53. "Can't modify already setted current_workspace"
  54. )
  55. self._current_workspace = workspace
  56. @property
  57. def current_user(self) -> User:
  58. if self._current_user is None:
  59. self.current_user = get_safe_user(self)
  60. return self._current_user
  61. @current_user.setter
  62. def current_user(self, user: User) -> None:
  63. if self._current_user is not None:
  64. raise ImmutableAttribute(
  65. "Can't modify already setted current_user"
  66. )
  67. self._current_user = user
  68. ###
  69. # Utils for TracimRequest
  70. ###
  71. def get_safe_user(
  72. request: TracimRequest,
  73. ) -> User:
  74. """
  75. Get current pyramid authenticated user from request
  76. :param request: pyramid request
  77. :return: current authenticated user
  78. """
  79. app_config = request.registry.settings['CFG']
  80. uapi = UserApi(None, session=request.dbsession, config=app_config)
  81. try:
  82. login = request.authenticated_userid
  83. if not login:
  84. raise NotAuthentificated('not authenticated user_id,'
  85. 'Failed Authentification ?')
  86. user = uapi.get_one_by_email(login)
  87. except NoResultFound:
  88. raise NotAuthentificated('User not found')
  89. return user
  90. def get_workspace(
  91. user: User,
  92. request: TracimRequest
  93. ) -> Workspace:
  94. """
  95. Get current workspace from request
  96. :param user: User who want to check the workspace
  97. :param request: pyramid request
  98. :return: current workspace
  99. """
  100. workspace_id = ''
  101. try:
  102. if 'workspace_id' not in request.json_body:
  103. raise WorkspaceNotFound('No workspace_id param in json body')
  104. workspace_id = request.json_body['workspace_id']
  105. wapi = WorkspaceApi(current_user=user, session=request.dbsession)
  106. workspace = wapi.get_one(workspace_id)
  107. except JSONDecodeError:
  108. raise WorkspaceNotFound('Bad json body')
  109. except NoResultFound:
  110. raise WorkspaceNotFound(
  111. 'Workspace {} does not exist '
  112. 'or is not visible for this user'.format(workspace_id)
  113. )
  114. return workspace