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.

96 lines
2.8 KiB

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 RolePermission(ProjectMixin, BasePermission):
  34. UNSAFE_METHODS = ('POST', 'PATCH', 'DELETE')
  35. unsafe_methods_check = True
  36. role_name = ''
  37. def has_permission(self, request, view):
  38. if request.user.is_superuser:
  39. return True
  40. if self.unsafe_methods_check and request.method in self.UNSAFE_METHODS:
  41. return request.user.is_superuser
  42. project_id = self.get_project_id(request, view)
  43. if not project_id and request.method in SAFE_METHODS:
  44. return True
  45. return is_in_role(self.role_name, request.user.id, project_id)
  46. class IsProjectAdmin(RolePermission):
  47. unsafe_methods_check = False
  48. role_name = settings.ROLE_PROJECT_ADMIN
  49. class IsAnnotatorAndReadOnly(RolePermission):
  50. role_name = settings.ROLE_ANNOTATOR
  51. class IsAnnotator(RolePermission):
  52. unsafe_methods_check = False
  53. role_name = settings.ROLE_ANNOTATOR
  54. class IsAnnotationApproverAndReadOnly(RolePermission):
  55. role_name = settings.ROLE_ANNOTATION_APPROVER
  56. class IsAnnotationApprover(RolePermission):
  57. unsafe_methods_check = False
  58. role_name = settings.ROLE_ANNOTATION_APPROVER
  59. def is_in_role(role_name, user_id, project_id):
  60. return RoleMapping.objects.filter(
  61. user_id=user_id,
  62. project_id=project_id,
  63. role_id=Subquery(Role.objects.filter(name=role_name).values('id')),
  64. ).exists()