Merge pull request #2715 from ryanpetrello/fix-2612

add some additional validation to JT.credentials
This commit is contained in:
Ryan Petrello
2018-07-30 14:34:20 -04:00
committed by GitHub
4 changed files with 51 additions and 2 deletions

View File

@@ -4285,6 +4285,10 @@ class JobLaunchSerializer(BaseSerializer):
errors.setdefault('credentials', []).append(_( errors.setdefault('credentials', []).append(_(
'Cannot assign multiple {} credentials.' 'Cannot assign multiple {} credentials.'
).format(cred.unique_hash(display=True))) ).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()) distinct_cred_kinds.append(cred.unique_hash())
# Prohibit removing credentials from the JT list (unsupported for now) # 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()]: if sub.unique_hash() in [cred.unique_hash() for cred in parent.credentials.all()]:
return {"error": _("Cannot assign multiple {credential_type} credentials.".format( return {"error": _("Cannot assign multiple {credential_type} credentials.".format(
credential_type=sub.unique_hash(display=True)))} 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) return super(JobTemplateCredentialsList, self).is_valid_relation(parent, sub, created)

View File

@@ -2,7 +2,7 @@ import json
import mock import mock
import pytest import pytest
from awx.main.models import Credential, Job from awx.main.models import Credential, CredentialType, Job
from awx.api.versioning import reverse 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 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 @pytest.mark.django_db
def test_prevent_multiple_machine_creds_at_launch(get, post, job_template, admin, machine_credential): 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", other_cred = Credential(credential_type=machine_credential.credential_type, name="Second",

View File

@@ -6,7 +6,7 @@ import pytest
# AWX # AWX
from awx.api.serializers import JobTemplateSerializer from awx.api.serializers import JobTemplateSerializer
from awx.api.versioning import reverse 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 from awx.main.migrations import _save_password_keys as save_password_keys
# Django # Django
@@ -182,6 +182,27 @@ def test_extra_credential_creation(get, post, organization_factory, job_template
assert response.data.get('count') == 1 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 @pytest.mark.django_db
def test_extra_credential_unique_type_xfail(get, post, organization_factory, job_template_factory, credentialtype_aws): def test_extra_credential_unique_type_xfail(get, post, organization_factory, job_template_factory, credentialtype_aws):
objs = organization_factory("org", superusers=['admin']) objs = organization_factory("org", superusers=['admin'])