コード例 #1
0
def _unified_jobs(apps):
    UnifiedJob = apps.get_model('main', 'UnifiedJob')
    for uj in UnifiedJob.objects.all():
        if uj.start_args is not None:
            if should_decrypt_field(uj.start_args):
                uj.start_args = decrypt_field(uj, 'start_args')
                uj.start_args = encrypt_field(uj, 'start_args')
                uj.save()
コード例 #2
0
ファイル: test_encryption.py プロジェクト: youhong316/awx
def test_encrypt_subfield():
    field = Setting(value={'name': 'ANSIBLE'})
    encrypted = field.value = encryption.encrypt_field(field,
                                                       'value',
                                                       subfield='name')
    assert encryption.decrypt_field(field, 'value',
                                    subfield='name') == 'ANSIBLE'
    assert encrypted.startswith('$encrypted$UTF8$AESCBC$')
コード例 #3
0
def test_encrypt_field_force_disable_unicode():
    value = u"NothingSpecial"
    field = Setting(value=value)
    encrypted = field.value = encryption.encrypt_field(field,
                                                       'value',
                                                       skip_utf8=True)
    assert "UTF8" not in encrypted
    assert encryption.decrypt_field(field, 'value') == value
コード例 #4
0
def _credentials(apps):
    for credential in apps.get_model('main', 'Credential').objects.all():
        for field_name in PASSWORD_FIELDS:
            value = getattr(credential, field_name)
            if should_decrypt_field(value):
                value = decrypt_field(credential, field_name)
                setattr(credential, field_name, value)
                setattr(credential, field_name, encrypt_field(credential, field_name))
        credential.save()
コード例 #5
0
 def _credentials(self):
     for credential in Credential.objects.iterator():
         for field_name in credential.credential_type.secret_fields:
             if field_name in credential.inputs:
                 credential.inputs[field_name] = decrypt_field(
                     credential, field_name, secret_key=self.old_key)
                 credential.inputs[field_name] = encrypt_field(
                     credential, field_name, secret_key=self.new_key)
             credential.save()
コード例 #6
0
def replace_aesecb_fernet(apps, schema_editor):
    from awx.main.utils.encryption import encrypt_field
    Setting = apps.get_model('conf', 'Setting')

    for setting in Setting.objects.filter().order_by('pk'):
        if settings_registry.is_setting_encrypted(setting.key):
            if should_decrypt_field(setting.value):
                setting.value = decrypt_field(setting, 'value')
                setting.value = encrypt_field(setting, 'value')
            setting.save()
コード例 #7
0
 def _unified_jobs(self):
     for uj in UnifiedJob.objects.iterator():
         if uj.start_args:
             uj.start_args = decrypt_field(uj,
                                           'start_args',
                                           secret_key=self.old_key)
             uj.start_args = encrypt_field(uj,
                                           'start_args',
                                           secret_key=self.new_key)
             uj.save()
コード例 #8
0
def _notification_templates(apps):
    NotificationTemplate = apps.get_model('main', 'NotificationTemplate')
    for nt in NotificationTemplate.objects.all():
        CLASS_FOR_NOTIFICATION_TYPE = dict([(x[0], x[2]) for x in NOTIFICATION_TYPES])
        notification_class = CLASS_FOR_NOTIFICATION_TYPE[nt.notification_type]
        for field in filter(lambda x: notification_class.init_parameters[x]['type'] == "password",
                            notification_class.init_parameters):
            if should_decrypt_field(nt.notification_configuration[field]):
                nt.notification_configuration[field] = decrypt_field(nt, 'notification_configuration', subfield=field)
                nt.notification_configuration[field] = encrypt_field(nt, 'notification_configuration', subfield=field)
        nt.save()
コード例 #9
0
 def _settings(self):
     # don't update memcached, the *actual* value isn't changing
     post_save.disconnect(on_post_save_setting, sender=Setting)
     for setting in Setting.objects.filter().order_by('pk'):
         if settings_registry.is_setting_encrypted(setting.key):
             setting.value = decrypt_field(setting,
                                           'value',
                                           secret_key=self.old_key)
             setting.value = encrypt_field(setting,
                                           'value',
                                           secret_key=self.new_key)
             setting.save()
