diff --git a/pkg/client/selfhosted/selfhosted.go b/pkg/client/selfhosted/selfhosted.go index 33bac242..47982684 100644 --- a/pkg/client/selfhosted/selfhosted.go +++ b/pkg/client/selfhosted/selfhosted.go @@ -114,13 +114,15 @@ func configureAuth(ctx context.Context, client *Client, opts *Options) error { token, err := client.setupBasicAuth(ctx, opts.Host, tokenPath) if httpErr, ok := selfhostederrors.IsHTTPError(err); ok { - return fmt.Errorf("failed to setup token auth (%d): %s", - httpErr.StatusCode, httpErr.Body) - } - if err != nil { + if httpErr.StatusCode == http.StatusNotFound { + client.log.Warnf("Token endpoint not found, using basic auth: %s%s %s", opts.Host, tokenPath, httpErr.Body) + } else { + return fmt.Errorf("failed to setup token auth (%d): %s", + httpErr.StatusCode, httpErr.Body) + } + } else if err != nil { return fmt.Errorf("failed to setup token auth: %s", err) } - client.Bearer = token return nil } @@ -229,7 +231,10 @@ func (c *Client) doRequest(ctx context.Context, url, header string, obj interfac req = req.WithContext(ctx) if len(c.Bearer) > 0 { req.Header.Add("Authorization", "Bearer "+c.Bearer) + } else if c.Username != "" && c.Password != "" { + req.SetBasicAuth(c.Username, c.Password) } + if len(header) > 0 { req.Header.Set("Accept", header) } diff --git a/pkg/client/selfhosted/selfhosted_test.go b/pkg/client/selfhosted/selfhosted_test.go index 3fd5abb5..223e6e6b 100644 --- a/pkg/client/selfhosted/selfhosted_test.go +++ b/pkg/client/selfhosted/selfhosted_test.go @@ -2,7 +2,9 @@ package selfhosted import ( "context" + "encoding/base64" "errors" + "fmt" "net/http" "net/http/httptest" "net/url" @@ -243,6 +245,31 @@ func TestDoRequest(t *testing.T) { assert.Error(t, err) assert.Contains(t, err.Error(), "unexpected") }) + + t.Run("use basic auth in request", func(t *testing.T) { + username := "foo" + password := "bar" + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, r.Header.Get("Authorization"), fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte(username+":"+password)))) + assert.Equal(t, "/v2/repo/image/tags/list", r.URL.Path) + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte(`{"tags":["v1","v2"]}`)) + })) + defer server.Close() + + h, err := url.Parse(server.URL) + assert.NoError(t, err) + + client.Username = username + client.Password = password + + var tagResponse TagResponse + headers, err := client.doRequest(ctx, h.Host+"/v2/repo/image/tags/list", "", &tagResponse) + + assert.NoError(t, err) + assert.NotNil(t, headers) + assert.Equal(t, []string{"v1", "v2"}, tagResponse.Tags) + }) } func TestSetupBasicAuth(t *testing.T) {