views.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. from rest_framework import exceptions, mixins, viewsets
  2. from rest_framework.decorators import action
  3. from rest_framework.response import Response
  4. from files.tasks import assemble_artifacts_task
  5. from organizations_ext.models import Organization
  6. from projects.models import Project
  7. from .models import Release, ReleaseFile
  8. from .permissions import ReleaseFilePermission, ReleasePermission
  9. from .serializers import (
  10. AssembleSerializer,
  11. ReleaseFileSerializer,
  12. ReleaseSerializer,
  13. ReleaseUpdateSerializer,
  14. )
  15. class ReleaseViewSet(viewsets.ModelViewSet):
  16. """
  17. /organizations/<org-slug>/releases/
  18. Sentry includes only project name and slug in nested list. This view uses ProjectReferenceSerializer,
  19. which also includes id and platform, for consistency.
  20. """
  21. queryset = Release.objects.all()
  22. serializer_class = ReleaseSerializer
  23. permission_classes = [ReleasePermission]
  24. lookup_field = "version"
  25. lookup_value_regex = "[^/]+"
  26. def get_serializer_class(self):
  27. serializer_class = self.serializer_class
  28. if self.request.method == "PUT":
  29. serializer_class = ReleaseUpdateSerializer
  30. return serializer_class
  31. def get_queryset(self):
  32. if not self.request.user.is_authenticated:
  33. return self.queryset.none()
  34. queryset = self.queryset.filter(organization__users=self.request.user)
  35. organization_slug = self.kwargs.get("organization_slug")
  36. if organization_slug:
  37. queryset = queryset.filter(organization__slug=organization_slug)
  38. project_slug = self.kwargs.get("project_slug")
  39. if project_slug:
  40. queryset = queryset.filter(projects__slug=project_slug)
  41. return queryset
  42. def get_organization(self):
  43. try:
  44. return Organization.objects.get(
  45. slug=self.kwargs.get("organization_slug"),
  46. users=self.request.user,
  47. )
  48. except Organization.DoesNotExist:
  49. raise exceptions.ValidationError("Organization does not exist")
  50. def perform_create(self, serializer):
  51. organization = self.get_organization()
  52. try:
  53. project = Project.objects.get(
  54. slug=self.kwargs.get("project_slug"),
  55. organization=organization,
  56. )
  57. except Project.DoesNotExist:
  58. raise exceptions.ValidationError("Project does not exist")
  59. release = serializer.save(organization=organization)
  60. release.projects.add(project)
  61. @action(detail=True, methods=["post"])
  62. def assemble(self, request, organization_slug: str, version: str):
  63. organization = self.get_organization()
  64. release = self.get_object()
  65. serializer = AssembleSerializer(data=request.data)
  66. serializer.is_valid(raise_exception=True)
  67. checksum = serializer.validated_data.get("checksum", None)
  68. chunks = serializer.validated_data.get("chunks", [])
  69. assemble_artifacts_task.delay(
  70. org_id=organization.id,
  71. version=version,
  72. checksum=checksum,
  73. chunks=chunks,
  74. )
  75. # TODO should return more state's
  76. return Response({"state": "ok", "missingChunks": []})
  77. class ReleaseFileViewSet(
  78. mixins.CreateModelMixin,
  79. mixins.ListModelMixin,
  80. mixins.DestroyModelMixin,
  81. mixins.RetrieveModelMixin,
  82. viewsets.GenericViewSet,
  83. ):
  84. queryset = ReleaseFile.objects.all()
  85. serializer_class = ReleaseFileSerializer
  86. permission_classes = [ReleaseFilePermission]
  87. def get_queryset(self):
  88. queryset = self.queryset
  89. if not self.request.user.is_authenticated:
  90. return queryset.none()
  91. queryset = queryset.filter(
  92. release__organization__users=self.request.user,
  93. release__organization__slug=self.kwargs.get("organization_slug"),
  94. release__version=self.kwargs.get("release_version"),
  95. )
  96. if self.kwargs.get("project_slug"):
  97. queryset = queryset.filter(
  98. release__projects__slug=self.kwargs.get("project_slug")
  99. )
  100. queryset = queryset.select_related("file")
  101. return queryset
  102. def perform_create(self, serializer):
  103. try:
  104. release = Release.objects.get(
  105. version=self.kwargs.get("release_version"),
  106. organization__slug=self.kwargs.get("organization_slug"),
  107. )
  108. except Release.DoesNotExist:
  109. raise exceptions.ValidationError("Release does not exist")
  110. serializer.save(release=release)