コード例 #10
0
def _migrate_setting(apps, old_key, new_key, encrypted=False):
    Setting = apps.get_model('conf', 'Setting')
    if not Setting.objects.filter(key=old_key).exists():
        return
    new_setting = Setting.objects.create(key=new_key,
                                         created=now(),
                                         modified=now())
    if encrypted:
        new_setting.value = decrypt_field(
            Setting.objects.filter(key=old_key).first(), 'value')
        new_setting.value = encrypt_field(new_setting, 'value')
    else:
        new_setting.value = getattr(
            Setting.objects.filter(key=old_key).first(), 'value')
    new_setting.save()
コード例 #11
0
 def _notification_templates(self):
     for nt in NotificationTemplate.objects.iterator():
         CLASS_FOR_NOTIFICATION_TYPE = dict([
             (x[0], x[2]) for x in NotificationTemplate.NOTIFICATION_TYPES
         ])
         notification_class = CLASS_FOR_NOTIFICATION_TYPE[
             nt.notification_type]
         for field in filter(
                 lambda x: notification_class.init_parameters[x]['type'] ==
                 "password", notification_class.init_parameters):
             nt.notification_configuration[field] = decrypt_field(
                 nt,
                 'notification_configuration',
                 subfield=field,
                 secret_key=self.old_key)
             nt.notification_configuration[field] = encrypt_field(
                 nt,
                 'notification_configuration',
                 subfield=field,
                 secret_key=self.new_key)
         nt.save()
コード例 #12
0
    def test_job_start_args(self, job_factory):
        # test basic decryption
        job = job_factory()
        job.start_args = json.dumps({'foo': 'bar'})
        job.start_args = encrypt_field(job, field_name='start_args')
        job.save()
        assert job.start_args.startswith(PREFIX)

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

        # verify that the old SECRET_KEY doesn't work
        with pytest.raises(InvalidToken):
            decrypt_field(new_job, field_name='start_args')

        # verify that the new SECRET_KEY *does* work
        with override_settings(SECRET_KEY=new_key):
            assert json.loads(
                decrypt_field(new_job, field_name='start_args')
            ) == {'foo': 'bar'}
コード例 #13
0
def migrate_to_v2_credentials(apps, schema_editor):
    CredentialType.setup_tower_managed_defaults()
    deprecated_cred = _generate_deprecated_cred_types()

    # this monkey-patch is necessary to make the implicit role generation save
    # signal use the correct Role model (the version active at this point in
    # migration, not the one at HEAD)
    orig_current_apps = utils.get_current_apps
    try:
        utils.get_current_apps = lambda: apps
        for cred in apps.get_model('main', 'Credential').objects.all():
            job_templates = cred.jobtemplates.all()
            jobs = cred.jobs.all()
            data = {}
            if getattr(cred, 'vault_password', None):
                data['vault_password'] = cred.vault_password
            if _is_insights_scm(apps, cred):
                _disassociate_non_insights_projects(apps, cred)
                credential_type = _get_insights_credential_type()
            else:
                credential_type = _populate_deprecated_cred_types(
                    deprecated_cred, cred.kind) or CredentialType.from_v1_kind(
                        cred.kind, data)

            defined_fields = credential_type.defined_fields
            cred.credential_type = apps.get_model(
                'main', 'CredentialType').objects.get(pk=credential_type.pk)

            for field in defined_fields:
                if getattr(cred, field, None):
                    cred.inputs[field] = getattr(cred, field)
            if cred.vault_password:
                for jt in job_templates:
                    jt.credential = None
                    jt.vault_credential = cred
                    jt.save()
                for job in jobs:
                    job.credential = None
                    job.vault_credential = cred
                    job.save()
            if data.get('is_insights', False):
                cred.kind = 'insights'
            cred.save()

            #
            # If the credential contains a vault password, create a new
            # *additional* credential for the ssh details
            #
            if cred.vault_password:
                # We need to make an ssh credential, too
                ssh_type = CredentialType.from_v1_kind('ssh')
                new_cred = apps.get_model('main',
                                          'Credential').objects.get(pk=cred.pk)
                new_cred.pk = None
                new_cred.vault_password = ''
                new_cred.credential_type = apps.get_model(
                    'main', 'CredentialType').objects.get(pk=ssh_type.pk)
                if 'vault_password' in new_cred.inputs:
                    del new_cred.inputs['vault_password']

                # unset these attributes so that new roles are properly created
                # at save time
                new_cred.read_role = None
                new_cred.admin_role = None
                new_cred.use_role = None

                if any([
                        getattr(cred, field)
                        for field in ssh_type.defined_fields
                ]):
                    new_cred.save(force_insert=True)

                    # copy rbac roles
                    for role_type in ('read_role', 'admin_role', 'use_role'):
                        for member in getattr(cred, role_type).members.all():
                            getattr(new_cred, role_type).members.add(member)
                        for role in getattr(cred, role_type).parents.all():
                            getattr(new_cred, role_type).parents.add(role)

                    for jt in job_templates:
                        jt.credential = new_cred
                        jt.save()
                    for job in jobs:
                        job.credential = new_cred
                        job.save()

                    # passwords must be decrypted and re-encrypted, because
                    # their encryption is based on the Credential's primary key
                    # (which has changed)
                    for field in ssh_type.defined_fields:
                        if field in ssh_type.secret_fields:
                            value = decrypt_field(cred, field)
                            if value:
                                setattr(new_cred, field, value)
                                new_cred.inputs[field] = encrypt_field(
                                    new_cred, field)
                                setattr(new_cred, field, '')
                        elif getattr(cred, field):
                            new_cred.inputs[field] = getattr(cred, field)
                    new_cred.save()
    finally:
        utils.get_current_apps = orig_current_apps
