Skip to content

Commit 9408bfb

Browse files
committed
[image-builder-bob] Tests&fixes from an experimental PR
Tool: gitpod/catfood.gitpod.cloud
1 parent ddc6f3c commit 9408bfb

File tree

3 files changed

+146
-4
lines changed

3 files changed

+146
-4
lines changed

components/image-builder-bob/cmd/proxy.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ var proxyCmd = &cobra.Command{
3737
}
3838
authA, err := proxy.NewAuthorizerFromEnvVar(proxyOpts.AdditionalAuth)
3939
if err != nil {
40-
log.WithError(err).WithField("auth", proxyOpts.Auth).Fatal("cannot unmarshal auth")
40+
log.WithError(err).WithField("additionalAuth", proxyOpts.AdditionalAuth).Fatal("cannot unmarshal additionalAuth")
4141
}
4242
authP = authP.AddIfNotExists(authA)
4343

components/image-builder-bob/pkg/proxy/auth.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ func (a MapAuthorizer) Authorize(host string) (user, pass string, err error) {
5252
}).Info("authorizing registry access")
5353
}()
5454

55+
// Strip any port from the host if present
56+
host = strings.Split(host, ":")[0]
57+
5558
explicitHostMatcher := func() (authConfig, bool) {
5659
res, ok := a[host]
5760
return res, ok
@@ -86,12 +89,13 @@ func (a MapAuthorizer) Authorize(host string) (user, pass string, err error) {
8689

8790
user, pass = res.Username, res.Password
8891
if res.Auth != "" {
89-
var auth []byte
90-
auth, err = base64.StdEncoding.DecodeString(res.Auth)
92+
var authBytes []byte
93+
authBytes, err = base64.StdEncoding.DecodeString(res.Auth)
9194
if err != nil {
9295
return
9396
}
94-
segs := strings.Split(string(auth), ":")
97+
auth := strings.TrimSpace(string(authBytes))
98+
segs := strings.Split(auth, ":")
9599
if len(segs) < 2 {
96100
return
97101
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
// Copyright (c) 2025 Gitpod GmbH. All rights reserved.
2+
// Licensed under the GNU Affero General Public License (AGPL).
3+
// See License.AGPL.txt in the project root for license information.
4+
5+
package proxy
6+
7+
import (
8+
"testing"
9+
)
10+
11+
func TestAuthorize(t *testing.T) {
12+
type expectation struct {
13+
user string
14+
pass string
15+
err string
16+
}
17+
tests := []struct {
18+
name string
19+
constructor func(string) (MapAuthorizer, error)
20+
input string
21+
testHost string
22+
expected expectation
23+
}{
24+
{
25+
name: "docker auth format - valid credentials",
26+
constructor: NewAuthorizerFromDockerEnvVar,
27+
input: `{"auths": {"registry.example.com": {"auth": "dXNlcjpwYXNz"}}}`, // base64(user:pass)
28+
testHost: "registry.example.com",
29+
expected: expectation{
30+
user: "user",
31+
pass: "pass",
32+
},
33+
},
34+
{
35+
name: "docker auth format - valid credentials - host with port",
36+
constructor: NewAuthorizerFromDockerEnvVar,
37+
input: `{"auths": {"registry.example.com": {"auth": "dXNlcjpwYXNz"}}}`, // base64(user:pass)
38+
testHost: "registry.example.com:443",
39+
expected: expectation{
40+
user: "user",
41+
pass: "pass",
42+
},
43+
},
44+
{
45+
name: "docker auth format - invalid host",
46+
constructor: NewAuthorizerFromDockerEnvVar,
47+
input: `{"auths": {"registry.example.com": {"auth": "dXNlcjpwYXNz"}}}`,
48+
testHost: "wrong.registry.com",
49+
expected: expectation{
50+
user: "",
51+
pass: "",
52+
},
53+
},
54+
{
55+
name: "env var format - valid credentials",
56+
constructor: NewAuthorizerFromEnvVar,
57+
input: `{"registry.example.com": {"auth": "dXNlcjpwYXNz"}}`,
58+
testHost: "registry.example.com",
59+
expected: expectation{
60+
user: "user",
61+
pass: "pass",
62+
},
63+
},
64+
{
65+
name: "env var format - empty input",
66+
constructor: NewAuthorizerFromEnvVar,
67+
input: "",
68+
testHost: "registry.example.com",
69+
expected: expectation{
70+
user: "",
71+
pass: "",
72+
},
73+
},
74+
{
75+
name: "gitpod format - valid credentials",
76+
constructor: NewAuthorizerFromEnvVar,
77+
input: `{"registry.example.com": {"auth": "dXNlcjpwYXNz"}}`,
78+
testHost: "registry.example.com",
79+
expected: expectation{
80+
user: "user",
81+
pass: "pass",
82+
},
83+
},
84+
{
85+
name: "gitpod format - multiple hosts",
86+
constructor: NewAuthorizerFromEnvVar,
87+
input: `{"registry1.example.com": {"auth": "dXNlcjE6cGFzczEK"}, "registry2.example.com": {"auth": "dXNlcjI6cGFzczIK"}}`,
88+
testHost: "registry2.example.com",
89+
expected: expectation{
90+
user: "user2",
91+
pass: "pass2",
92+
},
93+
},
94+
{
95+
name: "gitpod format - invalid format",
96+
constructor: NewAuthorizerFromEnvVar,
97+
input: "invalid:format:with:toomany:colons",
98+
testHost: "registry.example.com",
99+
expected: expectation{
100+
err: "invalid character 'i' looking for beginning of value",
101+
},
102+
},
103+
{
104+
name: "gitpod format - empty input",
105+
constructor: NewAuthorizerFromEnvVar,
106+
input: "",
107+
testHost: "registry.example.com",
108+
expected: expectation{
109+
user: "",
110+
pass: "",
111+
},
112+
},
113+
}
114+
115+
for _, tt := range tests {
116+
t.Run(tt.name, func(t *testing.T) {
117+
auth, err := tt.constructor(tt.input)
118+
if err != nil {
119+
if tt.expected.err == "" {
120+
t.Errorf("Constructor failed: %s", err)
121+
}
122+
return
123+
}
124+
125+
actualUser, actualPassword, err := auth.Authorize(tt.testHost)
126+
if (err != nil) != (tt.expected.err != "") {
127+
t.Errorf("Authorize() error = %v, wantErr %v", err, tt.expected.err)
128+
return
129+
}
130+
if actualUser != tt.expected.user {
131+
t.Errorf("Authorize() actual user = %v, want %v", actualUser, tt.expected.user)
132+
}
133+
if actualPassword != tt.expected.pass {
134+
t.Errorf("Authorize() actual password = %v, want %v", actualPassword, tt.expected.pass)
135+
}
136+
})
137+
}
138+
}

0 commit comments

Comments
 (0)