Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Pull basic auth info out of feed url
Previous versions of Pulp allowed users to include their basic auth
information in the url. This is obviously less ideal than passing
this in the config, but in order to remain backwards compatibile, this
removes the auth info from the url and adds it to the importer config.
For importer configurations that were created before this change, we pass
the configuration through the same cleaner function as we do during
importer creation, so a temporary importer configuration includes the
basic auth information.

closes #1977
  • Loading branch information
asmacdo committed Aug 15, 2016
1 parent 9262cdb commit 206cf5f
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 3 deletions.
17 changes: 15 additions & 2 deletions server/pulp/server/controllers/importer.py
@@ -1,10 +1,12 @@
import logging
import sys
import urlparse

import celery
from mongoengine import ValidationError

from pulp.common import error_codes, tags
from pulp.common.plugins import importer_constants
from pulp.plugins.config import PluginCallConfiguration
from pulp.plugins.loader import api as plugin_api
from pulp.server import exceptions
Expand Down Expand Up @@ -35,16 +37,27 @@ def build_resource_tag(repo_id, importer_type_id):

def clean_config_dict(config):
"""
Remove keys from a dict that have a value None.
Ensure that the config is ready to be passed to the plugin. There are two things that must
occur:
1. Remove keys from the dict that have a value None.
2. If they exist, move basic auth credentials from the feed_url to the config.
:param config: configuration for plugin
:type config: dict
:return: config without the keys whose values were None
:rtype: dict:
"""

if config is not None:
feed_url = config.get('feed')
if feed_url:
parsed = urlparse.urlparse(feed_url)
if parsed.username or parsed.password:
new_url = parsed._replace(netloc=parsed.netloc.rsplit('@', 1)[1])
config[importer_constants.KEY_BASIC_AUTH_USER] = parsed.username
config[importer_constants.KEY_BASIC_AUTH_PASS] = parsed.password
config['feed'] = new_url.geturl()

return dict([(k, v) for k, v in config.items() if v is not None])
else:
return None
Expand Down
4 changes: 3 additions & 1 deletion server/pulp/server/controllers/repository.py
@@ -1,5 +1,6 @@
from gettext import gettext as _
from itertools import chain
import copy
import logging
import os
import sys
Expand Down Expand Up @@ -738,7 +739,8 @@ def sync(repo_id, sync_config_override=None, scheduled_call_id=None):
except plugin_exceptions.PluginNotFound:
raise pulp_exceptions.MissingResource(repository=repo_id)

call_config = PluginCallConfiguration(imp_config, repo_importer.config, sync_config_override)
importer_config = importer_controller.clean_config_dict(copy.deepcopy(repo_importer.config))
call_config = PluginCallConfiguration(imp_config, importer_config, sync_config_override)
transfer_repo.working_dir = common_utils.get_working_directory()
conduit = RepoSyncConduit(repo_id, repo_importer.importer_type_id, repo_importer.id)
sync_result_collection = RepoSyncResult.get_collection()
Expand Down
39 changes: 39 additions & 0 deletions server/test/unit/server/controllers/test_importer.py
Expand Up @@ -168,6 +168,45 @@ def test_as_expected_none(self):
result = importer.clean_config_dict(mock_config)
self.assertTrue(result is None)

def test_feed_with_basic_auth_username_password(self):
"""
Ensure that username and password are removed from the feed and put into the config.
"""
mock_config = {'feed': 'http://mock_user:mock_pass@realfeed.com'}
expected_clean_config = {'feed': 'http://realfeed.com', 'basic_auth_username': 'mock_user',
'basic_auth_password': 'mock_pass'}
result = importer.clean_config_dict(mock_config)
self.assertDictEqual(expected_clean_config, result)

def test_feed_with_basic_auth_username(self):
"""
Ensure that the username is moved to config even if password is not present.
"""
mock_config = {'feed': 'http://mock_user@realfeed.com'}
expected_clean_config = {'feed': 'http://realfeed.com', 'basic_auth_username': 'mock_user'}
result = importer.clean_config_dict(mock_config)
self.assertDictEqual(expected_clean_config, result)

def test_feed_with_basic_auth_password(self):
"""
If password but not username is in the feed, move the password config set username empty ''.
"""
mock_config = {'feed': 'http://:mock_pass@realfeed.com'}
expected_clean_config = {'feed': 'http://realfeed.com', 'basic_auth_username': '',
'basic_auth_password': 'mock_pass'}
result = importer.clean_config_dict(mock_config)
self.assertDictEqual(expected_clean_config, result)

def test_feed_with_basic_auth_username_password_at_symbol(self):
"""
Ensure that usernames and passwords can contain the '@' symbol.
"""
mock_config = {'feed': 'http://mock@user:mock@pass@realfeed.com'}
expected_clean_config = {'feed': 'http://realfeed.com', 'basic_auth_username': 'mock@user',
'basic_auth_password': 'mock@pass'}
result = importer.clean_config_dict(mock_config)
self.assertDictEqual(expected_clean_config, result)


@mock.patch('pulp.server.controllers.importer.set_importer')
@mock.patch('pulp.server.controllers.importer.tags')
Expand Down

0 comments on commit 206cf5f

Please sign in to comment.