views.py 5.3 KB

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