From b162d8868c0b14961347c80df834f93f0e7e82a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= Date: Sat, 11 Sep 2021 20:13:21 +0200 Subject: [PATCH] Add unit tests for multiAuthHeader MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also rename it to parseMultiAuthHeader. Should not change behavior. Signed-off-by: Miloslav Trmač --- pkg/auth/auth.go | 8 ++++---- pkg/auth/auth_test.go | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/pkg/auth/auth.go b/pkg/auth/auth.go index 070e222ad2..73822eecf2 100644 --- a/pkg/auth/auth.go +++ b/pkg/auth/auth.go @@ -21,7 +21,7 @@ type HeaderAuthName string func (h HeaderAuthName) String() string { return string(h) } // XRegistryAuthHeader is the key to the encoded registry authentication configuration in an http-request header. -// This header supports one registry per header occurrence. To support N registries provided N headers, one per registry. +// This header supports one registry per header occurrence. To support N registries provide N headers, one per registry. // As of Docker API 1.40 and Libpod API 1.0.0, this header is supported by all endpoints. const XRegistryAuthHeader HeaderAuthName = "X-Registry-Auth" @@ -108,7 +108,7 @@ func getConfigCredentials(r *http.Request) (*types.DockerAuthConfig, string, err // should be removed after usage. func getAuthCredentials(r *http.Request) (*types.DockerAuthConfig, string, error) { // First look for a multi-auth header (i.e., a map). - authConfigs, err := multiAuthHeader(r) + authConfigs, err := parseMultiAuthHeader(r) if err == nil { authfile, err := authConfigsToAuthFile(authConfigs) return nil, authfile, err @@ -327,9 +327,9 @@ func singleAuthHeader(r *http.Request) (map[string]types.DockerAuthConfig, error return authConfigs, nil } -// multiAuthHeader extracts a DockerAuthConfig from the request's header. +// parseMultiAuthHeader extracts a DockerAuthConfig from the request's header. // The header content is a map[string]DockerAuthConfigs. -func multiAuthHeader(r *http.Request) (map[string]types.DockerAuthConfig, error) { +func parseMultiAuthHeader(r *http.Request) (map[string]types.DockerAuthConfig, error) { authHeader := r.Header.Get(string(XRegistryAuthHeader)) // Accept "null" and handle it as empty value for compatibility reason with Docker. // Some java docker clients pass this value, e.g. this one used in Eclipse. diff --git a/pkg/auth/auth_test.go b/pkg/auth/auth_test.go index da2d9a5c51..97e7fe1ecd 100644 --- a/pkg/auth/auth_test.go +++ b/pkg/auth/auth_test.go @@ -1,11 +1,14 @@ package auth import ( + "encoding/base64" "io/ioutil" + "net/http" "testing" "github.com/containers/image/v5/types" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestAuthConfigsToAuthFile(t *testing.T) { @@ -64,3 +67,39 @@ func TestAuthConfigsToAuthFile(t *testing.T) { } } } + +func TestParseMultiAuthHeader(t *testing.T) { + for _, tc := range []struct { + input string + shouldErr bool + expected map[string]types.DockerAuthConfig + }{ + // Empty header + {input: "", expected: nil}, + // "null" + {input: "null", expected: nil}, + // Invalid JSON + {input: "@", shouldErr: true}, + // Success + { + input: base64.URLEncoding.EncodeToString([]byte( + `{"https://index.docker.io/v1/":{"username":"u1","password":"p1"},` + + `"quay.io/libpod":{"username":"u2","password":"p2"}}`)), + expected: map[string]types.DockerAuthConfig{ + "https://index.docker.io/v1/": {Username: "u1", Password: "p1"}, + "quay.io/libpod": {Username: "u2", Password: "p2"}, + }, + }, + } { + req, err := http.NewRequest(http.MethodPost, "/", nil) + require.NoError(t, err, tc.input) + req.Header.Set(XRegistryAuthHeader.String(), tc.input) + res, err := parseMultiAuthHeader(req) + if tc.shouldErr { + assert.Error(t, err, tc.input) + } else { + require.NoError(t, err, tc.input) + assert.Equal(t, tc.expected, res, tc.input) + } + } +}