1
16
17 package credentialprovider
18
19 import (
20 "encoding/base64"
21 "encoding/json"
22 "os"
23 "path/filepath"
24 "reflect"
25 "testing"
26 )
27
28 func TestReadDockerConfigFile(t *testing.T) {
29 configJSONFileName := "config.json"
30 var fileInfo *os.File
31
32
33 inputDockerconfigJSONFile := "{ \"auths\": { \"http://foo.example.com\":{\"auth\":\"Zm9vOmJhcgo=\",\"email\":\"foo@example.com\"}}}"
34
35 preferredPath, err := os.MkdirTemp("", "test_foo_bar_dockerconfigjson_")
36 if err != nil {
37 t.Fatalf("Creating tmp dir fail: %v", err)
38 return
39 }
40 defer os.RemoveAll(preferredPath)
41 absDockerConfigFileLocation, err := filepath.Abs(filepath.Join(preferredPath, configJSONFileName))
42 if err != nil {
43 t.Fatalf("While trying to canonicalize %s: %v", preferredPath, err)
44 }
45
46 if _, err := os.Stat(absDockerConfigFileLocation); os.IsNotExist(err) {
47
48 fileInfo, err = os.OpenFile(absDockerConfigFileLocation, os.O_CREATE|os.O_RDWR, 0664)
49 if err != nil {
50 t.Fatalf("While trying to create file %s: %v", absDockerConfigFileLocation, err)
51 }
52 defer fileInfo.Close()
53 }
54
55 fileInfo.WriteString(inputDockerconfigJSONFile)
56
57 orgPreferredPath := GetPreferredDockercfgPath()
58 SetPreferredDockercfgPath(preferredPath)
59 defer SetPreferredDockercfgPath(orgPreferredPath)
60 if _, err := ReadDockerConfigFile(); err != nil {
61 t.Errorf("Getting docker config file fail : %v preferredPath : %q", err, preferredPath)
62 }
63 }
64 func TestDockerConfigJsonJSONDecode(t *testing.T) {
65
66 input := []byte(`{"auths": {"http://foo.example.com":{"username": "foo", "password": "bar", "email": "foo@example.com"}, "http://bar.example.com":{"username": "bar", "password": "baz", "email": "bar@example.com"}}}`)
67
68 expect := DockerConfigJSON{
69 Auths: DockerConfig(map[string]DockerConfigEntry{
70 "http://foo.example.com": {
71 Username: "foo",
72 Password: "bar",
73 Email: "foo@example.com",
74 },
75 "http://bar.example.com": {
76 Username: "bar",
77 Password: "baz",
78 Email: "bar@example.com",
79 },
80 }),
81 }
82
83 var output DockerConfigJSON
84 err := json.Unmarshal(input, &output)
85 if err != nil {
86 t.Errorf("Received unexpected error: %v", err)
87 }
88
89 if !reflect.DeepEqual(expect, output) {
90 t.Errorf("Received unexpected output. Expected %#v, got %#v", expect, output)
91 }
92 }
93
94 func TestDockerConfigJSONDecode(t *testing.T) {
95
96 input := []byte(`{"http://foo.example.com":{"username": "foo", "password": "bar", "email": "foo@example.com"}, "http://bar.example.com":{"username": "bar", "password": "baz", "email": "bar@example.com"}}`)
97
98 expect := DockerConfig(map[string]DockerConfigEntry{
99 "http://foo.example.com": {
100 Username: "foo",
101 Password: "bar",
102 Email: "foo@example.com",
103 },
104 "http://bar.example.com": {
105 Username: "bar",
106 Password: "baz",
107 Email: "bar@example.com",
108 },
109 })
110
111 var output DockerConfig
112 err := json.Unmarshal(input, &output)
113 if err != nil {
114 t.Errorf("Received unexpected error: %v", err)
115 }
116
117 if !reflect.DeepEqual(expect, output) {
118 t.Errorf("Received unexpected output. Expected %#v, got %#v", expect, output)
119 }
120 }
121
122 func TestDockerConfigEntryJSONDecode(t *testing.T) {
123 tests := []struct {
124 input []byte
125 expect DockerConfigEntry
126 fail bool
127 }{
128
129 {
130
131 input: []byte(`{"username": "foo", "password": "bar", "email": "foo@example.com"}`),
132 expect: DockerConfigEntry{
133 Username: "foo",
134 Password: "bar",
135 Email: "foo@example.com",
136 },
137 fail: false,
138 },
139
140
141 {
142 input: []byte(`{"auth": "Zm9vOmJhcg==", "email": "foo@example.com"}`),
143 expect: DockerConfigEntry{
144 Username: "foo",
145 Password: "bar",
146 Email: "foo@example.com",
147 },
148 fail: false,
149 },
150
151
152 {
153
154 input: []byte(`{"username": "foo", "password": "bar", "auth": "cGluZzpwb25n", "email": "foo@example.com"}`),
155 expect: DockerConfigEntry{
156 Username: "ping",
157 Password: "pong",
158 Email: "foo@example.com",
159 },
160 fail: false,
161 },
162
163
164 {
165 input: []byte(`{"auth": "pants", "email": "foo@example.com"}`),
166 expect: DockerConfigEntry{
167 Username: "",
168 Password: "",
169 Email: "foo@example.com",
170 },
171 fail: true,
172 },
173
174
175 {
176 input: []byte(`{"email": false}`),
177 expect: DockerConfigEntry{
178 Username: "",
179 Password: "",
180 Email: "",
181 },
182 fail: true,
183 },
184 }
185
186 for i, tt := range tests {
187 var output DockerConfigEntry
188 err := json.Unmarshal(tt.input, &output)
189 if (err != nil) != tt.fail {
190 t.Errorf("case %d: expected fail=%t, got err=%v", i, tt.fail, err)
191 }
192
193 if !reflect.DeepEqual(tt.expect, output) {
194 t.Errorf("case %d: expected output %#v, got %#v", i, tt.expect, output)
195 }
196 }
197 }
198
199 func TestDecodeDockerConfigFieldAuth(t *testing.T) {
200 tests := []struct {
201 input string
202 username string
203 password string
204 fail bool
205 }{
206
207 {
208 input: "Zm9vOmJhcg==",
209 username: "foo",
210 password: "bar",
211 },
212
213
214 {
215 input: "Zm9vOmJhcg",
216 username: "foo",
217 password: "bar",
218 },
219
220
221 {
222 input: "Zm9vOm\nJhcg==\n",
223 username: "foo",
224 password: "bar",
225 },
226
227
228 {
229 input: base64.StdEncoding.EncodeToString([]byte("foo:bar")),
230 username: "foo",
231 password: "bar",
232 },
233
234
235 {
236 input: base64.RawStdEncoding.EncodeToString([]byte("foo:bar")),
237 username: "foo",
238 password: "bar",
239 },
240
241
242 {
243 input: encodeDockerConfigFieldAuth("foo", "bar"),
244 username: "foo",
245 password: "bar",
246 },
247
248
249 {
250 input: "cGFudHM=",
251 fail: true,
252 },
253
254
255 {
256 input: "Zm9vOmJhcg== ",
257 fail: true,
258 },
259
260
261 {
262 input: "pants",
263 fail: true,
264 },
265 }
266
267 for i, tt := range tests {
268 username, password, err := decodeDockerConfigFieldAuth(tt.input)
269 if (err != nil) != tt.fail {
270 t.Errorf("case %d: expected fail=%t, got err=%v", i, tt.fail, err)
271 }
272
273 if tt.username != username {
274 t.Errorf("case %d: expected username %q, got %q", i, tt.username, username)
275 }
276
277 if tt.password != password {
278 t.Errorf("case %d: expected password %q, got %q", i, tt.password, password)
279 }
280 }
281 }
282
283 func TestDockerConfigEntryJSONCompatibleEncode(t *testing.T) {
284 tests := []struct {
285 input DockerConfigEntry
286 expect []byte
287 }{
288
289 {
290
291 expect: []byte(`{"username":"foo","password":"bar","email":"foo@example.com","auth":"Zm9vOmJhcg=="}`),
292 input: DockerConfigEntry{
293 Username: "foo",
294 Password: "bar",
295 Email: "foo@example.com",
296 },
297 },
298 }
299
300 for i, tt := range tests {
301 actual, err := json.Marshal(tt.input)
302 if err != nil {
303 t.Errorf("case %d: unexpected error: %v", i, err)
304 }
305
306 if string(tt.expect) != string(actual) {
307 t.Errorf("case %d: expected %v, got %v", i, string(tt.expect), string(actual))
308 }
309 }
310 }
311
312 func TestReadDockerConfigFileFromBytes(t *testing.T) {
313 testCases := []struct {
314 id string
315 input []byte
316 expectedCfg DockerConfig
317 errorExpected bool
318 expectedErrorMsg string
319 }{
320 {
321 id: "valid input, no error expected",
322 input: []byte(`{"http://foo.example.com":{"username": "foo", "password": "bar", "email": "foo@example.com"}}`),
323 expectedCfg: DockerConfig(map[string]DockerConfigEntry{
324 "http://foo.example.com": {
325 Username: "foo",
326 Password: "bar",
327 Email: "foo@example.com",
328 },
329 }),
330 },
331 {
332 id: "invalid input, error expected",
333 input: []byte(`{"http://foo.example.com":{"username": "foo", "password": "bar", "email": "foo@example.com"`),
334 errorExpected: true,
335 expectedErrorMsg: "error occurred while trying to unmarshal json",
336 },
337 }
338
339 for _, tc := range testCases {
340 cfg, err := ReadDockerConfigFileFromBytes(tc.input)
341 if err != nil && !tc.errorExpected {
342 t.Fatalf("Error was not expected: %v", err)
343 }
344 if err != nil && tc.errorExpected {
345 if !reflect.DeepEqual(err.Error(), tc.expectedErrorMsg) {
346 t.Fatalf("Expected error message: `%s` got `%s`", tc.expectedErrorMsg, err.Error())
347 }
348 } else {
349 if !reflect.DeepEqual(cfg, tc.expectedCfg) {
350 t.Fatalf("expected: %v got %v", tc.expectedCfg, cfg)
351 }
352 }
353 }
354 }
355
356 func TestReadDockerConfigJSONFileFromBytes(t *testing.T) {
357 testCases := []struct {
358 id string
359 input []byte
360 expectedCfg DockerConfig
361 errorExpected bool
362 expectedErrorMsg string
363 }{
364 {
365 id: "valid input, no error expected",
366 input: []byte(`{"auths": {"http://foo.example.com":{"username": "foo", "password": "bar", "email": "foo@example.com"}, "http://bar.example.com":{"username": "bar", "password": "baz", "email": "bar@example.com"}}}`),
367 expectedCfg: DockerConfig(map[string]DockerConfigEntry{
368 "http://foo.example.com": {
369 Username: "foo",
370 Password: "bar",
371 Email: "foo@example.com",
372 },
373 "http://bar.example.com": {
374 Username: "bar",
375 Password: "baz",
376 Email: "bar@example.com",
377 },
378 }),
379 },
380 {
381 id: "invalid input, error expected",
382 input: []byte(`{"auths": {"http://foo.example.com":{"username": "foo", "password": "bar", "email": "foo@example.com"}, "http://bar.example.com":{"username": "bar", "password": "baz", "email": "bar@example.com"`),
383 errorExpected: true,
384 expectedErrorMsg: "error occurred while trying to unmarshal json",
385 },
386 }
387
388 for _, tc := range testCases {
389 cfg, err := readDockerConfigJSONFileFromBytes(tc.input)
390 if err != nil && !tc.errorExpected {
391 t.Fatalf("Error was not expected: %v", err)
392 }
393 if err != nil && tc.errorExpected {
394 if !reflect.DeepEqual(err.Error(), tc.expectedErrorMsg) {
395 t.Fatalf("Expected error message: `%s` got `%s`", tc.expectedErrorMsg, err.Error())
396 }
397 } else {
398 if !reflect.DeepEqual(cfg, tc.expectedCfg) {
399 t.Fatalf("expected: %v got %v", tc.expectedCfg, cfg)
400 }
401 }
402 }
403 }
404
View as plain text