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.

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