Skip to content

Commit 55ebbf3

Browse files
authored
fix: disallow updating credential type on credential patch endpoint (#1137)
1 parent 8ebeecb commit 55ebbf3

File tree

4 files changed

+62
-13
lines changed

4 files changed

+62
-13
lines changed

src/aap_eda/api/serializers/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
from .eda_credential import (
3838
EdaCredentialCreateSerializer,
3939
EdaCredentialSerializer,
40+
EdaCredentialUpdateSerializer,
4041
)
4142
from .event_stream import EventStreamInSerializer, EventStreamOutSerializer
4243
from .organization import (
@@ -120,6 +121,7 @@
120121
"CredentialTypeRefSerializer",
121122
"EdaCredentialSerializer",
122123
"EdaCredentialCreateSerializer",
124+
"EdaCredentialUpdateSerializer",
123125
# decision environment
124126
"DecisionEnvironmentSerializer",
125127
# organizations

src/aap_eda/api/serializers/eda_credential.py

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -115,23 +115,45 @@ class EdaCredentialCreateSerializer(serializers.ModelSerializer):
115115
inputs = serializers.JSONField()
116116

117117
def validate(self, data):
118-
credential_type_id = data.get("credential_type_id")
119-
if credential_type_id:
120-
credential_type = models.CredentialType.objects.get(
121-
id=credential_type_id
122-
)
123-
else:
124-
# for update
125-
credential_type = self.instance.credential_type
118+
credential_type = models.CredentialType.objects.get(
119+
id=data.get("credential_type_id")
120+
)
126121

127122
inputs = data.get("inputs", {})
123+
errors = validate_inputs(credential_type.inputs, inputs)
124+
if bool(errors):
125+
raise serializers.ValidationError(errors)
128126

129-
# allow emtpy inputs during updating
127+
return data
128+
129+
class Meta:
130+
model = models.EdaCredential
131+
fields = [
132+
"name",
133+
"description",
134+
"inputs",
135+
"credential_type_id",
136+
"organization_id",
137+
]
138+
139+
140+
class EdaCredentialUpdateSerializer(serializers.ModelSerializer):
141+
organization_id = serializers.IntegerField(
142+
required=True,
143+
allow_null=False,
144+
validators=[validators.check_if_organization_exists],
145+
)
146+
inputs = serializers.JSONField()
147+
148+
def validate(self, data):
149+
credential_type = self.instance.credential_type
150+
151+
inputs = data.get("inputs", {})
152+
# allow empty inputs during updating
130153
if self.partial and not bool(inputs):
131154
return data
132155

133156
errors = validate_inputs(credential_type.inputs, inputs)
134-
135157
if bool(errors):
136158
raise serializers.ValidationError(errors)
137159

@@ -143,7 +165,6 @@ class Meta:
143165
"name",
144166
"description",
145167
"inputs",
146-
"credential_type_id",
147168
"organization_id",
148169
]
149170

src/aap_eda/api/views/eda_credential.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ def list(self, request):
184184

185185
@extend_schema(
186186
description="Partial update of an EDA credential",
187-
request=serializers.EdaCredentialCreateSerializer,
187+
request=serializers.EdaCredentialUpdateSerializer,
188188
responses={
189189
status.HTTP_200_OK: OpenApiResponse(
190190
serializers.EdaCredentialSerializer,
@@ -202,7 +202,7 @@ def partial_update(self, request, pk):
202202
data.get("inputs", {}), eda_credential.inputs
203203
)
204204

205-
serializer = serializers.EdaCredentialCreateSerializer(
205+
serializer = serializers.EdaCredentialUpdateSerializer(
206206
eda_credential, data=data, partial=True
207207
)
208208
serializer.is_valid(raise_exception=True)

tests/integration/api/test_eda_credential.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,32 @@ def test_partial_update_eda_credential_with_invalid_inputs(
500500
)
501501

502502

503+
@pytest.mark.django_db
504+
def test_partial_update_eda_credential_type_not_changed(
505+
admin_client: APIClient,
506+
default_registry_credential: models.EdaCredential,
507+
preseed_credential_types,
508+
):
509+
aap_cred_type = models.CredentialType.objects.get(
510+
name=enums.DefaultCredentialType.AAP
511+
)
512+
data = {"credential_type_id": aap_cred_type.id}
513+
response = admin_client.patch(
514+
f"{api_url_v1}/eda-credentials/{default_registry_credential.id}/",
515+
data=data,
516+
)
517+
assert response.status_code == status.HTTP_200_OK
518+
result = response.data
519+
assert (
520+
result["credential_type"]["id"]
521+
== default_registry_credential.credential_type.id
522+
)
523+
assert (
524+
result["credential_type"]["name"]
525+
== default_registry_credential.credential_type.name
526+
)
527+
528+
503529
@pytest.mark.parametrize(
504530
("credential_type", "old_inputs", "inputs", "expected_inputs"),
505531
[

0 commit comments

Comments
 (0)