Skip to content

Commit 9d6cddd

Browse files
authored
Merge pull request docker#364 from akerouanton/fix-regression-v0.9.0
osxkeychain: list: return full server URIs
2 parents 833d2c3 + d8e34f8 commit 9d6cddd

File tree

2 files changed

+84
-14
lines changed

2 files changed

+84
-14
lines changed

osxkeychain/osxkeychain.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import "C"
1212

1313
import (
1414
"errors"
15+
"net"
16+
"net/url"
1517
"strconv"
1618

1719
"github.com/docker/docker-credential-helpers/credentials"
@@ -121,10 +123,20 @@ func (h Osxkeychain) List() (map[string]string, error) {
121123

122124
resp := make(map[string]string)
123125
for _, r := range res {
124-
if r.Path == "" {
125-
continue
126+
proto := "http"
127+
if r.Protocol == kSecProtocolTypeHTTPS {
128+
proto = "https"
126129
}
127-
resp[r.Path] = r.Account
130+
host := r.Server
131+
if r.Port != 0 {
132+
host = net.JoinHostPort(host, strconv.Itoa(int(r.Port)))
133+
}
134+
u := url.URL{
135+
Scheme: proto,
136+
Host: host,
137+
Path: r.Path,
138+
}
139+
resp[u.String()] = r.Account
128140
}
129141
return resp, nil
130142
}

osxkeychain/osxkeychain_test.go

Lines changed: 69 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,6 @@ func TestOSXKeychainHelper(t *testing.T) {
1515
Username: "foobar",
1616
Secret: "foobarbaz",
1717
}
18-
creds1 := &credentials.Credentials{
19-
ServerURL: "https://foobar.example.com:2376/v2",
20-
Username: "foobarbaz",
21-
Secret: "foobar",
22-
}
2318
helper := Osxkeychain{}
2419
if err := helper.Add(creds); err != nil {
2520
t.Fatal(err)
@@ -43,19 +38,49 @@ func TestOSXKeychainHelper(t *testing.T) {
4338
t.Fatal(err)
4439
}
4540

41+
if _, ok := auths[creds.ServerURL]; !ok {
42+
t.Fatalf("server %s not found in list, got: %+v", creds.ServerURL, auths)
43+
}
44+
45+
// Insert another token and check if it is in the list
46+
creds1 := &credentials.Credentials{
47+
ServerURL: "https://foobar.example.com:2376/v2",
48+
Username: "foobarbaz",
49+
Secret: "foobar",
50+
}
4651
helper.Add(creds1)
4752
defer helper.Delete(creds1.ServerURL)
48-
newauths, err := helper.List()
49-
if len(newauths)-len(auths) != 1 {
50-
if err == nil {
51-
t.Fatalf("Error: len(newauths): %d, len(auths): %d", len(newauths), len(auths))
52-
}
53-
t.Fatalf("Error: len(newauths): %d, len(auths): %d\n Error= %v", len(newauths), len(auths), err)
53+
54+
auths, err = helper.List()
55+
if err != nil {
56+
t.Fatalf("operation List failed: %+v", err)
57+
}
58+
59+
if _, ok := auths[creds.ServerURL]; !ok {
60+
t.Fatalf("server %s not found in list, got: %+v", creds.ServerURL, auths)
61+
}
62+
if _, ok := auths[creds1.ServerURL]; !ok {
63+
t.Fatalf("server %s not found in list, got: %+v", creds1.ServerURL, auths)
5464
}
5565

66+
// Delete the 1st token inserted
5667
if err := helper.Delete(creds.ServerURL); err != nil {
5768
t.Fatal(err)
5869
}
70+
71+
auths, err = helper.List()
72+
if err != nil {
73+
t.Fatalf("operation List failed: %+v", err)
74+
}
75+
76+
// First token should have been deleted
77+
if _, ok := auths[creds.ServerURL]; ok {
78+
t.Fatalf("server %s was not deleted, got: %+v", creds.ServerURL, auths)
79+
}
80+
// Second token should still be there
81+
if _, ok := auths[creds1.ServerURL]; !ok {
82+
t.Fatalf("server %s not found in list, got: %+v", creds1.ServerURL, auths)
83+
}
5984
}
6085

6186
// TestOSXKeychainHelperRetrieveAliases verifies that secrets can be accessed
@@ -116,6 +141,39 @@ func TestOSXKeychainHelperRetrieveAliases(t *testing.T) {
116141
}
117142
}
118143

144+
func TestOSXKeychainHelperStoreWithUncleanPath(t *testing.T) {
145+
helper := Osxkeychain{}
146+
creds := &credentials.Credentials{
147+
ServerURL: "https://::1:8080//////location/../../hello",
148+
Username: "testuser",
149+
Secret: "testsecret",
150+
}
151+
152+
// Clean store before and after the test.
153+
defer helper.Delete(creds.ServerURL)
154+
if err := helper.Delete(creds.ServerURL); err != nil && !credentials.IsErrCredentialsNotFound(err) {
155+
t.Errorf("prepare: failed to delete '%s': %v", creds.ServerURL, err)
156+
}
157+
158+
// Store the credentials
159+
if err := helper.Add(creds); err != nil {
160+
t.Fatalf("Error: failed to store credentials with unclean path %q: %s", creds.ServerURL, err)
161+
}
162+
163+
// Retrieve and verify credentials
164+
username, secret, err := helper.Get(creds.ServerURL)
165+
if err != nil {
166+
t.Fatalf("Error: failed to retrieve credentials with unclean path %q: %s", creds.ServerURL, err)
167+
}
168+
169+
if username != creds.Username {
170+
t.Errorf("Error: expected username %s, got %s", creds.Username, username)
171+
}
172+
if secret != creds.Secret {
173+
t.Errorf("Error: expected secret %s, got %s", creds.Secret, secret)
174+
}
175+
}
176+
119177
// TestOSXKeychainHelperRetrieveStrict verifies that only matching secrets are
120178
// returned.
121179
func TestOSXKeychainHelperRetrieveStrict(t *testing.T) {

0 commit comments

Comments
 (0)