mirror of
https://github.com/ZwareBear/awx.git
synced 2026-04-23 00:11:48 -05:00
encrypt job survey data
see: https://github.com/ansible/ansible-tower/issues/7046
This commit is contained in:
committed by
Matthew Jones
parent
9978b3f9ad
commit
4be4e3db7f
@@ -91,6 +91,111 @@ def test_survey_spec_sucessful_creation(survey_spec_factory, job_template, post,
|
||||
assert updated_jt.survey_spec == survey_input_data
|
||||
|
||||
|
||||
@mock.patch('awx.api.views.feature_enabled', lambda feature: True)
|
||||
@pytest.mark.django_db
|
||||
@pytest.mark.parametrize('value, status', [
|
||||
('SUPERSECRET', 201),
|
||||
(['some', 'invalid', 'list'], 400),
|
||||
({'some-invalid': 'dict'}, 400),
|
||||
(False, 400)
|
||||
])
|
||||
def test_survey_spec_passwords_are_encrypted_on_launch(job_template_factory, post, admin_user, value, status):
|
||||
objects = job_template_factory('jt', organization='org1', project='prj',
|
||||
inventory='inv', credential='cred')
|
||||
job_template = objects.job_template
|
||||
job_template.survey_enabled = True
|
||||
job_template.save()
|
||||
input_data = {
|
||||
'description': 'A survey',
|
||||
'spec': [{
|
||||
'index': 0,
|
||||
'question_name': 'What is your password?',
|
||||
'required': True,
|
||||
'variable': 'secret_value',
|
||||
'type': 'password'
|
||||
}],
|
||||
'name': 'my survey'
|
||||
}
|
||||
post(url=reverse('api:job_template_survey_spec', kwargs={'pk': job_template.id}),
|
||||
data=input_data, user=admin_user, expect=200)
|
||||
resp = post(reverse('api:job_template_launch', kwargs={'pk': job_template.pk}),
|
||||
dict(extra_vars=dict(secret_value=value)), admin_user, expect=status)
|
||||
|
||||
if status == 201:
|
||||
job = Job.objects.get(pk=resp.data['id'])
|
||||
assert json.loads(job.extra_vars)['secret_value'].startswith('$encrypted$')
|
||||
assert json.loads(job.decrypted_extra_vars()) == {
|
||||
'secret_value': value
|
||||
}
|
||||
else:
|
||||
assert "for 'secret_value' expected to be a string." in json.dumps(resp.data)
|
||||
|
||||
|
||||
@mock.patch('awx.api.views.feature_enabled', lambda feature: True)
|
||||
@pytest.mark.django_db
|
||||
@pytest.mark.parametrize('default, status', [
|
||||
('SUPERSECRET', 200),
|
||||
(['some', 'invalid', 'list'], 400),
|
||||
({'some-invalid': 'dict'}, 400),
|
||||
(False, 400)
|
||||
])
|
||||
def test_survey_spec_default_passwords_are_encrypted(job_template, post, admin_user, default, status):
|
||||
job_template.survey_enabled = True
|
||||
job_template.save()
|
||||
input_data = {
|
||||
'description': 'A survey',
|
||||
'spec': [{
|
||||
'index': 0,
|
||||
'question_name': 'What is your password?',
|
||||
'required': True,
|
||||
'variable': 'secret_value',
|
||||
'default': default,
|
||||
'type': 'password'
|
||||
}],
|
||||
'name': 'my survey'
|
||||
}
|
||||
resp = post(url=reverse('api:job_template_survey_spec', kwargs={'pk': job_template.id}),
|
||||
data=input_data, user=admin_user, expect=status)
|
||||
|
||||
if status == 200:
|
||||
updated_jt = JobTemplate.objects.get(pk=job_template.pk)
|
||||
assert updated_jt.survey_spec['spec'][0]['default'].startswith('$encrypted$')
|
||||
|
||||
job = updated_jt.create_unified_job()
|
||||
assert json.loads(job.extra_vars)['secret_value'].startswith('$encrypted$')
|
||||
assert json.loads(job.decrypted_extra_vars()) == {
|
||||
'secret_value': default
|
||||
}
|
||||
else:
|
||||
assert "for 'secret_value' expected to be a string." in str(resp.data)
|
||||
|
||||
|
||||
@mock.patch('awx.api.views.feature_enabled', lambda feature: True)
|
||||
@pytest.mark.django_db
|
||||
def test_survey_spec_default_passwords_encrypted_on_update(job_template, post, put, admin_user):
|
||||
input_data = {
|
||||
'description': 'A survey',
|
||||
'spec': [{
|
||||
'index': 0,
|
||||
'question_name': 'What is your password?',
|
||||
'required': True,
|
||||
'variable': 'secret_value',
|
||||
'default': 'SUPERSECRET',
|
||||
'type': 'password'
|
||||
}],
|
||||
'name': 'my survey'
|
||||
}
|
||||
post(url=reverse('api:job_template_survey_spec', kwargs={'pk': job_template.id}),
|
||||
data=input_data, user=admin_user, expect=200)
|
||||
updated_jt = JobTemplate.objects.get(pk=job_template.pk)
|
||||
|
||||
# simulate a survey field edit where we're not changing the default value
|
||||
input_data['spec'][0]['default'] = '$encrypted$'
|
||||
post(url=reverse('api:job_template_survey_spec', kwargs={'pk': job_template.id}),
|
||||
data=input_data, user=admin_user, expect=200)
|
||||
assert updated_jt.survey_spec == JobTemplate.objects.get(pk=job_template.pk).survey_spec
|
||||
|
||||
|
||||
# Tests related to survey content validation
|
||||
@mock.patch('awx.api.views.feature_enabled', lambda feature: True)
|
||||
@pytest.mark.django_db
|
||||
|
||||
@@ -13,6 +13,7 @@ from awx.main.models import (
|
||||
@pytest.fixture
|
||||
def job(mocker):
|
||||
ret = mocker.MagicMock(**{
|
||||
'decrypted_extra_vars.return_value': '{\"secret_key\": \"my_password\"}',
|
||||
'display_extra_vars.return_value': '{\"secret_key\": \"$encrypted$\"}',
|
||||
'extra_vars_dict': {"secret_key": "my_password"},
|
||||
'pk': 1, 'job_template.pk': 1, 'job_template.name': '',
|
||||
|
||||
@@ -31,7 +31,7 @@ from awx.main.models import (
|
||||
)
|
||||
|
||||
from awx.main import tasks
|
||||
from awx.main.utils import encrypt_field
|
||||
from awx.main.utils import encrypt_field, encrypt_value
|
||||
|
||||
|
||||
|
||||
@@ -306,6 +306,20 @@ class TestGenericRun(TestJobExecution):
|
||||
assert '"awx_user_id": 123,' in ' '.join(args)
|
||||
assert '"awx_user_name": "angry-spud"' in ' '.join(args)
|
||||
|
||||
def test_survey_extra_vars(self):
|
||||
self.instance.extra_vars = json.dumps({
|
||||
'super_secret': encrypt_value('CLASSIFIED', pk=None)
|
||||
})
|
||||
self.instance.survey_passwords = {
|
||||
'super_secret': '$encrypted$'
|
||||
}
|
||||
self.task.run(self.pk)
|
||||
|
||||
assert self.run_pexpect.call_count == 1
|
||||
call_args, _ = self.run_pexpect.call_args_list[0]
|
||||
args, cwd, env, stdout = call_args
|
||||
assert '"super_secret": "CLASSIFIED"' in ' '.join(args)
|
||||
|
||||
def test_awx_task_env(self):
|
||||
patch = mock.patch('awx.main.tasks.settings.AWX_TASK_ENV', {'FOO': 'BAR'})
|
||||
patch.start()
|
||||
|
||||
Reference in New Issue
Block a user