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.

131 lines
3.8 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
3 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 (SAFE_METHODS, BasePermission,
  6. IsAdminUser)
  7. from .models import Project, Role, RoleMapping
  8. class ProjectMixin:
  9. @classmethod
  10. def get_project_id(self, request, view):
  11. return view.kwargs.get('project_id') or request.query_params.get('project_id')
  12. class IsAdminUserAndWriteOnly(BasePermission):
  13. def has_permission(self, request, view):
  14. if request.method in SAFE_METHODS:
  15. return True
  16. return IsAdminUser().has_permission(request, view)
  17. class ProjectAdminMixin(UserPassesTestMixin):
  18. def test_func(self):
  19. return self.request.user.is_superuser or is_in_role(
  20. role_name=IsProjectAdmin.role_name,
  21. user_id=self.request.user.id,
  22. project_id=self.kwargs['project_id'],
  23. )
  24. class IsOwnAnnotation(ProjectMixin, BasePermission):
  25. def has_permission(self, request, view):
  26. if request.user.is_superuser:
  27. return True
  28. project_id = self.get_project_id(request, view)
  29. annotation_id = view.kwargs.get('annotation_id')
  30. project = get_object_or_404(Project, pk=project_id)
  31. model = project.get_annotation_class()
  32. annotation = model.objects.filter(id=annotation_id, user=request.user)
  33. return annotation.exists()
  34. class CanEditAnnotation(ProjectMixin, BasePermission):
  35. def __init__(self, queryset):
  36. super().__init__()
  37. self.queryset = queryset
  38. def has_permission(self, request, view):
  39. if request.user.is_superuser:
  40. return True
  41. annotation_id = view.kwargs.get('annotation_id')
  42. return self.queryset.filter(id=annotation_id, user=request.user).exists()
  43. class IsOwnComment(ProjectMixin, BasePermission):
  44. @classmethod
  45. def has_object_permission(cls, request, view, obj):
  46. if request.user.is_superuser:
  47. return True
  48. return obj.user.id == request.user.id
  49. class RolePermission(ProjectMixin, BasePermission):
  50. UNSAFE_METHODS = ('POST', 'PATCH', 'DELETE')
  51. unsafe_methods_check = True
  52. role_name = ''
  53. def has_permission(self, request, view):
  54. if request.user.is_superuser:
  55. return True
  56. if self.unsafe_methods_check and request.method in self.UNSAFE_METHODS:
  57. return request.user.is_superuser
  58. project_id = self.get_project_id(request, view)
  59. if not project_id and request.method in SAFE_METHODS:
  60. return True
  61. return is_in_role(self.role_name, request.user.id, project_id)
  62. class IsProjectAdmin(RolePermission):
  63. unsafe_methods_check = False
  64. role_name = settings.ROLE_PROJECT_ADMIN
  65. class IsAnnotatorAndReadOnly(RolePermission):
  66. role_name = settings.ROLE_ANNOTATOR
  67. class IsAnnotator(RolePermission):
  68. unsafe_methods_check = False
  69. role_name = settings.ROLE_ANNOTATOR
  70. class IsAnnotationApproverAndReadOnly(RolePermission):
  71. role_name = settings.ROLE_ANNOTATION_APPROVER
  72. class IsAnnotationApprover(RolePermission):
  73. unsafe_methods_check = False
  74. role_name = settings.ROLE_ANNOTATION_APPROVER
  75. class IsStaff(BasePermission):
  76. def has_permission(self, request, view):
  77. if request.user.is_superuser or request.user.is_staff:
  78. return True
  79. return False
  80. def is_in_role(role_name, user_id, project_id):
  81. return RoleMapping.objects.filter(
  82. user_id=user_id,
  83. project_id=project_id,
  84. role_id=Subquery(Role.objects.filter(name=role_name).values('id')),
  85. ).exists()
  86. IsInProjectReadOnlyOrAdmin = (IsAnnotatorAndReadOnly | IsAnnotationApproverAndReadOnly | IsProjectAdmin)
  87. IsInProjectOrAdmin = (IsAnnotator | IsAnnotationApprover | IsProjectAdmin)