From 23348449a84465c5c3d99ff4da012620bdd8080a Mon Sep 17 00:00:00 2001 From: Patrick Jahn <33724206+p-jahn@users.noreply.github.com> Date: Sat, 20 Apr 2024 20:50:09 +0200 Subject: [PATCH] fix: fallback to URL-path when parsing auth config URL without scheme (#2488) --- docker_auth.go | 13 +++++++++++-- docker_auth_test.go | 29 ++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/docker_auth.go b/docker_auth.go index e6fcfedf83..04b8527ccb 100644 --- a/docker_auth.go +++ b/docker_auth.go @@ -13,11 +13,14 @@ import ( "github.com/testcontainers/testcontainers-go/internal/core" ) +// defaultRegistryFn is variable overwritten in tests to check for behaviour with different default values. +var defaultRegistryFn = defaultRegistry + // DockerImageAuth returns the auth config for the given Docker image, extracting first its Docker registry. // Finally, it will use the credential helpers to extract the information from the docker config file // for that registry, if it exists. func DockerImageAuth(ctx context.Context, image string) (string, registry.AuthConfig, error) { - defaultRegistry := defaultRegistry(ctx) + defaultRegistry := defaultRegistryFn(ctx) reg := core.ExtractRegistry(image, defaultRegistry) cfgs, err := getDockerAuthConfigs() @@ -44,7 +47,13 @@ func getRegistryAuth(reg string, cfgs map[string]registry.AuthConfig) (registry. continue } - if keyURL.Host == reg { + host := keyURL.Host + if keyURL.Scheme == "" { + // url.Parse: The url may be relative (a path, without a host) [...] + host = keyURL.Path + } + + if host == reg { return cfg, true } } diff --git a/docker_auth_test.go b/docker_auth_test.go index 514cf753c7..33602a4347 100644 --- a/docker_auth_test.go +++ b/docker_auth_test.go @@ -153,7 +153,34 @@ func TestGetDockerConfig(t *testing.T) { }`) registry, cfg, err := DockerImageAuth(context.Background(), imageReg+imagePath) - require.Equal(t, err, dockercfg.ErrCredentialsNotFound) + require.ErrorIs(t, err, dockercfg.ErrCredentialsNotFound) + require.Empty(t, cfg) + + assert.Equal(t, imageReg, registry) + }) + + t.Run("fail to match registry authentication by host with empty URL scheme creds and missing default", func(t *testing.T) { + origDefaultRegistryFn := defaultRegistryFn + t.Cleanup(func() { + defaultRegistryFn = origDefaultRegistryFn + }) + defaultRegistryFn = func(ctx context.Context) string { + return "" + } + + base64 := "Z29waGVyOnNlY3JldA==" // gopher:secret + imageReg := "" + imagePath := "image:latest" + + t.Setenv("DOCKER_AUTH_CONFIG", `{ + "auths": { + "example-auth.com": { "username": "gopher", "password": "secret", "auth": "`+base64+`" } + }, + "credsStore": "desktop" + }`) + + registry, cfg, err := DockerImageAuth(context.Background(), imageReg+imagePath) + require.ErrorIs(t, err, dockercfg.ErrCredentialsNotFound) require.Empty(t, cfg) assert.Equal(t, imageReg, registry)