1
0
mirror of https://github.com/ansible/awx.git synced 2024-10-31 15:21:13 +03:00

add some additional validation to JT.credentials

see: https://github.com/ansible/tower/issues/2612
This commit is contained in:
Ryan Petrello 2018-07-30 13:36:37 -04:00
parent 6e3686bfc9
commit b99f211c7e
No known key found for this signature in database
GPG Key ID: F2AA5F2122351777
4 changed files with 51 additions and 2 deletions

View File

@ -4285,6 +4285,10 @@ class JobLaunchSerializer(BaseSerializer):
errors.setdefault('credentials', []).append(_(
'Cannot assign multiple {} credentials.'
).format(cred.unique_hash(display=True)))
if cred.credential_type.kind not in ('ssh', 'vault', 'cloud', 'net'):
errors.setdefault('credentials', []).append(_(
'Cannot assign a Credential of kind `{}`'
).format(cred.credential_type.kind))
distinct_cred_kinds.append(cred.unique_hash())
# Prohibit removing credentials from the JT list (unsupported for now)

View File

@ -3346,6 +3346,9 @@ class JobTemplateCredentialsList(SubListCreateAttachDetachAPIView):
if sub.unique_hash() in [cred.unique_hash() for cred in parent.credentials.all()]:
return {"error": _("Cannot assign multiple {credential_type} credentials.".format(
credential_type=sub.unique_hash(display=True)))}
kind = sub.credential_type.kind
if kind not in ('ssh', 'vault', 'cloud', 'net'):
return {'error': _('Cannot assign a Credential of kind `{}`.').format(kind)}
return super(JobTemplateCredentialsList, self).is_valid_relation(parent, sub, created)

View File

@ -2,7 +2,7 @@ import json
import mock
import pytest
from awx.main.models import Credential, Job
from awx.main.models import Credential, CredentialType, Job
from awx.api.versioning import reverse
@ -151,6 +151,27 @@ def test_prevent_multiple_machine_creds(get, post, job_template, admin, machine_
assert 'Cannot assign multiple Machine credentials.' in resp.content
@pytest.mark.django_db
@pytest.mark.parametrize('kind', ['scm', 'insights'])
def test_invalid_credential_type_at_launch(get, post, job_template, admin, kind):
cred_type = CredentialType.defaults[kind]()
cred_type.save()
cred = Credential(
name='Some Cred',
credential_type=cred_type,
inputs={
'username': 'bob',
'password': 'secret',
}
)
cred.save()
url = reverse('api:job_template_launch', kwargs={'pk': job_template.pk})
resp = post(url, {'credentials': [cred.pk]}, admin, expect=400)
assert 'Cannot assign a Credential of kind `{}`'.format(kind) in resp.data.get('credentials', [])
assert Job.objects.count() == 0
@pytest.mark.django_db
def test_prevent_multiple_machine_creds_at_launch(get, post, job_template, admin, machine_credential):
other_cred = Credential(credential_type=machine_credential.credential_type, name="Second",

View File

@ -6,7 +6,7 @@ import pytest
# AWX
from awx.api.serializers import JobTemplateSerializer
from awx.api.versioning import reverse
from awx.main.models.jobs import Job, JobTemplate
from awx.main.models import Job, JobTemplate, CredentialType
from awx.main.migrations import _save_password_keys as save_password_keys
# Django
@ -182,6 +182,27 @@ def test_extra_credential_creation(get, post, organization_factory, job_template
assert response.data.get('count') == 1
@pytest.mark.django_db
@pytest.mark.parametrize('kind', ['scm', 'insights'])
def test_invalid_credential_kind_xfail(get, post, organization_factory, job_template_factory, kind):
objs = organization_factory("org", superusers=['admin'])
jt = job_template_factory("jt", organization=objs.organization,
inventory='test_inv', project='test_proj').job_template
url = reverse('api:job_template_credentials_list', kwargs={'version': 'v2', 'pk': jt.pk})
cred_type = CredentialType.defaults[kind]()
cred_type.save()
response = post(url, {
'name': 'My Cred',
'credential_type': cred_type.pk,
'inputs': {
'username': 'bob',
'password': 'secret',
}
}, objs.superusers.admin, expect=400)
assert 'Cannot assign a Credential of kind `{}`.'.format(kind) in response.data.values()
@pytest.mark.django_db
def test_extra_credential_unique_type_xfail(get, post, organization_factory, job_template_factory, credentialtype_aws):
objs = organization_factory("org", superusers=['admin'])