mirror of https://github.com/knative/func.git
Allow empty credentials registry (#1004)
* Allow empty credentials registry Useful when using local unsecured registry. Signed-off-by: Matej Vasek <mvasek@redhat.com> * Added tests for empty credentials registries Signed-off-by: Matej Vasek <mvasek@redhat.com>
This commit is contained in:
parent
75fe105969
commit
ac8f1d2d66
|
|
@ -36,13 +36,6 @@ type VerifyCredentialsCallback func(ctx context.Context, registry string, creden
|
|||
|
||||
// CheckAuth verifies that credentials are correct
|
||||
func CheckAuth(ctx context.Context, registry string, credentials docker.Credentials, trans http.RoundTripper) error {
|
||||
serverAddress := registry
|
||||
if !strings.HasPrefix(serverAddress, "https://") && !strings.HasPrefix(serverAddress, "http://") {
|
||||
serverAddress = "https://" + serverAddress
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s/v2/", serverAddress)
|
||||
|
||||
authenticator := &authn.Basic{
|
||||
Username: credentials.Username,
|
||||
Password: credentials.Password,
|
||||
|
|
@ -53,6 +46,13 @@ func CheckAuth(ctx context.Context, registry string, credentials docker.Credenti
|
|||
return err
|
||||
}
|
||||
|
||||
serverAddress := registry
|
||||
if !strings.HasPrefix(serverAddress, "https://") && !strings.HasPrefix(serverAddress, "http://") {
|
||||
serverAddress = reg.Scheme() + "://" + serverAddress
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s/v2/", serverAddress)
|
||||
|
||||
tr, err := transport.NewWithContext(ctx, reg, authenticator, trans, nil)
|
||||
if err != nil {
|
||||
var transportErr *transport.Error
|
||||
|
|
@ -189,6 +189,9 @@ func NewCredentialsProvider(opts ...Opt) docker.CredentialsProvider {
|
|||
dockerConfigPath := filepath.Join(home, ".docker", "config.json")
|
||||
|
||||
var defaultCredentialLoaders = []CredentialsCallback{
|
||||
func(registry string) (docker.Credentials, error) { // empty credentials provider for unsecured registries
|
||||
return docker.Credentials{}, nil
|
||||
},
|
||||
func(registry string) (docker.Credentials, error) {
|
||||
creds, err := config.GetCredentials(sys, registry)
|
||||
if err != nil {
|
||||
|
|
@ -220,20 +223,22 @@ func (c *credentialsProvider) getCredentials(ctx context.Context, registry strin
|
|||
|
||||
result, err = load(registry)
|
||||
|
||||
if err != nil && !errors.Is(err, errCredentialsNotFound) {
|
||||
if err != nil {
|
||||
if errors.Is(err, errCredentialsNotFound) {
|
||||
continue
|
||||
}
|
||||
return docker.Credentials{}, err
|
||||
}
|
||||
|
||||
if result != (docker.Credentials{}) {
|
||||
err = c.verifyCredentials(ctx, registry, result)
|
||||
if err == nil {
|
||||
return result, nil
|
||||
} else {
|
||||
if !errors.Is(err, ErrUnauthorized) {
|
||||
return docker.Credentials{}, err
|
||||
}
|
||||
err = c.verifyCredentials(ctx, registry, result)
|
||||
if err == nil {
|
||||
return result, nil
|
||||
} else {
|
||||
if !errors.Is(err, ErrUnauthorized) {
|
||||
return docker.Credentials{}, err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if c.promptForCredentials == nil {
|
||||
|
|
|
|||
|
|
@ -68,8 +68,15 @@ func Test_registryEquals(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCheckAuth(t *testing.T) {
|
||||
localhost, localhostTLS, stopServer := startServer(t)
|
||||
defer stopServer()
|
||||
|
||||
const (
|
||||
uname = "testuser"
|
||||
pwd = "testpwd"
|
||||
incorrectPwd = "badpwd"
|
||||
)
|
||||
|
||||
localhost, localhostTLS, stopServer := startServer(t, uname, pwd)
|
||||
t.Cleanup(stopServer)
|
||||
|
||||
_, portTLS, err := net.SplitHostPort(localhostTLS)
|
||||
if err != nil {
|
||||
|
|
@ -93,8 +100,8 @@ func TestCheckAuth(t *testing.T) {
|
|||
name: "correct credentials localhost no-TLS",
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
username: "testuser",
|
||||
password: "testpwd",
|
||||
username: uname,
|
||||
password: pwd,
|
||||
registry: localhost,
|
||||
},
|
||||
wantErr: false,
|
||||
|
|
@ -103,8 +110,8 @@ func TestCheckAuth(t *testing.T) {
|
|||
name: "correct credentials localhost",
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
username: "testuser",
|
||||
password: "testpwd",
|
||||
username: uname,
|
||||
password: pwd,
|
||||
registry: localhostTLS,
|
||||
},
|
||||
wantErr: false,
|
||||
|
|
@ -114,8 +121,8 @@ func TestCheckAuth(t *testing.T) {
|
|||
name: "correct credentials non-localhost",
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
username: "testuser",
|
||||
password: "testpwd",
|
||||
username: uname,
|
||||
password: pwd,
|
||||
registry: nonLocalhostTLS,
|
||||
},
|
||||
wantErr: false,
|
||||
|
|
@ -124,8 +131,8 @@ func TestCheckAuth(t *testing.T) {
|
|||
name: "incorrect credentials localhost no-TLS",
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
username: "testuser",
|
||||
password: "badpwd",
|
||||
username: uname,
|
||||
password: incorrectPwd,
|
||||
registry: localhost,
|
||||
},
|
||||
wantErr: true,
|
||||
|
|
@ -134,8 +141,8 @@ func TestCheckAuth(t *testing.T) {
|
|||
name: "incorrect credentials localhost",
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
username: "testuser",
|
||||
password: "badpwd",
|
||||
username: uname,
|
||||
password: incorrectPwd,
|
||||
registry: localhostTLS,
|
||||
},
|
||||
wantErr: true,
|
||||
|
|
@ -154,7 +161,17 @@ func TestCheckAuth(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func startServer(t *testing.T) (addr, addrTLS string, stopServer func()) {
|
||||
func TestCheckAuthEmptyCreds(t *testing.T) {
|
||||
|
||||
localhost, _, stopServer := startServer(t, "", "")
|
||||
t.Cleanup(stopServer)
|
||||
err := creds.CheckAuth(context.Background(), localhost, docker.Credentials{}, http.DefaultTransport)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func startServer(t *testing.T, uname, pwd string) (addr, addrTLS string, stopServer func()) {
|
||||
// TODO: this should be refactored to use OS-chosen ports so as not to
|
||||
// fail when a user is running a Function on the default port.)
|
||||
listener, err := net.Listen("tcp", "localhost:0")
|
||||
|
|
@ -170,10 +187,14 @@ func startServer(t *testing.T) (addr, addrTLS string, stopServer func()) {
|
|||
addrTLS = listenerTLS.Addr().String()
|
||||
|
||||
handler := http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
|
||||
if uname == "" || pwd == "" {
|
||||
resp.WriteHeader(http.StatusOK)
|
||||
return
|
||||
}
|
||||
// TODO add also test for token based auth
|
||||
resp.Header().Add("WWW-Authenticate", "basic")
|
||||
if user, pwd, ok := req.BasicAuth(); ok {
|
||||
if user == "testuser" && pwd == "testpwd" {
|
||||
if u, p, ok := req.BasicAuth(); ok {
|
||||
if u == uname && p == pwd {
|
||||
resp.WriteHeader(http.StatusOK)
|
||||
return
|
||||
}
|
||||
|
|
@ -401,6 +422,23 @@ func TestNewCredentialsProvider(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestNewCredentialsProviderEmptyCreds(t *testing.T) {
|
||||
credentialsProvider := creds.NewCredentialsProvider(creds.WithVerifyCredentials(func(ctx context.Context, registry string, credentials docker.Credentials) error {
|
||||
if registry == "localhost:5000" && credentials == (docker.Credentials{}) {
|
||||
return nil
|
||||
}
|
||||
t.Fatal("unreachable")
|
||||
return nil
|
||||
}))
|
||||
c, err := credentialsProvider(context.Background(), "localhost:5000")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if c != (docker.Credentials{}) {
|
||||
t.Error("unexpected credentials")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCredentialsProviderSavingFromUserInput(t *testing.T) {
|
||||
defer withCleanHome(t)()
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue