Skip to content

Commit

Permalink
fix: fallback matching of registry authentication config (#1927)
Browse files Browse the repository at this point in the history
  • Loading branch information
sermio-te authored Nov 29, 2023
1 parent 3a513f3 commit 5046458
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 6 deletions.
23 changes: 22 additions & 1 deletion docker_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/base64"
"encoding/json"
"net/url"
"os"

"github.com/cpuguy83/dockercfg"
Expand All @@ -24,13 +25,33 @@ func DockerImageAuth(ctx context.Context, image string) (string, registry.AuthCo
return reg, registry.AuthConfig{}, err
}

if cfg, ok := cfgs[reg]; ok {
if cfg, ok := getRegistryAuth(reg, cfgs); ok {
return reg, cfg, nil
}

return reg, registry.AuthConfig{}, dockercfg.ErrCredentialsNotFound
}

func getRegistryAuth(reg string, cfgs map[string]registry.AuthConfig) (registry.AuthConfig, bool) {
if cfg, ok := cfgs[reg]; ok {
return cfg, true
}

// fallback match using authentication key host
for k, cfg := range cfgs {
keyURL, err := url.Parse(k)
if err != nil {
continue
}

if keyURL.Host == reg {
return cfg, true
}
}

return registry.AuthConfig{}, false
}

// defaultRegistry returns the default registry to use when pulling images
// It will use the docker daemon to get the default registry, returning "https://index.docker.io/v1/" if
// it fails to get the information from the daemon
Expand Down
52 changes: 47 additions & 5 deletions docker_auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ func TestGetDockerConfig(t *testing.T) {
// Then, we can safely run the tests that rely on it.
defaultCfg, err := dockercfg.LoadDefaultConfig()
require.Nil(t, err)
require.NotNil(t, defaultCfg)
require.NotEmpty(t, defaultCfg)

t.Run("without DOCKER_CONFIG env var retrieves default", func(t *testing.T) {
t.Setenv("DOCKER_CONFIG", "")

cfg, err := getDockerConfig()
require.Nil(t, err)
require.NotNil(t, cfg)
require.NotEmpty(t, cfg)

assert.Equal(t, defaultCfg, cfg)
})
Expand All @@ -55,7 +55,7 @@ func TestGetDockerConfig(t *testing.T) {

cfg, err := getDockerConfig()
require.Nil(t, err)
require.NotNil(t, cfg)
require.NotEmpty(t, cfg)

assert.Equal(t, 3, len(cfg.AuthConfigs))

Expand Down Expand Up @@ -83,7 +83,7 @@ func TestGetDockerConfig(t *testing.T) {

cfg, err := getDockerConfig()
require.Nil(t, err)
require.NotNil(t, cfg)
require.NotEmpty(t, cfg)

assert.Equal(t, 1, len(cfg.AuthConfigs))

Expand All @@ -109,13 +109,55 @@ func TestGetDockerConfig(t *testing.T) {

registry, cfg, err := DockerImageAuth(context.Background(), exampleAuth+"/my/image:latest")
require.Nil(t, err)
require.NotNil(t, cfg)
require.NotEmpty(t, cfg)

assert.Equal(t, exampleAuth, registry)
assert.Equal(t, "gopher", cfg.Username)
assert.Equal(t, "secret", cfg.Password)
assert.Equal(t, base64, cfg.Auth)
})

t.Run("match registry authentication by host", func(t *testing.T) {
base64 := "Z29waGVyOnNlY3JldA==" // gopher:secret
imageReg := "example-auth.com"
imagePath := "/my/image:latest"

t.Setenv("DOCKER_AUTH_CONFIG", `{
"auths": {
"`+exampleAuth+`": { "username": "gopher", "password": "secret", "auth": "`+base64+`" }
},
"credsStore": "desktop"
}`)

registry, cfg, err := DockerImageAuth(context.Background(), imageReg+imagePath)
require.Nil(t, err)
require.NotEmpty(t, cfg)

assert.Equal(t, imageReg, registry)
assert.Equal(t, "gopher", cfg.Username)
assert.Equal(t, "secret", cfg.Password)
assert.Equal(t, base64, cfg.Auth)
})

t.Run("fail to match registry authentication due to invalid host", func(t *testing.T) {
base64 := "Z29waGVyOnNlY3JldA==" // gopher:secret
imageReg := "example-auth.com"
imagePath := "/my/image:latest"
invalidRegistryURL := "://invalid-host"

t.Setenv("DOCKER_AUTH_CONFIG", `{
"auths": {
"`+invalidRegistryURL+`": { "username": "gopher", "password": "secret", "auth": "`+base64+`" }
},
"credsStore": "desktop"
}`)

registry, cfg, err := DockerImageAuth(context.Background(), imageReg+imagePath)
require.Equal(t, err, dockercfg.ErrCredentialsNotFound)
require.Empty(t, cfg)

assert.Equal(t, imageReg, registry)
})
}

func TestBuildContainerFromDockerfile(t *testing.T) {
Expand Down

0 comments on commit 5046458

Please sign in to comment.