package updater import ( "encoding/base64" "encoding/json" "io" "log/slog" "os" "path/filepath" "testing" "github.com/docker/docker/api/types/registry" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func writeDockerConfig(t *testing.T, body string) string { t.Helper() dir := t.TempDir() require.NoError(t, os.WriteFile(filepath.Join(dir, "config.json"), []byte(body), 0o600)) return dir } func decodeAuth(t *testing.T, enc string) registry.AuthConfig { t.Helper() raw, err := base64.URLEncoding.DecodeString(enc) require.NoError(t, err) var ac registry.AuthConfig require.NoError(t, json.Unmarshal(raw, &ac)) return ac } func TestRegistryAuth(t *testing.T) { user := base64.StdEncoding.EncodeToString([]byte("bob:s3cret")) log := slog.New(slog.NewTextHandler(io.Discard, nil)) t.Run("docker hub spellings", func(t *testing.T) { for _, key := range []string{"https://index.docker.io/v1/", "index.docker.io", "docker.io", "registry-1.docker.io"} { dir := writeDockerConfig(t, `{"auths":{"`+key+`":{"auth":"`+user+`"}}}`) a, err := LoadRegistryAuth(dir, log) require.NoError(t, err) for _, repo := range []string{"gitea/gitea", "docker.io/library/nginx", "nginx"} { ac := decodeAuth(t, a.For(repo)) assert.Equal(t, "bob", ac.Username, "%s for %s", key, repo) assert.Equal(t, "s3cret", ac.Password) } assert.Empty(t, a.For("gitea.shcizo.se/shcizo/slusk")) } }) t.Run("custom registry with scheme", func(t *testing.T) { dir := writeDockerConfig(t, `{"auths":{"https://gitea.shcizo.se":{"auth":"`+user+`"},"ghcr.io":{"identitytoken":"tok"}}}`) a, err := LoadRegistryAuth(dir, log) require.NoError(t, err) assert.Equal(t, "bob", decodeAuth(t, a.For("gitea.shcizo.se/shcizo/slusk")).Username) assert.Equal(t, "tok", decodeAuth(t, a.For("ghcr.io/x/y")).IdentityToken) assert.Empty(t, a.For("registry.example.com/x")) }) t.Run("empty dir is anonymous", func(t *testing.T) { a, err := LoadRegistryAuth("", log) require.NoError(t, err) assert.Nil(t, a) assert.Empty(t, a.For("gitea/gitea")) }) t.Run("malformed json", func(t *testing.T) { _, err := LoadRegistryAuth(writeDockerConfig(t, "{"), log) assert.Error(t, err) }) t.Run("missing file", func(t *testing.T) { _, err := LoadRegistryAuth(t.TempDir(), log) assert.Error(t, err) }) }