diff --git a/api/integrations/launch_darkly/views.py b/api/integrations/launch_darkly/views.py index b6dc98af71c6..93e2ddc0cc81 100644 --- a/api/integrations/launch_darkly/views.py +++ b/api/integrations/launch_darkly/views.py @@ -4,6 +4,7 @@ from drf_yasg.utils import swagger_auto_schema from rest_framework import mixins, status, viewsets from rest_framework.exceptions import ValidationError +from rest_framework.permissions import BasePermission from rest_framework.request import Request from rest_framework.response import Response @@ -16,7 +17,12 @@ from integrations.launch_darkly.tasks import ( process_launch_darkly_import_request, ) -from projects.permissions import CREATE_ENVIRONMENT, VIEW_PROJECT +from projects.models import Project +from projects.permissions import ( + CREATE_ENVIRONMENT, + VIEW_PROJECT, + NestedProjectPermissions, +) class LaunchDarklyImportRequestViewSet( @@ -29,14 +35,21 @@ class LaunchDarklyImportRequestViewSet( pagination_class = None # set here to ensure documentation is correct model_class = LaunchDarklyImportRequest + def get_permissions(self) -> list[BasePermission]: + return [ + NestedProjectPermissions( + action_permission_map={ + "retrieve": VIEW_PROJECT, + "create": CREATE_ENVIRONMENT, + } + ), + ] + def get_queryset(self) -> QuerySet[LaunchDarklyImportRequest]: if getattr(self, "swagger_fake_view", False): return self.model_class.objects.none() - project = get_object_or_404( - self.request.user.get_permitted_projects(VIEW_PROJECT), - pk=self.kwargs["project_pk"], - ) + project = get_object_or_404(Project, pk=self.kwargs["project_pk"]) return self.model_class.objects.filter(project=project) @swagger_auto_schema( @@ -49,10 +62,7 @@ def create(self, request: Request, *args, **kwargs) -> Response: ) request_serializer.is_valid(raise_exception=True) - project = get_object_or_404( - self.request.user.get_permitted_projects(CREATE_ENVIRONMENT), - pk=self.kwargs["project_pk"], - ) + project = get_object_or_404(Project, pk=self.kwargs["project_pk"]) try: instance = create_import_request( diff --git a/api/tests/unit/integrations/launch_darkly/test_views.py b/api/tests/unit/integrations/launch_darkly/test_views.py index 060dd1cde803..6cbced078734 100644 --- a/api/tests/unit/integrations/launch_darkly/test_views.py +++ b/api/tests/unit/integrations/launch_darkly/test_views.py @@ -24,7 +24,39 @@ def test_launch_darkly_import_request_view__list__wrong_project__return_expected response = api_client.get(url) # Then - assert response.status_code == status.HTTP_404_NOT_FOUND + assert response.status_code == status.HTTP_403_FORBIDDEN + + +def test_launch_darkly_import_request_view__list__return_expected( + import_request: LaunchDarklyImportRequest, + project: Project, + admin_client: APIClient, + mocker: MockerFixture, +) -> None: + # Given + url = reverse("api-v1:projects:imports-launch-darkly-list", args=[project.id]) + + # When + response = admin_client.get(url) + + # Then + assert response.status_code == status.HTTP_200_OK + assert response.json() == [ + { + "completed_at": None, + "created_at": mocker.ANY, + "created_by": "user@example.com", + "id": import_request.id, + "project": project.id, + "status": { + "error_messages": [], + "requested_environment_count": 2, + "requested_flag_count": 9, + "result": None, + }, + "updated_at": mocker.ANY, + }, + ] def test_launch_darkly_import_request_view__create__return_expected(