mirror of
https://github.com/ansible/awx.git
synced 2026-01-15 03:40:42 -03:30
automatically encrypt/decrypt main_oauth2application.client_secret
see: https://github.com/ansible/awx/issues/1416
This commit is contained in:
parent
c2446beb6e
commit
5f01d26224
@ -42,6 +42,7 @@ from rest_framework import serializers
|
||||
|
||||
# AWX
|
||||
from awx.main.utils.filters import SmartFilter
|
||||
from awx.main.utils.encryption import encrypt_value, decrypt_value, get_encryption_key
|
||||
from awx.main.validators import validate_ssh_private_key
|
||||
from awx.main.models.rbac import batch_role_ancestor_rebuilding, Role
|
||||
from awx.main import utils
|
||||
@ -821,3 +822,16 @@ class AskForField(models.BooleanField):
|
||||
# self.name will be set by the model metaclass, not this field
|
||||
raise Exception('Corresponding allows_field cannot be accessed until model is initialized.')
|
||||
return self._allows_field
|
||||
|
||||
|
||||
class OAuth2ClientSecretField(models.CharField):
|
||||
|
||||
def get_db_prep_value(self, value, connection, prepared=False):
|
||||
return super(OAuth2ClientSecretField, self).get_db_prep_value(
|
||||
encrypt_value(value), connection, prepared
|
||||
)
|
||||
|
||||
def from_db_value(self, value, expression, connection, context):
|
||||
if value.startswith('$encrypted$'):
|
||||
return decrypt_value(get_encryption_key('value', pk=None), value)
|
||||
return value
|
||||
|
||||
22
awx/main/migrations/0029_v330_encrypt_oauth2_secret.py
Normal file
22
awx/main/migrations/0029_v330_encrypt_oauth2_secret.py
Normal file
@ -0,0 +1,22 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.11 on 2018-04-03 20:48
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import awx.main.fields
|
||||
from django.db import migrations
|
||||
import oauth2_provider.generators
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('main', '0028_v330_modify_application'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='oauth2application',
|
||||
name='client_secret',
|
||||
field=awx.main.fields.OAuth2ClientSecretField(blank=True, db_index=True, default=oauth2_provider.generators.generate_client_secret, max_length=1024),
|
||||
),
|
||||
]
|
||||
@ -9,6 +9,9 @@ from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
# Django OAuth Toolkit
|
||||
from oauth2_provider.models import AbstractApplication, AbstractAccessToken
|
||||
from oauth2_provider.generators import generate_client_secret
|
||||
|
||||
from awx.main.fields import OAuth2ClientSecretField
|
||||
|
||||
|
||||
DATA_URI_RE = re.compile(r'.*') # FIXME
|
||||
@ -39,6 +42,10 @@ class OAuth2Application(AbstractApplication):
|
||||
null=True,
|
||||
)
|
||||
|
||||
client_secret = OAuth2ClientSecretField(
|
||||
max_length=1024, blank=True, default=generate_client_secret, db_index=True
|
||||
)
|
||||
|
||||
|
||||
class OAuth2AccessToken(AbstractAccessToken):
|
||||
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
import pytest
|
||||
import base64
|
||||
|
||||
from django.db import connection
|
||||
|
||||
from awx.main.utils.encryption import decrypt_value, get_encryption_key
|
||||
from awx.api.versioning import reverse, drf_reverse
|
||||
from awx.main.models.oauth import (OAuth2Application as Application,
|
||||
OAuth2AccessToken as AccessToken,
|
||||
@ -65,6 +68,26 @@ def test_oauth_application_update(oauth_application, organization, patch, admin,
|
||||
assert updated_app.organization == organization
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_oauth_application_encryption(admin, organization, post):
|
||||
response = post(
|
||||
reverse('api:o_auth2_application_list'), {
|
||||
'name': 'test app',
|
||||
'organization': organization.pk,
|
||||
'client_type': 'confidential',
|
||||
'authorization_grant_type': 'password',
|
||||
}, admin, expect=201
|
||||
)
|
||||
pk = response.data.get('id')
|
||||
secret = response.data.get('client_secret')
|
||||
with connection.cursor() as cursor:
|
||||
encrypted = cursor.execute(
|
||||
'SELECT client_secret FROM main_oauth2application WHERE id={}'.format(pk)
|
||||
).fetchone()[0]
|
||||
assert encrypted.startswith('$encrypted$')
|
||||
assert decrypt_value(get_encryption_key('value', pk=None), encrypted) == secret
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_oauth_token_create(oauth_application, get, post, admin):
|
||||
response = post(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user