@@ -42,9 +42,9 @@ type Store interface {
42
42
Delete (ctx context.Context , serverAddress string ) error
43
43
}
44
44
45
- // dynamicStore dynamically determines which store to use based on the settings
45
+ // DynamicStore dynamically determines which store to use based on the settings
46
46
// in the config file.
47
- type dynamicStore struct {
47
+ type DynamicStore struct {
48
48
config * config.Config
49
49
options StoreOptions
50
50
detectedCredsStore string
@@ -60,36 +60,45 @@ type StoreOptions struct {
60
60
// - If AllowPlaintextPut is set to true, Put() will save credentials in
61
61
// plaintext in the config file when native store is not available.
62
62
AllowPlaintextPut bool
63
+
64
+ // DetectDefaultCredsStore enables detecting the platform-default
65
+ // credentials store when the config file has no authentication information.
66
+ //
67
+ // If DetectDefaultCredsStore is set to true, the store will detect and set
68
+ // the default credentials store in the "credsStore" field of the config
69
+ // file.
70
+ // - Windows: "wincred"
71
+ // - Linux: "pass" or "secretservice"
72
+ // - macOS: "osxkeychain"
73
+ //
74
+ // References:
75
+ // - https://docs.docker.com/engine/reference/commandline/login/#credentials-store
76
+ // - https://docs.docker.com/engine/reference/commandline/cli/#docker-cli-configuration-file-configjson-properties
77
+ DetectDefaultCredsStore bool
63
78
}
64
79
65
80
// NewStore returns a Store based on the given configuration file.
66
81
//
67
- // For Get(), Put() and Delete(), the returned Store will dynamically determine which underlying credentials
68
- // store to use for the given server address.
82
+ // For Get(), Put() and Delete(), the returned Store will dynamically determine
83
+ // which underlying credentials store to use for the given server address.
69
84
// The underlying credentials store is determined in the following order:
70
85
// 1. Native server-specific credential helper
71
86
// 2. Native credentials store
72
87
// 3. The plain-text config file itself
73
88
//
74
- // If the config file has no authentication information, a platform-default
75
- // native store will be used.
76
- // - Windows: "wincred"
77
- // - Linux: "pass" or "secretservice"
78
- // - macOS: "osxkeychain"
79
- //
80
89
// References:
81
90
// - https://docs.docker.com/engine/reference/commandline/login/#credentials-store
82
91
// - https://docs.docker.com/engine/reference/commandline/cli/#docker-cli-configuration-file-configjson-properties
83
- func NewStore (configPath string , opts StoreOptions ) (Store , error ) {
92
+ func NewStore (configPath string , opts StoreOptions ) (* DynamicStore , error ) {
84
93
cfg , err := config .Load (configPath )
85
94
if err != nil {
86
95
return nil , err
87
96
}
88
- ds := & dynamicStore {
97
+ ds := & DynamicStore {
89
98
config : cfg ,
90
99
options : opts ,
91
100
}
92
- if ! cfg .IsAuthConfigured () {
101
+ if opts . DetectDefaultCredsStore && ! cfg .IsAuthConfigured () {
93
102
// no authentication configured, detect the default credentials store
94
103
ds .detectedCredsStore = getDefaultHelperSuffix ()
95
104
}
@@ -106,7 +115,7 @@ func NewStore(configPath string, opts StoreOptions) (Store, error) {
106
115
// References:
107
116
// - https://docs.docker.com/engine/reference/commandline/cli/#configuration-files
108
117
// - https://docs.docker.com/engine/reference/commandline/cli/#change-the-docker-directory
109
- func NewStoreFromDocker (opt StoreOptions ) (Store , error ) {
118
+ func NewStoreFromDocker (opt StoreOptions ) (* DynamicStore , error ) {
110
119
configPath , err := getDockerConfigPath ()
111
120
if err != nil {
112
121
return nil , err
@@ -115,14 +124,14 @@ func NewStoreFromDocker(opt StoreOptions) (Store, error) {
115
124
}
116
125
117
126
// Get retrieves credentials from the store for the given server address.
118
- func (ds * dynamicStore ) Get (ctx context.Context , serverAddress string ) (auth.Credential , error ) {
127
+ func (ds * DynamicStore ) Get (ctx context.Context , serverAddress string ) (auth.Credential , error ) {
119
128
return ds .getStore (serverAddress ).Get (ctx , serverAddress )
120
129
}
121
130
122
131
// Put saves credentials into the store for the given server address.
123
- // Returns ErrPlaintextPutDisabled if native store is not available and
124
- // StoreOptions.AllowPlaintextPut is set to false.
125
- func (ds * dynamicStore ) Put (ctx context.Context , serverAddress string , cred auth.Credential ) (returnErr error ) {
132
+ // Put returns ErrPlaintextPutDisabled if native store is not available and
133
+ // [ StoreOptions] .AllowPlaintextPut is set to false.
134
+ func (ds * DynamicStore ) Put (ctx context.Context , serverAddress string , cred auth.Credential ) (returnErr error ) {
126
135
if err := ds .getStore (serverAddress ).Put (ctx , serverAddress , cred ); err != nil {
127
136
return err
128
137
}
@@ -138,13 +147,24 @@ func (ds *dynamicStore) Put(ctx context.Context, serverAddress string, cred auth
138
147
}
139
148
140
149
// Delete removes credentials from the store for the given server address.
141
- func (ds * dynamicStore ) Delete (ctx context.Context , serverAddress string ) error {
150
+ func (ds * DynamicStore ) Delete (ctx context.Context , serverAddress string ) error {
142
151
return ds .getStore (serverAddress ).Delete (ctx , serverAddress )
143
152
}
144
153
154
+ // IsAuthConfigured returns whether there is authentication configured in the
155
+ // config file or not.
156
+ //
157
+ // IsAuthConfigured returns true when:
158
+ // - The "credsStore" field is not empty
159
+ // - Or the "credHelpers" field is not empty
160
+ // - Or there is any entry in the "auths" field
161
+ func (ds * DynamicStore ) IsAuthConfigured () bool {
162
+ return ds .config .IsAuthConfigured ()
163
+ }
164
+
145
165
// getHelperSuffix returns the credential helper suffix for the given server
146
166
// address.
147
- func (ds * dynamicStore ) getHelperSuffix (serverAddress string ) string {
167
+ func (ds * DynamicStore ) getHelperSuffix (serverAddress string ) string {
148
168
// 1. Look for a server-specific credential helper first
149
169
if helper := ds .config .GetCredentialHelper (serverAddress ); helper != "" {
150
170
return helper
@@ -158,7 +178,7 @@ func (ds *dynamicStore) getHelperSuffix(serverAddress string) string {
158
178
}
159
179
160
180
// getStore returns a store for the given server address.
161
- func (ds * dynamicStore ) getStore (serverAddress string ) Store {
181
+ func (ds * DynamicStore ) getStore (serverAddress string ) Store {
162
182
if helper := ds .getHelperSuffix (serverAddress ); helper != "" {
163
183
return NewNativeStore (helper )
164
184
}
0 commit comments