def test_survey_spec(self, inventory, project, survey_spec_factory, cls):
        params = {}
        if cls == 'JobTemplate':
            params['inventory'] = inventory
            params['project'] = project
        # test basic decryption
        jt = getattr(models, cls).objects.create(
            name='Example Template',
            survey_spec=survey_spec_factory([{
                'variable': 'secret_key',
                'default': encrypt_value('donttell', pk=None),
                'type': 'password'
            }]),
            survey_enabled=True,
            **params
        )
        job = jt.create_unified_job()
        assert jt.survey_spec['spec'][0]['default'].startswith(PREFIX)
        assert job.survey_passwords == {'secret_key': '$encrypted$'}
        assert json.loads(job.decrypted_extra_vars())['secret_key'] == 'donttell'

        # re-key the extra_vars
        new_key = regenerate_secret_key.Command().handle()
        new_job = models.UnifiedJob.objects.get(pk=job.pk)
        assert new_job.extra_vars != job.extra_vars

        # verify that the old SECRET_KEY doesn't work
        with pytest.raises(InvalidToken):
            new_job.decrypted_extra_vars()

        # verify that the new SECRET_KEY *does* work
        with override_settings(SECRET_KEY=new_key):
            assert json.loads(
                new_job.decrypted_extra_vars()
            )['secret_key'] == 'donttell'
Ejemplo n.º 2
0
 def _oauth2_app_secrets(self):
     for app in OAuth2Application.objects.iterator():
         raw = app.client_secret
         app.client_secret = raw
         encrypted = encrypt_value(raw, secret_key=self.new_key)
         OAuth2Application.objects.filter(pk=app.pk).update(
             client_secret=encrypted)
Ejemplo n.º 3
0
def _encrypt_survey_passwords(Job, JobTemplate, WorkflowJob,
                              WorkflowJobTemplate):
    from awx.main.utils.encryption import encrypt_value
    for _type in (JobTemplate, WorkflowJobTemplate):
        for jt in _type.objects.exclude(survey_spec={}):
            changed = False
            if jt.survey_spec.get('spec', []):
                for field in jt.survey_spec['spec']:
                    if field.get('type') == 'password' and field.get(
                            'default', ''):
                        default = field['default']
                        if default.startswith('$encrypted$'):
                            if default == '$encrypted$':
                                # If you have a survey_spec with a literal
                                # '$encrypted$' as the default, you have
                                # encountered a known bug in awx/Tower
                                # https://github.com/ansible/ansible-tower/issues/7800
                                logger.error(
                                    '{}.pk={} survey_spec has ambiguous $encrypted$ default for {}, needs attention...'
                                    .format(jt, jt.pk, field['variable']))
                                field['default'] = ''
                                changed = True
                            continue
                        field['default'] = encrypt_value(field['default'],
                                                         pk=None)
                        changed = True
            if changed:
                jt.save()

    for _type in (Job, WorkflowJob):
        for job in _type.objects.defer('result_stdout_text').exclude(
                survey_passwords={}).iterator():
            changed = False
            for key in job.survey_passwords:
                if key in job.extra_vars:
                    extra_vars = json.loads(job.extra_vars)
                    if not extra_vars.get(
                            key,
                            '') or extra_vars[key].startswith('$encrypted$'):
                        continue
                    extra_vars[key] = encrypt_value(extra_vars[key], pk=None)
                    job.extra_vars = json.dumps(extra_vars)
                    changed = True
            if changed:
                job.save()
Ejemplo n.º 4
0
    def _survey_passwords(self):
        for _type in (JobTemplate, WorkflowJobTemplate):
            for jt in _type.objects.exclude(survey_spec={}):
                changed = False
                if jt.survey_spec.get('spec', []):
                    for field in jt.survey_spec['spec']:
                        if field.get('type') == 'password' and field.get(
                                'default', ''):
                            raw = decrypt_value(
                                get_encryption_key('value',
                                                   None,
                                                   secret_key=self.old_key),
                                field['default'])
                            field['default'] = encrypt_value(
                                raw, pk=None, secret_key=self.new_key)
                            changed = True
                if changed:
                    jt.save(update_fields=["survey_spec"])

        for _type in (Job, WorkflowJob):
            for job in _type.objects.exclude(survey_passwords={}).iterator():
                changed = False
                for key in job.survey_passwords:
                    if key in job.extra_vars:
                        extra_vars = json.loads(job.extra_vars)
                        if not extra_vars.get(key):
                            continue
                        raw = decrypt_value(
                            get_encryption_key('value',
                                               None,
                                               secret_key=self.old_key),
                            extra_vars[key])
                        extra_vars[key] = encrypt_value(
                            raw, pk=None, secret_key=self.new_key)
                        job.extra_vars = json.dumps(extra_vars)
                        changed = True
                if changed:
                    job.save(update_fields=["extra_vars"])
Ejemplo n.º 5
0
import tempfile
import json
import yaml

import pytest
from awx.main.utils.encryption import encrypt_value
from awx.main.tasks import RunJob
from awx.main.models import (
    Job,
    JobTemplate,
    JobLaunchConfig,
    WorkflowJobTemplate
)
from awx.main.utils.safe_yaml import SafeLoader

ENCRYPTED_SECRET = encrypt_value('secret')


@pytest.mark.survey
class SurveyVariableValidation:

    def test_survey_answers_as_string(self, job_template_factory):
        objects = job_template_factory(
            'job-template-with-survey',
            survey=[{'variable': 'var1', 'type': 'text'}],
            persisted=False)
        jt = objects.job_template
        user_extra_vars = json.dumps({'var1': 'asdf'})
        accepted, ignored, errors = jt._accept_or_ignore_job_kwargs(extra_vars=user_extra_vars)
        assert ignored.get('extra_vars', {}) == {}, [str(element) for element in errors]
        assert 'var1' in accepted['extra_vars']
Ejemplo n.º 6
0
 def get_db_prep_value(self, value, connection, prepared=False):
     return super(OAuth2ClientSecretField,
                  self).get_db_prep_value(encrypt_value(value), connection,
                                          prepared)
Ejemplo n.º 7
0
 def test_encrypt_empty_string_twice(self):
     # Encryption is idempotent
     val = encryption.encrypt_value('foobar')
     val2 = encryption.encrypt_value(val)
     assert encryption.decrypt_value(self._key, val2) == 'foobar'
Ejemplo n.º 8
0
 def test_encrypt_encryption_key(self):
     assert encryption.encrypt_value('$encrypted$') == '$encrypted$'
Ejemplo n.º 9
0
 def test_encrypt_empty_string(self):
     assert encryption.encrypt_value('') == ''