pkg/auth: re-allow http{s} prefixes
Until version v3.2, `podman login` trimmed http{s} prefixes along with
everything else but the host[:port] parts. Starting with v3.3, `login`
supports storing credentials for namespaces and dropped support for
trimming prefixes due to ambiguities in registry URLs.
The aforementioned changes caused a regression (see BZ below) as some
users depend on the prefix trimming. Fix that regression by enabling
the http{s} prefix trimming. If present, everything but the host[:port]
parts will be stripped as well.
* `login quay.io/repo` uses `quay.io/repo`
* `login https://quay.io/repo` uses `quay.io`
Fixes: bugzilla.redhat.com/show_bug.cgi?id=2062072
Signed-off-by: Valentin Rothberg <vrothberg@redhat.com>
This commit is contained in:
parent
7d08b8b9f7
commit
c9914e52de
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -165,20 +166,21 @@ func Login(ctx context.Context, systemContext *types.SystemContext, opts *LoginO
|
||||||
// parseCredentialsKey turns the provided argument into a valid credential key
|
// parseCredentialsKey turns the provided argument into a valid credential key
|
||||||
// and computes the registry part.
|
// and computes the registry part.
|
||||||
func parseCredentialsKey(arg string, acceptRepositories bool) (key, registry string, err error) {
|
func parseCredentialsKey(arg string, acceptRepositories bool) (key, registry string, err error) {
|
||||||
|
// URL arguments are replaced with their host[:port] parts.
|
||||||
|
key, err = replaceURLByHostPort(arg)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
split := strings.Split(key, "/")
|
||||||
|
registry = split[0]
|
||||||
|
|
||||||
if !acceptRepositories {
|
if !acceptRepositories {
|
||||||
registry = getRegistryName(arg)
|
return registry, registry, nil
|
||||||
key = registry
|
|
||||||
return key, registry, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
key = trimScheme(arg)
|
// Return early if the key isn't namespaced or uses an http{s} prefix.
|
||||||
if key != arg {
|
|
||||||
return "", "", errors.New("credentials key has https[s]:// prefix")
|
|
||||||
}
|
|
||||||
|
|
||||||
registry = getRegistryName(key)
|
|
||||||
if registry == key {
|
if registry == key {
|
||||||
// The key is not namespaced
|
|
||||||
return key, registry, nil
|
return key, registry, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -202,24 +204,18 @@ func parseCredentialsKey(arg string, acceptRepositories bool) (key, registry str
|
||||||
return key, registry, nil
|
return key, registry, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getRegistryName scrubs and parses the input to get the server name
|
// If the specified string starts with http{s} it is replaced with it's
|
||||||
func getRegistryName(server string) string {
|
// host[:port] parts; everything else is stripped. Otherwise, the string is
|
||||||
// removes 'http://' or 'https://' from the front of the
|
// returned as is.
|
||||||
// server/registry string if either is there. This will be mostly used
|
func replaceURLByHostPort(repository string) (string, error) {
|
||||||
// for user input from 'Buildah login' and 'Buildah logout'.
|
if !strings.HasPrefix(repository, "https://") && !strings.HasPrefix(repository, "http://") {
|
||||||
server = trimScheme(server)
|
return repository, nil
|
||||||
// gets the registry from the input. If the input is of the form
|
}
|
||||||
// quay.io/myuser/myimage, it will parse it and just return quay.io
|
u, err := url.Parse(repository)
|
||||||
split := strings.Split(server, "/")
|
if err != nil {
|
||||||
return split[0]
|
return "", fmt.Errorf("trimming http{s} prefix: %v", err)
|
||||||
}
|
}
|
||||||
|
return u.Host, nil
|
||||||
// trimScheme removes the HTTP(s) scheme from the provided repository.
|
|
||||||
func trimScheme(repository string) string {
|
|
||||||
// removes 'http://' or 'https://' from the front of the
|
|
||||||
// server/registry string if either is there. This will be mostly used
|
|
||||||
// for user input from 'Buildah login' and 'Buildah logout'.
|
|
||||||
return strings.TrimPrefix(strings.TrimPrefix(repository, "https://"), "http://")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// getUserAndPass gets the username and password from STDIN if not given
|
// getUserAndPass gets the username and password from STDIN if not given
|
||||||
|
|
|
||||||
|
|
@ -104,10 +104,74 @@ func TestParseCredentialsKey(t *testing.T) {
|
||||||
expectedRegistry: "docker.io",
|
expectedRegistry: "docker.io",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "with http[s] prefix",
|
name: "with http[s] prefix - accept repositories",
|
||||||
arg: "https://quay.io",
|
arg: "https://quay.io",
|
||||||
acceptRepositories: true,
|
acceptRepositories: true,
|
||||||
expectedKey: "",
|
expectedKey: "quay.io",
|
||||||
|
expectedRegistry: "quay.io",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with http[s] prefix - accept repositories",
|
||||||
|
arg: "http://example.com/v2/",
|
||||||
|
acceptRepositories: true,
|
||||||
|
expectedKey: "example.com",
|
||||||
|
expectedRegistry: "example.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with http[s] prefix + path - accept repositories",
|
||||||
|
arg: "https://quay.io/repo/imag:tag",
|
||||||
|
acceptRepositories: true,
|
||||||
|
expectedKey: "quay.io",
|
||||||
|
expectedRegistry: "quay.io",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with http[s] prefix + port - accept repositories",
|
||||||
|
arg: "https://quay.io:1234",
|
||||||
|
acceptRepositories: true,
|
||||||
|
expectedKey: "quay.io:1234",
|
||||||
|
expectedRegistry: "quay.io:1234",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with http[s] prefix + port + path - accept repositories",
|
||||||
|
arg: "https://quay.io:1234/repo@foo",
|
||||||
|
acceptRepositories: true,
|
||||||
|
expectedKey: "quay.io:1234",
|
||||||
|
expectedRegistry: "quay.io:1234",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with http[s] prefix",
|
||||||
|
arg: "https://quay.io",
|
||||||
|
acceptRepositories: false,
|
||||||
|
expectedKey: "quay.io",
|
||||||
|
expectedRegistry: "quay.io",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with http[s] prefix",
|
||||||
|
arg: "http://example.com/v2/",
|
||||||
|
acceptRepositories: false,
|
||||||
|
expectedKey: "example.com",
|
||||||
|
expectedRegistry: "example.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with http[s] prefix + path",
|
||||||
|
arg: "https://quay.io/repo/imag:tag",
|
||||||
|
acceptRepositories: false,
|
||||||
|
expectedKey: "quay.io",
|
||||||
|
expectedRegistry: "quay.io",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with http[s] prefix + port",
|
||||||
|
arg: "https://quay.io:1234",
|
||||||
|
acceptRepositories: false,
|
||||||
|
expectedKey: "quay.io:1234",
|
||||||
|
expectedRegistry: "quay.io:1234",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with http[s] prefix + port + path",
|
||||||
|
arg: "https://quay.io:1234/repo@foo",
|
||||||
|
acceptRepositories: false,
|
||||||
|
expectedKey: "quay.io:1234",
|
||||||
|
expectedRegistry: "quay.io:1234",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "failure with tag",
|
name: "failure with tag",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue