Skip to content

Commit 310ea91

Browse files
committed
Fix support for legacy .dockercfg auth config format
Signed-off-by: Joffrey F <[email protected]>
1 parent f70545e commit 310ea91

File tree

4 files changed

+60
-57
lines changed

4 files changed

+60
-57
lines changed

docker/api/container.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,9 @@ def commit(self, container, repository=None, tag=None, message=None,
139139
'changes': changes
140140
}
141141
u = self._url("/commit")
142-
return self._result(self._post_json(u, data=conf, params=params),
143-
json=True)
142+
return self._result(
143+
self._post_json(u, data=conf, params=params), json=True
144+
)
144145

145146
def containers(self, quiet=False, all=False, trunc=False, latest=False,
146147
since=None, before=None, limit=-1, size=False,

docker/auth.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ def load_config(config_path=None, config_dict=None):
270270
"Couldn't find auth-related section ; attempting to interpret"
271271
"as auth-only file"
272272
)
273-
return parse_auth(config_dict)
273+
return {'auths': parse_auth(config_dict)}
274274

275275

276276
def _load_legacy_config(config_file):
@@ -287,14 +287,14 @@ def _load_legacy_config(config_file):
287287
)
288288

289289
username, password = decode_auth(data[0])
290-
return {
290+
return {'auths': {
291291
INDEX_NAME: {
292292
'username': username,
293293
'password': password,
294294
'email': data[1],
295295
'serveraddress': INDEX_URL,
296296
}
297-
}
297+
}}
298298
except Exception as e:
299299
log.debug(e)
300300
pass

tests/integration/api_client_test.py

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
import base64
2-
import os
3-
import tempfile
41
import time
52
import unittest
63
import warnings
@@ -24,43 +21,6 @@ def test_info(self):
2421
assert 'Debug' in res
2522

2623

27-
class LoadConfigTest(BaseAPIIntegrationTest):
28-
def test_load_legacy_config(self):
29-
folder = tempfile.mkdtemp()
30-
self.tmp_folders.append(folder)
31-
cfg_path = os.path.join(folder, '.dockercfg')
32-
f = open(cfg_path, 'w')
33-
auth_ = base64.b64encode(b'sakuya:izayoi').decode('ascii')
34-
f.write('auth = {0}\n'.format(auth_))
35-
f.write('email = [email protected]')
36-
f.close()
37-
cfg = docker.auth.load_config(cfg_path)
38-
assert cfg[docker.auth.INDEX_NAME] is not None
39-
cfg = cfg[docker.auth.INDEX_NAME]
40-
assert cfg['username'] == 'sakuya'
41-
assert cfg['password'] == 'izayoi'
42-
assert cfg['email'] == '[email protected]'
43-
assert cfg.get('Auth') is None
44-
45-
def test_load_json_config(self):
46-
folder = tempfile.mkdtemp()
47-
self.tmp_folders.append(folder)
48-
cfg_path = os.path.join(folder, '.dockercfg')
49-
f = open(os.path.join(folder, '.dockercfg'), 'w')
50-
auth_ = base64.b64encode(b'sakuya:izayoi').decode('ascii')
51-
email_ = '[email protected]'
52-
f.write('{{"{0}": {{"auth": "{1}", "email": "{2}"}}}}\n'.format(
53-
docker.auth.INDEX_URL, auth_, email_))
54-
f.close()
55-
cfg = docker.auth.load_config(cfg_path)
56-
assert cfg[docker.auth.INDEX_URL] is not None
57-
cfg = cfg[docker.auth.INDEX_URL]
58-
assert cfg['username'] == 'sakuya'
59-
assert cfg['password'] == 'izayoi'
60-
assert cfg['email'] == '[email protected]'
61-
assert cfg.get('Auth') is None
62-
63-
6424
class AutoDetectVersionTest(unittest.TestCase):
6525
def test_client_init(self):
6626
client = docker.APIClient(version='auto', **kwargs_from_env())

tests/unit/auth_test.py

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -282,22 +282,64 @@ def test_load_config_no_file(self):
282282
cfg = auth.load_config(folder)
283283
assert cfg is not None
284284

285-
def test_load_config(self):
285+
def test_load_legacy_config(self):
286286
folder = tempfile.mkdtemp()
287287
self.addCleanup(shutil.rmtree, folder)
288-
dockercfg_path = os.path.join(folder, '.dockercfg')
289-
with open(dockercfg_path, 'w') as f:
290-
auth_ = base64.b64encode(b'sakuya:izayoi').decode('ascii')
288+
cfg_path = os.path.join(folder, '.dockercfg')
289+
auth_ = base64.b64encode(b'sakuya:izayoi').decode('ascii')
290+
with open(cfg_path, 'w') as f:
291291
f.write('auth = {0}\n'.format(auth_))
292292
f.write('email = [email protected]')
293-
cfg = auth.load_config(dockercfg_path)
294-
assert auth.INDEX_NAME in cfg
295-
assert cfg[auth.INDEX_NAME] is not None
296-
cfg = cfg[auth.INDEX_NAME]
293+
294+
cfg = auth.load_config(cfg_path)
295+
assert auth.resolve_authconfig(cfg) is not None
296+
assert cfg['auths'][auth.INDEX_NAME] is not None
297+
cfg = cfg['auths'][auth.INDEX_NAME]
297298
assert cfg['username'] == 'sakuya'
298299
assert cfg['password'] == 'izayoi'
299300
assert cfg['email'] == '[email protected]'
300-
assert cfg.get('auth') is None
301+
assert cfg.get('Auth') is None
302+
303+
def test_load_json_config(self):
304+
folder = tempfile.mkdtemp()
305+
self.addCleanup(shutil.rmtree, folder)
306+
cfg_path = os.path.join(folder, '.dockercfg')
307+
auth_ = base64.b64encode(b'sakuya:izayoi').decode('ascii')
308+
309+
with open(cfg_path, 'w') as f:
310+
json.dump(
311+
{auth.INDEX_URL: {'auth': auth_, 'email': email}}, f
312+
)
313+
cfg = auth.load_config(cfg_path)
314+
assert auth.resolve_authconfig(cfg) is not None
315+
assert cfg['auths'][auth.INDEX_URL] is not None
316+
cfg = cfg['auths'][auth.INDEX_URL]
317+
assert cfg['username'] == 'sakuya'
318+
assert cfg['password'] == 'izayoi'
319+
assert cfg['email'] == email
320+
assert cfg.get('Auth') is None
321+
322+
def test_load_modern_json_config(self):
323+
folder = tempfile.mkdtemp()
324+
self.addCleanup(shutil.rmtree, folder)
325+
cfg_path = os.path.join(folder, 'config.json')
326+
auth_ = base64.b64encode(b'sakuya:izayoi').decode('ascii')
327+
328+
with open(cfg_path, 'w') as f:
329+
json.dump({
330+
'auths': {
331+
auth.INDEX_URL: {
332+
'auth': auth_, 'email': email
333+
}
334+
}
335+
}, f)
336+
cfg = auth.load_config(cfg_path)
337+
assert auth.resolve_authconfig(cfg) is not None
338+
assert cfg['auths'][auth.INDEX_URL] is not None
339+
cfg = cfg['auths'][auth.INDEX_URL]
340+
assert cfg['username'] == 'sakuya'
341+
assert cfg['password'] == 'izayoi'
342+
assert cfg['email'] == email
301343

302344
def test_load_config_with_random_name(self):
303345
folder = tempfile.mkdtemp()
@@ -318,7 +360,7 @@ def test_load_config_with_random_name(self):
318360
with open(dockercfg_path, 'w') as f:
319361
json.dump(config, f)
320362

321-
cfg = auth.load_config(dockercfg_path)
363+
cfg = auth.load_config(dockercfg_path)['auths']
322364
assert registry in cfg
323365
assert cfg[registry] is not None
324366
cfg = cfg[registry]
@@ -345,7 +387,7 @@ def test_load_config_custom_config_env(self):
345387
json.dump(config, f)
346388

347389
with mock.patch.dict(os.environ, {'DOCKER_CONFIG': folder}):
348-
cfg = auth.load_config(None)
390+
cfg = auth.load_config(None)['auths']
349391
assert registry in cfg
350392
assert cfg[registry] is not None
351393
cfg = cfg[registry]
@@ -422,7 +464,7 @@ def test_load_config_unknown_keys(self):
422464
json.dump(config, f)
423465

424466
cfg = auth.load_config(dockercfg_path)
425-
assert cfg == {}
467+
assert cfg == {'auths': {}}
426468

427469
def test_load_config_invalid_auth_dict(self):
428470
folder = tempfile.mkdtemp()

0 commit comments

Comments
 (0)