mirror of
https://github.com/ansible/awx.git
synced 2026-01-14 03:10:42 -03:30
Merge pull request #7240 from ryanpetrello/fix-7216
improve sanitation of empty credential values to match API v1 behavior
This commit is contained in:
commit
340ced02e2
@ -420,15 +420,15 @@ def format_ssh_private_key(value):
|
||||
# These end in a unicode-encoded final character that gets double
|
||||
# escaped due to being in a Python 2 bytestring, and that causes
|
||||
# Python's key parsing to barf. Detect this issue and correct it.
|
||||
if value == '$encrypted$':
|
||||
return value
|
||||
if not value or value == '$encrypted$':
|
||||
return True
|
||||
if r'\u003d' in value:
|
||||
value = value.replace(r'\u003d', '=')
|
||||
try:
|
||||
validate_ssh_private_key(value)
|
||||
except django_exceptions.ValidationError as e:
|
||||
raise jsonschema.exceptions.FormatError(e.message)
|
||||
return value
|
||||
return True
|
||||
|
||||
|
||||
class CredentialInputField(JSONSchemaField):
|
||||
@ -478,6 +478,13 @@ class CredentialInputField(JSONSchemaField):
|
||||
return super(CredentialInputField, self).validate(value,
|
||||
model_instance)
|
||||
|
||||
# Backwards compatability: in prior versions, if you submit `null` for
|
||||
# a credential field value, it just considers the value an empty string
|
||||
for unset in [key for key, v in model_instance.inputs.items() if not v]:
|
||||
default_value = model_instance.credential_type.default_for_field(unset)
|
||||
if default_value is not None:
|
||||
model_instance.inputs[unset] = default_value
|
||||
|
||||
decrypted_values = {}
|
||||
for k, v in value.items():
|
||||
if all([
|
||||
|
||||
@ -457,6 +457,13 @@ class CredentialType(CommonModelNameNotUnique):
|
||||
if field.get('ask_at_runtime', False) is True
|
||||
]
|
||||
|
||||
def default_for_field(self, field_id):
|
||||
for field in self.inputs.get('fields', []):
|
||||
if field['id'] == field_id:
|
||||
if 'choices' in field:
|
||||
return field['choices'][0]
|
||||
return {'string': '', 'boolean': False}[field['type']]
|
||||
|
||||
@classmethod
|
||||
def default(cls, f):
|
||||
func = functools.partial(f, cls)
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import itertools
|
||||
|
||||
import mock # noqa
|
||||
import pytest
|
||||
|
||||
@ -707,6 +709,59 @@ def test_inputs_cannot_contain_extra_fields(get, post, organization, admin, cred
|
||||
assert "'invalid_field' was unexpected" in response.data['inputs'][0]
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@pytest.mark.parametrize('field_name, field_value', itertools.product(
|
||||
['username', 'password', 'ssh_key_data', 'ssh_key_unlock', 'become_method', 'become_username', 'become_password'], # noqa
|
||||
['', None]
|
||||
))
|
||||
def test_nullish_field_data(get, post, organization, admin, field_name, field_value):
|
||||
ssh = CredentialType.defaults['ssh']()
|
||||
ssh.save()
|
||||
params = {
|
||||
'name': 'Best credential ever',
|
||||
'credential_type': ssh.pk,
|
||||
'organization': organization.id,
|
||||
'inputs': {
|
||||
field_name: field_value
|
||||
}
|
||||
}
|
||||
response = post(
|
||||
reverse('api:credential_list', kwargs={'version': 'v2'}),
|
||||
params,
|
||||
admin
|
||||
)
|
||||
assert response.status_code == 201
|
||||
|
||||
assert Credential.objects.count() == 1
|
||||
cred = Credential.objects.all()[:1].get()
|
||||
assert getattr(cred, field_name) == ''
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@pytest.mark.parametrize('field_value', ['', None, False])
|
||||
def test_falsey_field_data(get, post, organization, admin, field_value):
|
||||
net = CredentialType.defaults['net']()
|
||||
net.save()
|
||||
params = {
|
||||
'name': 'Best credential ever',
|
||||
'credential_type': net.pk,
|
||||
'organization': organization.id,
|
||||
'inputs': {
|
||||
'authorize': field_value
|
||||
}
|
||||
}
|
||||
response = post(
|
||||
reverse('api:credential_list', kwargs={'version': 'v2'}),
|
||||
params,
|
||||
admin
|
||||
)
|
||||
assert response.status_code == 201
|
||||
|
||||
assert Credential.objects.count() == 1
|
||||
cred = Credential.objects.all()[:1].get()
|
||||
assert cred.authorize is False
|
||||
|
||||
|
||||
#
|
||||
# SCM Credentials
|
||||
#
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user