Skip to content

Commit

Permalink
types: Add SystemContext.GetAuth
Browse files Browse the repository at this point in the history
The previous system is difficult to configure, with several
SystemContext properties feeding the auth-getting logic.  It also
assumed that there was either a single username/password
(DockerAuthConfig) or that the auth information was on disk somewhere.
With this commit, I'm pushing all of the complexity down into a
user-supplied getter (falling back to the old logic if the getter is
unset).  That makes it easy to plug in your own alternative without
worrying about the default logic.

The Docker-config AuthStore has a public Config property to make it
easy for callers to drop in their own configuration for read-only
access without having to go through either the filesystem or JSON.
I've made the backing types public to support that use-case, and set
custom JSON serialization for the newly-public Auth structure to allow
Go callers to avoid having to understand the base64 wrapping used in
the JSON serialization.

I've also shifted a number of auth-getting unit tests from
docker_client_test.go into config_test.go, since they only excercise
config.go logic.

Ideally the auth interface would support challenge/response auth like
[1], but for now it just uses Docker's "we'll be able to hard-code
authorization for each authority" approach.  URI authorities are
specified in [2].

[1]: https://tools.ietf.org/html/rfc7235
[2]: https://tools.ietf.org/html/rfc3986#section-3.2

Signed-off-by: W. Trevor King <[email protected]>
  • Loading branch information
wking committed Feb 25, 2019
1 parent f30d2c4 commit 44801dd
Show file tree
Hide file tree
Showing 6 changed files with 762 additions and 642 deletions.
18 changes: 18 additions & 0 deletions credentials/single/single.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Package single implements a basic credentials helper with a single username and secret.
package single

import (
"github.com/docker/docker-credential-helpers/credentials"
)

// AuthStore is a basic credentials store that holds a single entry.
type AuthStore credentials.Credentials

// Get retrieves credentials from the store.
func (s *AuthStore) Get(serverURL string) (string, string, error) {
if s == nil || serverURL != s.ServerURL {
return "", "", credentials.NewErrCredentialsNotFound()
}

return s.Username, s.Secret, nil
}
12 changes: 9 additions & 3 deletions docker/docker_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,10 +197,17 @@ func dockerCertDir(sys *types.SystemContext, hostPort string) (string, error) {
// “write” specifies whether the client will be used for "write" access (in particular passed to lookaside.go:toplevelFromSection)
func newDockerClientFromRef(sys *types.SystemContext, ref dockerReference, write bool, actions string) (*dockerClient, error) {
registry := reference.Domain(ref.ref)
username, password, err := config.GetAuthentication(sys, reference.Domain(ref.ref))
getAuth := sys.GetAuth
if getAuth == nil {
getAuth = func(serverURL string) (string, string, error) {
return config.GetAuthentication(sys, serverURL)
}
}
username, password, err := getAuth(registry)
if err != nil {
return nil, errors.Wrapf(err, "error getting username and password")
}

sigBase, err := configuredSignatureStorageBase(sys, ref, write)
if err != nil {
return nil, err
Expand Down Expand Up @@ -327,8 +334,7 @@ func SearchRegistry(ctx context.Context, sys *types.SystemContext, registry, ima
v2Res := &V2Results{}
v1Res := &V1Results{}

// Get credentials from authfile for the underlying hostname
username, password, err := config.GetAuthentication(sys, registry)
username, password, err := sys.GetAuth(registry)
if err != nil {
return nil, errors.Wrapf(err, "error getting username and password")
}
Expand Down
Loading

0 comments on commit 44801dd

Please sign in to comment.