Skip to content

Commit 2a0d95f

Browse files
committed
rework api perms to allow read by authed user, edit by superuser
1 parent b2fcf91 commit 2a0d95f

3 files changed

Lines changed: 36 additions & 6 deletions

File tree

dojo/authorization/api_permissions.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from dojo.importers.auto_create_context import AutoCreateContextManager
2020
from dojo.location.models import Location
2121
from dojo.models import (
22+
CICDInfrastructure,
2223
Development_Environment,
2324
Endpoint,
2425
Engagement,
@@ -919,6 +920,19 @@ class UserHasRegulationPermission(BaseDjangoModelPermission):
919920
}
920921

921922

923+
class UserHasCICDInfrastructurePermission(BaseDjangoModelPermission):
924+
django_model = CICDInfrastructure
925+
# Reads are open to any authenticated user (engagement views surface CICD
926+
# references and need to render them). Writes require the configuration
927+
# permission — superuser/staff on OS, full RBAC under Pro shadowing.
928+
request_method_permission_map = {
929+
"POST": "add",
930+
"PUT": "change",
931+
"PATCH": "change",
932+
"DELETE": "delete",
933+
}
934+
935+
922936
def raise_no_auto_create_import_validation_error(
923937
test_title,
924938
scan_type,
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
from django_filters.rest_framework import DjangoFilterBackend
2+
from rest_framework.permissions import IsAuthenticated
23

34
from dojo.api_v2.views import DojoModelViewSet
45
from dojo.authorization import api_permissions as permissions
56
from dojo.cicd_infrastructure.api.serializers import CICDInfrastructureSerializer
67
from dojo.models import CICDInfrastructure
78

89

9-
# Authorization: configuration
10+
# Authorization: read open to authenticated users; write requires configuration permission.
1011
class CICDInfrastructureViewSet(
1112
DojoModelViewSet,
1213
):
1314
serializer_class = CICDInfrastructureSerializer
1415
queryset = CICDInfrastructure.objects.none()
1516
filter_backends = (DjangoFilterBackend,)
1617
filterset_fields = ["id", "name", "infrastructure_type"]
17-
permission_classes = (permissions.UserHasConfigurationPermissionSuperuser,)
18+
permission_classes = (IsAuthenticated, permissions.UserHasCICDInfrastructurePermission)
1819

1920
def get_queryset(self):
2021
return CICDInfrastructure.objects.all().order_by("id")

unittests/test_cicd_infrastructure.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,9 @@ def test_disabled_field_ignores_posted_value(self):
9696
class CICDInfrastructureAPITests(APITestCase):
9797

9898
"""
99-
The /cicd_infrastructure endpoint uses UserHasConfigurationPermissionSuperuser
100-
— superusers can do anything; non-superusers need the explicit Django permission.
99+
The /cicd_infrastructure endpoint uses UserHasCICDInfrastructurePermission
100+
— reads are open to any authenticated user; writes require the configuration
101+
permission (superuser/staff on OS, full RBAC under Pro).
101102
"""
102103

103104
fixtures = ["dojo_testdata.json"]
@@ -144,11 +145,25 @@ def test_create_allows_same_name_different_type(self):
144145
)
145146
self.assertEqual(r.status_code, 201, r.content[:1000])
146147

147-
def test_non_superuser_is_rejected(self):
148+
def test_non_superuser_can_list(self):
148149
# 'user1' (pk=2 in dojo_testdata.json) is a non-superuser with a token.
150+
# Reads are open to authenticated users.
149151
try:
150152
c = self._client_for("user1")
151153
except Token.DoesNotExist:
152154
self.skipTest("user1 token not present in dojo_testdata fixture.")
153155
r = c.get(reverse("cicd_infrastructure-list"))
154-
self.assertIn(r.status_code, (401, 403), f"expected 401/403, got {r.status_code}")
156+
self.assertEqual(r.status_code, 200, r.content[:1000])
157+
158+
def test_non_superuser_cannot_create(self):
159+
try:
160+
c = self._client_for("user1")
161+
except Token.DoesNotExist:
162+
self.skipTest("user1 token not present in dojo_testdata fixture.")
163+
r = c.post(
164+
reverse("cicd_infrastructure-list"),
165+
{"name": "NonSuperCreate", "infrastructure_type": "build_server"},
166+
format="json",
167+
)
168+
self.assertEqual(r.status_code, 403, r.content[:1000])
169+
self.assertFalse(CICDInfrastructure.objects.filter(name="NonSuperCreate").exists())

0 commit comments

Comments
 (0)