コード例 #14
0
ファイル: test_encryption.py プロジェクト: youhong316/awx
def test_encrypt_field_with_ask():
    encrypted = encryption.encrypt_field(Setting(value='ASK'),
                                         'value',
                                         ask=True)
    assert encrypted == 'ASK'
コード例 #15
0
ファイル: test_encryption.py プロジェクト: youhong316/awx
def test_encrypt_field_with_unicode_string():
    value = u'Iñtërnâtiônàlizætiøn'
    field = Setting(value=value)
    encrypted = field.value = encryption.encrypt_field(field, 'value')
    assert encryption.decrypt_field(field, 'value') == value
    assert encrypted.startswith('$encrypted$UTF8$AESCBC$')
コード例 #16
0
def test_encrypt_field_with_undefined_attr_raises_expected_exception():
    with pytest.raises(AttributeError):
        encryption.encrypt_field({}, 'undefined_attr')
コード例 #17
0
ファイル: test_encryption.py プロジェクト: youhong316/awx
def test_encrypt_field_with_empty_value():
    encrypted = encryption.encrypt_field(Setting(value=None), 'value')
    assert encrypted is None
コード例 #18
0
ファイル: test_encryption.py プロジェクト: youhong316/awx
def test_encrypt_field():
    field = Setting(pk=123, value='ANSIBLE')
    encrypted = field.value = encryption.encrypt_field(field, 'value')
    assert encryption.decrypt_field(field, 'value') == 'ANSIBLE'
    assert encrypted.startswith('$encrypted$UTF8$AESCBC$')
