Skip to content

Commit 9c392cb

Browse files
authored
fix: skip validating inputs to allow updating credentials' name or description (#865)
1 parent 89dde47 commit 9c392cb

File tree

3 files changed

+82
-27
lines changed

3 files changed

+82
-27
lines changed

src/aap_eda/api/serializers/eda_credential.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14-
1514
from django.db.models import Q
1615
from drf_spectacular.utils import extend_schema_field
1716
from rest_framework import serializers
@@ -124,9 +123,13 @@ def validate(self, data):
124123
# for update
125124
credential_type = self.instance.credential_type
126125

127-
errors = validate_inputs(
128-
credential_type.inputs, data.get("inputs", {})
129-
)
126+
inputs = data.get("inputs", {})
127+
128+
# allow emtpy inputs during updating
129+
if self.partial and not bool(inputs):
130+
return data
131+
132+
errors = validate_inputs(credential_type.inputs, inputs)
130133

131134
if bool(errors):
132135
raise serializers.ValidationError(errors)

src/aap_eda/api/views/eda_credential.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,10 @@ def partial_update(self, request, pk):
190190
)
191191
serializer.is_valid(raise_exception=True)
192192

193-
if serializer.validated_data.get("inputs"):
193+
inputs = serializer.validated_data.get("inputs")
194+
if inputs or inputs == {}:
194195
serializer.validated_data["inputs"] = inputs_to_store(
195-
serializer.validated_data["inputs"],
196+
inputs,
196197
eda_credential.inputs,
197198
)
198199

tests/integration/api/test_eda_credential.py

Lines changed: 72 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from rest_framework.test import APIClient
66

77
from aap_eda.core import enums, models
8+
from tests.integration.conftest import DUMMY_GPG_KEY
89
from tests.integration.constants import api_url_v1
910

1011
DATA_DIR = Path(__file__).parent.parent.parent / "unit/data"
@@ -36,14 +37,18 @@
3637
}
3738

3839

40+
@pytest.mark.parametrize(
41+
"inputs", [{}, {"username": "adam", "password": "secret"}]
42+
)
3943
@pytest.mark.django_db
4044
def test_create_eda_credential(
4145
client: APIClient,
4246
credential_type: models.CredentialType,
47+
inputs,
4348
):
4449
data_in = {
4550
"name": "eda-credential",
46-
"inputs": {"username": "adam", "password": "secret"},
51+
"inputs": inputs,
4752
"credential_type_id": credential_type.id,
4853
}
4954
response = client.post(f"{api_url_v1}/eda-credentials/", data=data_in)
@@ -111,24 +116,6 @@ def test_create_eda_credential_with_type(
111116
}
112117

113118

114-
@pytest.mark.django_db
115-
def test_create_eda_credential_with_empty_required_field(
116-
client: APIClient, preseed_credential_types
117-
):
118-
credential_type = models.CredentialType.objects.get(
119-
name=enums.DefaultCredentialType.REGISTRY
120-
)
121-
122-
data_in = {
123-
"name": "eda-credential",
124-
"inputs": {"host": ""},
125-
"credential_type_id": credential_type.id,
126-
}
127-
response = client.post(f"{api_url_v1}/eda-credentials/", data=data_in)
128-
assert response.status_code == status.HTTP_400_BAD_REQUEST
129-
assert "Cannot be blank" in response.data["inputs.host"]
130-
131-
132119
@pytest.mark.parametrize(
133120
("credential_type", "status_code", "key", "error_message"),
134121
[
@@ -349,7 +336,7 @@ def test_delete_managed_eda_credential(client: APIClient):
349336

350337

351338
@pytest.mark.django_db
352-
def test_partial_update_eda_credential(
339+
def test_partial_update_eda_credential_without_inputs(
353340
client: APIClient, credential_type: models.CredentialType
354341
):
355342
obj = models.EdaCredential.objects.create(
@@ -371,8 +358,72 @@ def test_partial_update_eda_credential(
371358
}
372359

373360

361+
@pytest.mark.parametrize(
362+
("credential_type", "inputs"),
363+
[
364+
(enums.DefaultCredentialType.VAULT, {}),
365+
(
366+
enums.DefaultCredentialType.VAULT,
367+
{"vault_password": "new_password"},
368+
),
369+
(enums.DefaultCredentialType.AAP, {}),
370+
(
371+
enums.DefaultCredentialType.AAP,
372+
{"host": "new_host", "username": "new user"},
373+
),
374+
(enums.DefaultCredentialType.GPG, {}),
375+
(enums.DefaultCredentialType.GPG, {"gpg_public_key": DUMMY_GPG_KEY}),
376+
(enums.DefaultCredentialType.REGISTRY, {}),
377+
(
378+
enums.DefaultCredentialType.REGISTRY,
379+
{"host": "new_host", "username": "new user", "verify_ssl": True},
380+
),
381+
(enums.DefaultCredentialType.SOURCE_CONTROL, {}),
382+
(
383+
enums.DefaultCredentialType.SOURCE_CONTROL,
384+
{"username": "new user", "password": "new password"},
385+
),
386+
],
387+
)
388+
@pytest.mark.django_db
389+
def test_partial_update_eda_credentials(
390+
client: APIClient,
391+
preseed_credential_types,
392+
credential_type,
393+
inputs,
394+
):
395+
old_inputs = {"keep": "data"}
396+
credential_type = models.CredentialType.objects.get(name=credential_type)
397+
obj = models.EdaCredential.objects.create(
398+
name="eda-credential",
399+
inputs=old_inputs,
400+
credential_type_id=credential_type.id,
401+
)
402+
new_name = "new-eda-credential"
403+
new_description = "new-eda-credential description"
404+
# update name, description with empty inputs
405+
data = {"name": new_name, "description": new_description, "inputs": inputs}
406+
response = client.patch(
407+
f"{api_url_v1}/eda-credentials/{obj.id}/", data=data
408+
)
409+
assert response.status_code == status.HTTP_200_OK
410+
result = response.data
411+
assert result["name"] == new_name
412+
assert result["description"] == new_description
413+
414+
data = {"inputs": inputs}
415+
# update inputs
416+
response = client.patch(
417+
f"{api_url_v1}/eda-credentials/{obj.id}/", data=data
418+
)
419+
result = response.data
420+
assert result["inputs"]["keep"] == old_inputs["keep"]
421+
for key in inputs.keys():
422+
assert result["inputs"][key] is not None
423+
424+
374425
@pytest.mark.django_db
375-
def test_partial_update_eda_credential_name(
426+
def test_partial_update_eda_credential_with_encrypted_output(
376427
client: APIClient, credential_type: models.CredentialType
377428
):
378429
obj = models.EdaCredential.objects.create(

0 commit comments

Comments
 (0)