11package configfile
22
33import (
4+ "context"
45 "encoding/base64"
56 "encoding/json"
67 "fmt"
@@ -12,6 +13,7 @@ import (
1213 "github.com/docker/cli/cli/config/credentials"
1314 "github.com/docker/cli/cli/config/memorystore"
1415 "github.com/docker/cli/cli/config/types"
16+ "github.com/docker/docker/api/types/registry"
1517 "github.com/pkg/errors"
1618 "github.com/sirupsen/logrus"
1719)
@@ -301,20 +303,9 @@ func (configFile *ConfigFile) GetCredentialsStore(registryHostname string) crede
301303 return store
302304 }
303305
304- authConfig , err := parseEnvConfig (envConfig )
305- if err != nil {
306- _ , _ = fmt .Fprintln (os .Stderr , "Failed to create credential store from DOCKER_AUTH_CONFIG: " , err )
307- return store
308- }
309-
310- // use DOCKER_AUTH_CONFIG if set
311- // it uses the native or file store as a fallback to fetch and store credentials
312- envStore , err := memorystore .New (
313- memorystore .WithAuthConfig (authConfig ),
314- memorystore .WithFallbackStore (store ),
315- )
306+ envStore , err := getEnvStore (envConfig , store )
316307 if err != nil {
317- _ , _ = fmt .Fprintln (os .Stderr , "Failed to create credential store from DOCKER_AUTH_CONFIG: " , err )
308+ _ , _ = fmt .Fprintln (os .Stderr , err )
318309 return store
319310 }
320311
@@ -360,6 +351,92 @@ func (configFile *ConfigFile) GetAuthConfig(registryHostname string) (types.Auth
360351 return configFile .GetCredentialsStore (registryHostname ).Get (registryHostname )
361352}
362353
354+ func getEnvStore (envConfig string , fallbackStore credentials.Store ) (credentials.Store , error ) {
355+ authConfig , err := parseEnvConfig (envConfig )
356+ if err != nil {
357+ return nil , fmt .Errorf ("failed to create credential store from %s: %w" , DockerEnvConfigKey , err )
358+ }
359+
360+ // use DOCKER_AUTH_CONFIG if set
361+ // it uses the native or file store as a fallback to fetch and store credentials
362+ envStore , err := memorystore .New (
363+ memorystore .WithAuthConfig (authConfig ),
364+ memorystore .WithFallbackStore (fallbackStore ),
365+ )
366+ if err != nil {
367+ return nil , fmt .Errorf ("failed to create credential store from %s: %w" , DockerEnvConfigKey , err )
368+ }
369+ return envStore , nil
370+ }
371+
372+ func getEncodedAuth (store credentials.Store , registryHostname string ) (string , error ) {
373+ c , err := store .Get (registryHostname )
374+ if err != nil {
375+ return "" , err
376+ }
377+ return registry .EncodeAuthConfig (registry .AuthConfig (c ))
378+ }
379+
380+ func envRequestAuthConfig (registryHostname string ) registry.RequestAuthConfig {
381+ return func (ctx context.Context ) (string , error ) {
382+ fmt .Fprintln (os .Stdout , "Trying env" )
383+
384+ envConfig := os .Getenv (DockerEnvConfigKey )
385+ if envConfig == "" {
386+ return "" , fmt .Errorf ("%s not defined" , DockerEnvConfigKey )
387+ }
388+
389+ envStore , err := getEnvStore (envConfig , nil )
390+ if err != nil {
391+ return "" , err
392+ }
393+ return getEncodedAuth (envStore , registryHostname )
394+ }
395+ }
396+
397+ func nativeRequestAuthConfig (configFile * ConfigFile , registryHostname string ) registry.RequestAuthConfig {
398+ return func (ctx context.Context ) (string , error ) {
399+ fmt .Fprintln (os .Stdout , "Trying native" )
400+ helper := getConfiguredCredentialStore (configFile , registryHostname )
401+ if helper == "" {
402+ return "" , errors .New ("native credential helper not supported" )
403+ }
404+ store := newNativeStore (configFile , helper )
405+ return getEncodedAuth (store , registryHostname )
406+ }
407+ }
408+
409+ func fileRequestAuthConfig (configFile * ConfigFile , registryHostname string ) registry.RequestAuthConfig {
410+ return func (ctx context.Context ) (string , error ) {
411+ fmt .Fprintln (os .Stdout , "Trying file" )
412+ store := credentials .NewFileStore (configFile )
413+ return getEncodedAuth (store , registryHostname )
414+ }
415+ }
416+
417+ // RegistryAuthPrivilegeFunc returns an ordered slice of [registry.RequestAuthConfig]
418+ //
419+ // The order of precedence for resolving credentials are as follows:
420+ // - Credentials stored in the environment through DOCKER_AUTH_CONFIG
421+ // - Native credentials through the credential-helper
422+ // - Filestore credentials stored in `~/.docker/config.json`
423+ func RegistryAuthPrivilegeFunc (configFile * ConfigFile , registryHostname string ) registry.RequestAuthConfig {
424+ sourceFuncs := []registry.RequestAuthConfig {
425+ envRequestAuthConfig (registryHostname ),
426+ nativeRequestAuthConfig (configFile , registryHostname ),
427+ fileRequestAuthConfig (configFile , registryHostname ),
428+ }
429+ return func (ctx context.Context ) (string , error ) {
430+ fmt .Fprintln (os .Stdout , "try funcs" )
431+ for _ , f := range sourceFuncs {
432+ if cred , err := f (ctx ); err == nil && cred != "" {
433+ return cred , nil
434+ }
435+ }
436+ return "" , nil
437+ }
438+ }
439+
363440// getConfiguredCredentialStore returns the credential helper configured for the
364441// given registry, the default credsStore, or the empty string if neither are
365442// configured.
0 commit comments