コード例 #19
0
ファイル: _galaxy.py プロジェクト: yckwon75/awx
def migrate_galaxy_settings(apps, schema_editor):
    Organization = apps.get_model('main', 'Organization')
    if Organization.objects.count() == 0:
        # nothing to migrate
        return
    set_current_apps(apps)
    ModernCredentialType.setup_tower_managed_defaults(apps)
    CredentialType = apps.get_model('main', 'CredentialType')
    Credential = apps.get_model('main', 'Credential')
    Setting = apps.get_model('conf', 'Setting')

    galaxy_type = CredentialType.objects.get(kind='galaxy')
    private_galaxy_url = Setting.objects.filter(
        key='PRIMARY_GALAXY_URL').first()

    # by default, prior versions of AWX automatically pulled content
    # from galaxy.ansible.com
    public_galaxy_enabled = True
    public_galaxy_setting = Setting.objects.filter(
        key='PUBLIC_GALAXY_ENABLED').first()
    if public_galaxy_setting and public_galaxy_setting.value is False:
        # ...UNLESS this behavior was explicitly disabled via this setting
        public_galaxy_enabled = False
    try:
        # Needed for old migrations
        public_galaxy_credential = Credential(
            created=now(),
            modified=now(),
            name='Ansible Galaxy',
            managed_by_tower=True,
            credential_type=galaxy_type,
            inputs={'url': 'https://galaxy.ansible.com/'},
        )
    except:
        # Needed for new migrations, tests
        public_galaxy_credential = Credential(
            created=now(),
            modified=now(),
            name='Ansible Galaxy',
            managed=True,
            credential_type=galaxy_type,
            inputs={'url': 'https://galaxy.ansible.com/'})
    public_galaxy_credential.save()

    for org in Organization.objects.all():
        if private_galaxy_url and private_galaxy_url.value:
            # If a setting exists for a private Galaxy URL, make a credential for it
            username = Setting.objects.filter(
                key='PRIMARY_GALAXY_USERNAME').first()
            password = Setting.objects.filter(
                key='PRIMARY_GALAXY_PASSWORD').first()
            if (username and username.value) or (password and password.value):
                logger.error(
                    f'Specifying HTTP basic auth for the Ansible Galaxy API '
                    f'({private_galaxy_url.value}) is no longer supported. '
                    'Please provide an API token instead after your upgrade '
                    'has completed', )
            inputs = {'url': private_galaxy_url.value}
            token = Setting.objects.filter(key='PRIMARY_GALAXY_TOKEN').first()
            if token and token.value:
                inputs['token'] = decrypt_field(token, 'value')
            auth_url = Setting.objects.filter(
                key='PRIMARY_GALAXY_AUTH_URL').first()
            if auth_url and auth_url.value:
                inputs['auth_url'] = auth_url.value
            name = f'Private Galaxy ({private_galaxy_url.value})'
            if 'cloud.redhat.com' in inputs['url']:
                name = f'Ansible Automation Hub ({private_galaxy_url.value})'
            cred = Credential(created=now(),
                              modified=now(),
                              name=name,
                              organization=org,
                              credential_type=galaxy_type,
                              inputs=inputs)
            cred.save()
            if token and token.value:
                # encrypt based on the primary key from the prior save
                cred.inputs['token'] = encrypt_field(cred, 'token')
                cred.save()
            org.galaxy_credentials.add(cred)

        fallback_servers = getattr(settings, 'FALLBACK_GALAXY_SERVERS', [])
        for fallback in fallback_servers:
            url = fallback.get('url', None)
            auth_url = fallback.get('auth_url', None)
            username = fallback.get('username', None)
            password = fallback.get('password', None)
            token = fallback.get('token', None)
            if username or password:
                logger.error(
                    f'Specifying HTTP basic auth for the Ansible Galaxy API '
                    f'({url}) is no longer supported. '
                    'Please provide an API token instead after your upgrade '
                    'has completed', )
            inputs = {'url': url}
            if token:
                inputs['token'] = token
            if auth_url:
                inputs['auth_url'] = auth_url
            cred = Credential(created=now(),
                              modified=now(),
                              name=f'Ansible Galaxy ({url})',
                              organization=org,
                              credential_type=galaxy_type,
                              inputs=inputs)
            cred.save()
            if token:
                # encrypt based on the primary key from the prior save
                cred.inputs['token'] = encrypt_field(cred, 'token')
                cred.save()
            org.galaxy_credentials.add(cred)

        if public_galaxy_enabled:
            # If public Galaxy was enabled, associate it to the org
            org.galaxy_credentials.add(public_galaxy_credential)
コード例 #20
0
def test_encrypt_field_without_pk():
    field = Setting(value='ANSIBLE')
    encrypted = field.value = encryption.encrypt_field(field, 'value')
    assert encryption.decrypt_field(field, 'value') == 'ANSIBLE'
    assert encrypted.startswith('$encrypted$AESCBC$')