Skip to content

Commit

Permalink
Switch token attribute to be encryped and hidden
Browse files Browse the repository at this point in the history
fixes pulp#1221
  • Loading branch information
mdellweg committed Sep 5, 2022
1 parent 92348d1 commit a247bf9
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGES/1221.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Switched the attribute `token` on `CollectionRemotes` to be encrypted in the database and not to
be exposed in the API.
67 changes: 67 additions & 0 deletions pulp_ansible/app/migrations/0044_alter_collectionremote_token.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Generated by Django 3.2.15 on 2022-08-29 11:04

from django.db import migrations
import pulpcore.app.models.fields


def encrypt_remote_fields(apps, schema_editor):
CollectionRemote = apps.get_model("ansible", "CollectionRemote")

remotes_needing_update = []
for remote in CollectionRemote.objects.order_by("pulp_id").iterator():
remote._encrypted_token = remote.token
remotes_needing_update.append(remote)

if len(remotes_needing_update) > 100:
CollectionRemote.objects.bulk_update(remotes_needing_update, ("_encrypted_token",))
remotes_needing_update.clear()

CollectionRemote.objects.bulk_update(remotes_needing_update, ("_encrypted_token",))


def unencrypt_remote_fields(apps, schema_editor):
CollectionRemote = apps.get_model("ansible", "CollectionRemote")

remotes_needing_update = []
for remote in CollectionRemote.objects.order_by("pulp_id").iterator():
remote.token = remote._encrypted_token
remotes_needing_update.append(remote)

if len(remotes_needing_update) > 100:
CollectionRemote.objects.bulk_update(remotes_needing_update, ("token",))
remotes_needing_update.clear()

CollectionRemote.objects.bulk_update(remotes_needing_update, ("token",))


class Migration(migrations.Migration):

dependencies = [
('ansible', '0043_alter_collectionversionsignature_data'),
]

operations = [
# Add new fields to temporarily hold the encrypted values
migrations.AddField(
model_name="collectionremote",
name="_encrypted_token",
field=pulpcore.app.models.fields.EncryptedTextField(null=True),
),
# Populate the new fields with encrypted values computed from the unencrypted fields
migrations.RunPython(
code=encrypt_remote_fields,
reverse_code=unencrypt_remote_fields,
elidable=True,
),
# Remove the unencrypted columns
migrations.RemoveField(
model_name="collectionremote",
name="token",
),
# Replace the formerly-unencrypted columns with the new encrypted ones
migrations.RenameField(
model_name="collectionremote",
old_name="_encrypted_token",
new_name="token",
),
]
3 changes: 2 additions & 1 deletion pulp_ansible/app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
Distribution,
SigningService,
Task,
EncryptedTextField,
)
from .downloaders import AnsibleDownloaderFactory

Expand Down Expand Up @@ -231,7 +232,7 @@ class CollectionRemote(Remote):

requirements_file = models.TextField(null=True)
auth_url = models.CharField(null=True, max_length=255)
token = models.TextField(null=True, max_length=2000)
token = EncryptedTextField(null=True)
sync_dependencies = models.BooleanField(default=True)
signed_only = models.BooleanField(default=False)

Expand Down
1 change: 1 addition & 0 deletions pulp_ansible/app/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ class CollectionRemoteSerializer(RemoteSerializer):
allow_null=True,
required=False,
max_length=2000,
write_only=True,
)

sync_dependencies = serializers.BooleanField(
Expand Down
3 changes: 2 additions & 1 deletion pulp_ansible/tests/functional/api/collection/test_remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,14 @@ def test_update_auth_url(self):
auth_url="https://example.com",
)
remote = self.remote_collection_api.create(body)
assert not hasattr(remote, "token")
self.addCleanup(self.remote_collection_api.delete, remote.pulp_href)
response = self.remote_collection_api.partial_update(remote.pulp_href, {"auth_url": None})
monitor_task(response.task)
response = self.remote_collection_api.partial_update(
remote.pulp_href, {"auth_url": "https://example.com"}
)
monitor_task(response.task)
self.addCleanup(self.remote_collection_api.delete, remote.pulp_href)

def test_auth_url_requires_token(self):
"""Assert that a `CollectionRemote` with `auth_url` and no `token` can't be created."""
Expand Down

0 comments on commit a247bf9

Please sign in to comment.