From b1a858a14ddf7d49ab46209d420c0e281125ce6a Mon Sep 17 00:00:00 2001 From: Aanand Prasad Date: Thu, 26 Feb 2015 13:56:11 +0000 Subject: [PATCH] Update resolve_authconfig to bring it in line with Docker client Instead of expanding the registry name we're looking for to a full URL, strip entries in the authconfig down to just the hostname. Signed-off-by: Aanand Prasad --- docker/auth/auth.py | 46 +++++++++++++++++++-------------------------- docker/client.py | 3 +-- tests/utils_test.py | 12 +++++++++++- 3 files changed, 31 insertions(+), 30 deletions(-) diff --git a/docker/auth/auth.py b/docker/auth/auth.py index 86939103ff..90c3a6ffe1 100644 --- a/docker/auth/auth.py +++ b/docker/auth/auth.py @@ -26,14 +26,6 @@ DOCKER_CONFIG_FILENAME = '.dockercfg' -def swap_protocol(url): - if url.startswith('http://'): - return url.replace('http://', 'https://', 1) - if url.startswith('https://'): - return url.replace('https://', 'http://', 1) - return url - - def expand_registry_url(hostname, insecure=False): if hostname.startswith('http:') or hostname.startswith('https:'): return hostname @@ -68,29 +60,29 @@ def resolve_repository_name(repo_name, insecure=False): def resolve_authconfig(authconfig, registry=None): - """Return the authentication data from the given auth configuration for a - specific registry. We'll do our best to infer the correct URL for the - registry, trying both http and https schemes. Returns an empty dictionnary - if no data exists.""" + """ + Returns the authentication data from the given auth configuration for a + specific registry. As with the Docker client, legacy entries in the config + with full URLs are stripped down to hostnames before checking for a match. + Returns None if no match was found. + """ # Default to the public index server - registry = registry or INDEX_URL - - # If it's not the index server there are three cases: - # - # 1. this is a full config url -> it should be used as is - # 2. it could be a full url, but with the wrong protocol - # 3. it can be the hostname optionally with a port - # - # as there is only one auth entry which is fully qualified we need to start - # parsing and matching - if '/v1/' not in registry: - registry = os.path.join(registry, 'v1/') - if not registry.startswith('http:') and not registry.startswith('https:'): - registry = 'https://' + registry + registry = convert_to_hostname(registry) if registry else INDEX_URL if registry in authconfig: return authconfig[registry] - return authconfig.get(swap_protocol(registry), None) + + for key, config in six.iteritems(authconfig): + if convert_to_hostname(key) == registry: + return config + + return None + + +def convert_to_hostname(url): + url = url.replace('http://', '') + url = url.replace('https://', '') + return url.split('/', 1)[0] def encode_auth(auth_info): diff --git a/docker/client.py b/docker/client.py index 26adf28696..88d435fb92 100644 --- a/docker/client.py +++ b/docker/client.py @@ -627,8 +627,7 @@ def login(self, username, password=None, email=None, registry=None, elif not self._auth_configs: self._auth_configs = auth.load_config() - registry = auth.expand_registry_url(registry, insecure_registry) \ - if registry else auth.INDEX_URL + registry = registry or auth.INDEX_URL authcfg = auth.resolve_authconfig(self._auth_configs, registry) # If we found an existing auth config for this registry and username diff --git a/tests/utils_test.py b/tests/utils_test.py index 9b6461f426..75de915a40 100644 --- a/tests/utils_test.py +++ b/tests/utils_test.py @@ -104,7 +104,8 @@ def test_create_host_config(self): def test_resolve_authconfig(self): auth_config = { 'https://index.docker.io/v1/': {'auth': 'indexuser'}, - 'http://my.registry.net/v1/': {'auth': 'privateuser'} + 'my.registry.net': {'auth': 'privateuser'}, + 'http://legacy.registry.url/v1/': {'auth': 'legacyauth'} } # hostname only self.assertEqual( @@ -154,6 +155,15 @@ def test_resolve_authconfig(self): resolve_authconfig(auth_config, 'http://my.registry.net/v1/'), {'auth': 'privateuser'} ) + # legacy entry in config + self.assertEqual( + resolve_authconfig(auth_config, 'legacy.registry.url'), + {'auth': 'legacyauth'} + ) + # no matching entry + self.assertTrue( + resolve_authconfig(auth_config, 'does.not.exist') is None + ) if __name__ == '__main__':