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.

85 lines
2.6 KiB

  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. def get_project_id(self, request, view):
  9. return view.kwargs.get('project_id') or request.query_params.get('project_id')
  10. class IsAdminUserAndWriteOnly(BasePermission):
  11. def has_permission(self, request, view):
  12. if request.method in SAFE_METHODS:
  13. return True
  14. return IsAdminUser().has_permission(request, view)
  15. class SuperUserMixin(UserPassesTestMixin):
  16. def test_func(self):
  17. return self.request.user.is_superuser
  18. class IsOwnAnnotation(ProjectMixin, BasePermission):
  19. def has_permission(self, request, view):
  20. project_id = self.get_project_id(request, view)
  21. annotation_id = view.kwargs.get('annotation_id')
  22. project = get_object_or_404(Project, pk=project_id)
  23. model = project.get_annotation_class()
  24. annotation = model.objects.filter(id=annotation_id, user=request.user)
  25. return annotation.exists()
  26. class RolePermission(ProjectMixin, BasePermission):
  27. UNSAFE_METHODS = ('POST', 'PATCH', 'DELETE')
  28. unsafe_methods_check = True
  29. role_name = ''
  30. def has_permission(self, request, view):
  31. if request.user.is_superuser:
  32. return True
  33. if self.unsafe_methods_check and request.method in self.UNSAFE_METHODS:
  34. return request.user.is_superuser
  35. project_id = self.get_project_id(request, view)
  36. if not project_id and request.method in SAFE_METHODS:
  37. return True
  38. return is_in_role(self.role_name, request.user.id, project_id)
  39. class IsProjectAdmin(RolePermission):
  40. unsafe_methods_check = False
  41. role_name = settings.ROLE_PROJECT_ADMIN
  42. class IsAnnotatorAndReadOnly(RolePermission):
  43. role_name = settings.ROLE_ANNOTATOR
  44. class IsAnnotator(RolePermission):
  45. unsafe_methods_check = False
  46. role_name = settings.ROLE_ANNOTATOR
  47. class IsAnnotationApproverAndReadOnly(RolePermission):
  48. role_name = settings.ROLE_ANNOTATION_APPROVER
  49. class IsAnnotationApprover(RolePermission):
  50. unsafe_methods_check = False
  51. role_name = settings.ROLE_ANNOTATION_APPROVER
  52. def is_in_role(role_name, user_id, project_id):
  53. return RoleMapping.objects.filter(
  54. user_id=user_id,
  55. project_id=project_id,
  56. role_id=Subquery(Role.objects.filter(name=role_name).values('id')),
  57. ).exists()