authorization.py 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. # -*- coding: utf-8 -*-
  2. from typing import TYPE_CHECKING
  3. from pyramid.interfaces import IAuthorizationPolicy
  4. from zope.interface import implementer
  5. try:
  6. from json.decoder import JSONDecodeError
  7. except ImportError: # python3.4
  8. JSONDecodeError = ValueError
  9. from tracim.exceptions import InsufficientUserWorkspaceRole, \
  10. InsufficientUserProfile
  11. if TYPE_CHECKING:
  12. from tracim import TracimRequest
  13. ###
  14. # Pyramid default permission/authorization mecanism
  15. # INFO - G.M - 12-04-2018 - Setiing a Default permission on view is
  16. # needed to activate AuthentificationPolicy and
  17. # AuthorizationPolicy on pyramid request
  18. TRACIM_DEFAULT_PERM = 'tracim'
  19. @implementer(IAuthorizationPolicy)
  20. class AcceptAllAuthorizationPolicy(object):
  21. """
  22. Empty AuthorizationPolicy : Allow all request. As Pyramid need
  23. a Authorization policy when we use AuthentificationPolicy, this
  24. class permit use to disable pyramid authorization mecanism with
  25. working a AuthentificationPolicy.
  26. """
  27. def permits(self, context, principals, permision):
  28. return True
  29. def principals_allowed_by_permission(self, context, permission):
  30. raise NotImplementedError()
  31. ###
  32. # Authorization decorators for views
  33. # INFO - G.M - 12-04-2018
  34. # Instead of relying on pyramid authorization mecanism
  35. # We prefer to use decorators
  36. def require_same_user_or_profile(group: int):
  37. """
  38. Decorator for view to restrict access of tracim request if candidate user
  39. is distinct from authenticated user and not with high enough profile.
  40. :param group: value from Group Object
  41. like Group.TIM_USER or Group.TIM_MANAGER
  42. :return:
  43. """
  44. def decorator(func):
  45. def wrapper(self, context, request: 'TracimRequest'):
  46. auth_user = request.current_user
  47. candidate_user = request.candidate_user
  48. if auth_user.user_id == candidate_user.user_id or \
  49. auth_user.profile.id >= group:
  50. return func(self, context, request)
  51. raise InsufficientUserProfile()
  52. return wrapper
  53. return decorator
  54. def require_profile(group: int):
  55. """
  56. Decorator for view to restrict access of tracim request if profile is
  57. not high enough
  58. :param group: value from Group Object
  59. like Group.TIM_USER or Group.TIM_MANAGER
  60. :return:
  61. """
  62. def decorator(func):
  63. def wrapper(self, context, request: 'TracimRequest'):
  64. user = request.current_user
  65. if user.profile.id >= group:
  66. return func(self, context, request)
  67. raise InsufficientUserProfile()
  68. return wrapper
  69. return decorator
  70. def require_workspace_role(minimal_required_role: int):
  71. """
  72. Decorator for view to restrict access of tracim request if role
  73. is not high enough
  74. :param minimal_required_role: value from UserInWorkspace Object like
  75. UserRoleInWorkspace.CONTRIBUTOR or UserRoleInWorkspace.READER
  76. :return: decorator
  77. """
  78. def decorator(func):
  79. def wrapper(self, context, request: 'TracimRequest'):
  80. user = request.current_user
  81. workspace = request.current_workspace
  82. if workspace.get_user_role(user) >= minimal_required_role:
  83. return func(self, context, request)
  84. raise InsufficientUserWorkspaceRole()
  85. return wrapper
  86. return decorator