Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make sensitive Remote fields write_only #1165

Merged
merged 1 commit into from Mar 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES/8202.removal
@@ -0,0 +1,2 @@
Removed sensitive fields ``username``, ``password``, and ``client_key`` from Remote responses. These
fields can still be set and updated but will no longer be readable.
3 changes: 3 additions & 0 deletions pulpcore/app/serializers/repository.py
Expand Up @@ -86,6 +86,7 @@ class RemoteSerializer(ModelSerializer):
help_text="A PEM encoded private key used for authentication.",
required=False,
allow_null=True,
write_only=True,
)
tls_validation = serializers.BooleanField(
help_text="If True, TLS peer validation must be performed.", required=False
Expand All @@ -99,11 +100,13 @@ class RemoteSerializer(ModelSerializer):
help_text="The username to be used for authentication when syncing.",
required=False,
allow_null=True,
write_only=True,
)
password = serializers.CharField(
help_text="The password to be used for authentication when syncing.",
required=False,
allow_null=True,
write_only=True,
)
pulp_last_updated = serializers.DateTimeField(
help_text="Timestamp of the most recent update of the remote.", read_only=True
Expand Down
49 changes: 48 additions & 1 deletion pulpcore/tests/functional/api/using_plugin/test_crud_repos.py
@@ -1,10 +1,11 @@
"""Tests that CRUD repositories."""
import re
import time
import unittest
from itertools import permutations
from urllib.parse import urljoin

from pulp_smash import api, config, utils
from pulp_smash import api, cli, config, utils
from pulp_smash.pulp3.bindings import monitor_task
from pulp_smash.pulp3.utils import gen_repo

Expand All @@ -22,6 +23,7 @@
from pulpcore.client.pulp_file.exceptions import ApiException
from pulpcore.client.pulp_file import (
ApiClient as FileApiClient,
FileFileRemote,
RemotesFileApi,
)

Expand Down Expand Up @@ -237,6 +239,13 @@ def setUp(self):
self.remote = self.remotes_api.create(self.remote_attrs)

def _compare_results(self, data, received):
self.assertFalse(hasattr(received, "password"))

# handle write only fields
data.pop("username", None)
data.pop("password", None)
data.pop("client_key", None)

for k in data:
self.assertEqual(getattr(received, k), data[k])

Expand All @@ -251,6 +260,44 @@ def test_update(self):
new_remote = self.remotes_api.read(self.remote.pulp_href)
self._compare_results(data, new_remote)

def test_password_writeable(self):
"""Test that a password can be updated with a PUT request."""
cli_client = cli.Client(self.cfg)
remote = self.remotes_api.create({"name": "test_pass", "url": "http://", "password": "new"})
href = remote.pulp_href
uuid = re.search(r"/pulp/api/v3/remotes/file/file/([\w-]+)/", href).group(1)
shell_cmd = (
f"import pulpcore; print(pulpcore.app.models.Remote.objects.get(pk='{uuid}').password)"
)

self.addCleanup(self.remotes_api.delete, href)

# test a PUT request with a new password
remote_update = FileFileRemote(name="test_pass", url="http://", password="changed")
response = self.remotes_api.update(href, remote_update)
monitor_task(response.task)
exc = cli_client.run(["pulpcore-manager", "shell", "-c", shell_cmd])
self.assertEqual(exc.stdout.rstrip("\n"), "changed")

def test_password_not_unset(self):
"""Test that password doesn't get unset when not passed with a PUT request."""
cli_client = cli.Client(self.cfg)
remote = self.remotes_api.create({"name": "test_pass", "url": "http://", "password": "new"})
href = remote.pulp_href
uuid = re.search(r"/pulp/api/v3/remotes/file/file/([\w-]+)/", href).group(1)
shell_cmd = (
f"import pulpcore; print(pulpcore.app.models.Remote.objects.get(pk='{uuid}').password)"
)

self.addCleanup(self.remotes_api.delete, href)

# test a PUT request without a password
remote_update = FileFileRemote(name="pass_test", url="http://")
response = self.remotes_api.update(href, remote_update)
monitor_task(response.task)
exc = cli_client.run(["pulpcore-manager", "shell", "-c", shell_cmd])
self.assertEqual(exc.stdout.rstrip("\n"), "new")

def test_timeout_attributes(self):
# Test valid timeout settings (float >= 0)
data = {
Expand Down