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.

105 lines
3.0 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. from django.conf import settings
  2. from django.contrib.auth.mixins import UserPassesTestMixin
  3. from django.db.models import Subquery
  4. from django.shortcuts import get_object_or_404
  5. from rest_framework.permissions import BasePermission, SAFE_METHODS, IsAdminUser
  6. from .models import Project, Role, RoleMapping
  7. class ProjectMixin:
  8. @classmethod
  9. def get_project_id(self, request, view):
  10. return view.kwargs.get('project_id') or request.query_params.get('project_id')
  11. class IsAdminUserAndWriteOnly(BasePermission):
  12. def has_permission(self, request, view):
  13. if request.method in SAFE_METHODS:
  14. return True
  15. return IsAdminUser().has_permission(request, view)
  16. class ProjectAdminMixin(UserPassesTestMixin):
  17. def test_func(self):
  18. return self.request.user.is_superuser or is_in_role(
  19. role_name=IsProjectAdmin.role_name,
  20. user_id=self.request.user.id,
  21. project_id=self.kwargs['project_id'],
  22. )
  23. class IsOwnAnnotation(ProjectMixin, BasePermission):
  24. def has_permission(self, request, view):
  25. if request.user.is_superuser:
  26. return True
  27. project_id = self.get_project_id(request, view)
  28. annotation_id = view.kwargs.get('annotation_id')
  29. project = get_object_or_404(Project, pk=project_id)
  30. model = project.get_annotation_class()
  31. annotation = model.objects.filter(id=annotation_id, user=request.user)
  32. return annotation.exists()
  33. class IsOwnComment(ProjectMixin, BasePermission):
  34. @classmethod
  35. def has_object_permission(cls, request, view, obj):
  36. if request.user.is_superuser:
  37. return True
  38. return obj.user.id == request.user.id
  39. class RolePermission(ProjectMixin, BasePermission):
  40. UNSAFE_METHODS = ('POST', 'PATCH', 'DELETE')
  41. unsafe_methods_check = True
  42. role_name = ''
  43. def has_permission(self, request, view):
  44. if request.user.is_superuser:
  45. return True
  46. if self.unsafe_methods_check and request.method in self.UNSAFE_METHODS:
  47. return request.user.is_superuser
  48. project_id = self.get_project_id(request, view)
  49. if not project_id and request.method in SAFE_METHODS:
  50. return True
  51. return is_in_role(self.role_name, request.user.id, project_id)
  52. class IsProjectAdmin(RolePermission):
  53. unsafe_methods_check = False
  54. role_name = settings.ROLE_PROJECT_ADMIN
  55. class IsAnnotatorAndReadOnly(RolePermission):
  56. role_name = settings.ROLE_ANNOTATOR
  57. class IsAnnotator(RolePermission):
  58. unsafe_methods_check = False
  59. role_name = settings.ROLE_ANNOTATOR
  60. class IsAnnotationApproverAndReadOnly(RolePermission):
  61. role_name = settings.ROLE_ANNOTATION_APPROVER
  62. class IsAnnotationApprover(RolePermission):
  63. unsafe_methods_check = False
  64. role_name = settings.ROLE_ANNOTATION_APPROVER
  65. def is_in_role(role_name, user_id, project_id):
  66. return RoleMapping.objects.filter(
  67. user_id=user_id,
  68. project_id=project_id,
  69. role_id=Subquery(Role.objects.filter(name=role_name).values('id')),
  70. ).exists()