views.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. from django.shortcuts import get_object_or_404
  2. from rest_framework import exceptions, status, viewsets
  3. from rest_framework.decorators import action
  4. from rest_framework.filters import OrderingFilter
  5. from rest_framework.response import Response
  6. from organizations_ext.models import Organization, OrganizationUserRole
  7. from teams.models import Team
  8. from teams.views import NestedTeamViewSet
  9. from .models import Project, ProjectKey
  10. from .permissions import ProjectKeyPermission, ProjectPermission
  11. from .serializers.serializers import ProjectKeySerializer, ProjectSerializer
  12. class NestedProjectViewSet(viewsets.ModelViewSet):
  13. """
  14. Detail view is under /api/0/projects/{organization_slug}/{project_slug}/
  15. Project keys/DSN's are available at /api/0/projects/{organization_slug}/{project_slug}/keys/
  16. """
  17. queryset = Project.objects.all()
  18. serializer_class = ProjectSerializer
  19. lookup_field = "slug"
  20. permission_classes = [ProjectPermission]
  21. def get_object(self):
  22. queryset = self.filter_queryset(self.get_queryset())
  23. slug = self.kwargs.get("project_slug", self.kwargs.get("slug"))
  24. obj = get_object_or_404(
  25. queryset,
  26. slug=slug,
  27. organization__slug=self.kwargs["organization_slug"],
  28. )
  29. self.check_object_permissions(self.request, obj)
  30. return obj
  31. def get_queryset(self):
  32. if self.request.user.is_authenticated:
  33. queryset = self.queryset.filter(organization__users=self.request.user)
  34. organization_slug = self.kwargs.get("organization_slug")
  35. if organization_slug:
  36. queryset = queryset.filter(organization__slug=organization_slug)
  37. team_slug = self.kwargs.get("team_slug")
  38. if team_slug:
  39. queryset = queryset.filter(team__slug=team_slug)
  40. return queryset
  41. return self.queryset.none()
  42. def perform_create(self, serializer):
  43. team = None
  44. if self.kwargs.get("team_slug"):
  45. try:
  46. team = Team.objects.get(
  47. slug=self.kwargs.get("team_slug"),
  48. organization__slug=self.kwargs.get("organization_slug"),
  49. organization__users=self.request.user,
  50. organization__organization_users__role__gte=OrganizationUserRole.ADMIN,
  51. )
  52. except Team.DoesNotExist:
  53. raise exceptions.ValidationError("Team not found")
  54. try:
  55. organization = Organization.objects.get(
  56. slug=self.kwargs.get("organization_slug"),
  57. users=self.request.user,
  58. organization_users__role__gte=OrganizationUserRole.ADMIN,
  59. )
  60. except Organization.DoesNotExist:
  61. raise exceptions.ValidationError("Organization not found")
  62. new_project = serializer.save(organization=organization)
  63. if new_project and team:
  64. new_project.team_set.add(team)
  65. class ProjectViewSet(NestedProjectViewSet):
  66. filter_backends = [OrderingFilter]
  67. ordering = ["name"]
  68. ordering_fields = ["name"]
  69. lookup_field = "pk"
  70. lookup_value_regex = r"(?P<organization_slug>[^/.]+)/(?P<project_slug>[-\w]+)"
  71. def create(self, request, *args, **kwargs):
  72. raise exceptions.MethodNotAllowed(
  73. request.method,
  74. "Create project not allowed. Use team-projects view instead.",
  75. )
  76. class ProjectKeyViewSet(viewsets.ModelViewSet):
  77. queryset = ProjectKey.objects.all()
  78. serializer_class = ProjectKeySerializer
  79. lookup_field = "public_key"
  80. permission_classes = [ProjectKeyPermission]
  81. def get_queryset(self):
  82. if not self.request.user.is_authenticated:
  83. return self.queryset.none()
  84. return (
  85. super()
  86. .get_queryset()
  87. .filter(
  88. project__slug=self.kwargs["project_slug"],
  89. project__organization__slug=self.kwargs["organization_slug"],
  90. project__organization__users=self.request.user,
  91. )
  92. )
  93. def perform_create(self, serializer):
  94. project = get_object_or_404(
  95. Project,
  96. slug=self.kwargs.get("project_slug"),
  97. organization__slug=self.kwargs["organization_slug"],
  98. organization__users=self.request.user,
  99. )
  100. serializer.save(project=project)
  101. class ProjectTeamViewSet(NestedTeamViewSet):
  102. @action(
  103. methods=["post", "delete"], detail=False, url_path=("(?P<team_slug>[-\w]+)")
  104. )
  105. def add_remove_project(
  106. self,
  107. request,
  108. project_pk=None,
  109. project_slug=None,
  110. organization_slug=None,
  111. team_slug=None,
  112. ):
  113. """Add/remove team to a project"""
  114. team = get_object_or_404(self.get_queryset(), slug=team_slug)
  115. project = get_object_or_404(
  116. Project,
  117. slug=project_slug,
  118. organization__slug=organization_slug,
  119. organization__users=self.request.user,
  120. organization__organization_users__role__gte=OrganizationUserRole.MANAGER,
  121. )
  122. serializer = ProjectSerializer(instance=project, context={"request": request})
  123. if request.method == "POST":
  124. project.team_set.add(team)
  125. return Response(serializer.data, status=status.HTTP_201_CREATED)
  126. project.team_set.remove(team)
  127. return Response(serializer.data)