Skip to content

Commit fe640fd

Browse files
committed
pass: base64 encoded username with backward compatility
Signed-off-by: CrazyMax <[email protected]>
1 parent 2078996 commit fe640fd

File tree

2 files changed

+79
-26
lines changed

2 files changed

+79
-26
lines changed

pass/pass.go

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,9 @@ func (p Pass) Add(creds *credentials.Credentials) error {
8989
return errors.New("missing credentials")
9090
}
9191

92-
encoded := base64.URLEncoding.EncodeToString([]byte(creds.ServerURL))
93-
94-
username := creds.Username
95-
if strings.Contains(username, "/") {
96-
username = base64.URLEncoding.EncodeToString([]byte(creds.Username))
97-
}
98-
99-
_, err := p.runPass(creds.Secret, "insert", "-f", "-m", path.Join(PASS_FOLDER, encoded, username))
92+
encodedServerURL := base64.URLEncoding.EncodeToString([]byte(creds.ServerURL))
93+
encodedUsername := base64.URLEncoding.EncodeToString([]byte(creds.Username))
94+
_, err := p.runPass(creds.Secret, "insert", "-f", "-m", path.Join(PASS_FOLDER, encodedServerURL, encodedUsername))
10095
return err
10196
}
10297

@@ -106,8 +101,8 @@ func (p Pass) Delete(serverURL string) error {
106101
return errors.New("missing server url")
107102
}
108103

109-
encoded := base64.URLEncoding.EncodeToString([]byte(serverURL))
110-
_, err := p.runPass("", "rm", "-rf", path.Join(PASS_FOLDER, encoded))
104+
encodedServerURL := base64.URLEncoding.EncodeToString([]byte(serverURL))
105+
_, err := p.runPass("", "rm", "-rf", path.Join(PASS_FOLDER, encodedServerURL))
111106
return err
112107
}
113108

@@ -149,17 +144,16 @@ func (p Pass) Get(serverURL string) (string, string, error) {
149144
return "", "", errors.New("missing server url")
150145
}
151146

152-
encoded := base64.URLEncoding.EncodeToString([]byte(serverURL))
153-
154-
if _, err := os.Stat(path.Join(getPassDir(), PASS_FOLDER, encoded)); err != nil {
147+
encodedServerURL := base64.URLEncoding.EncodeToString([]byte(serverURL))
148+
if _, err := os.Stat(path.Join(getPassDir(), PASS_FOLDER, encodedServerURL)); err != nil {
155149
if os.IsNotExist(err) {
156150
return "", "", credentials.NewErrCredentialsNotFound()
157151
}
158152

159153
return "", "", err
160154
}
161155

162-
usernames, err := listPassDir(encoded)
156+
usernames, err := listPassDir(encodedServerURL)
163157
if err != nil {
164158
return "", "", err
165159
}
@@ -170,11 +164,10 @@ func (p Pass) Get(serverURL string) (string, string, error) {
170164

171165
actual := strings.TrimSuffix(usernames[0].Name(), ".gpg")
172166
username := actual
173-
decodedUsername, err := base64.URLEncoding.DecodeString(actual)
174-
if err == nil {
167+
if decodedUsername, err := base64.URLEncoding.DecodeString(actual); err == nil {
175168
username = string(decodedUsername)
176169
}
177-
secret, err := p.runPass("", "show", path.Join(PASS_FOLDER, encoded, actual))
170+
secret, err := p.runPass("", "show", path.Join(PASS_FOLDER, encodedServerURL, actual))
178171
return username, secret, err
179172
}
180173

@@ -206,9 +199,9 @@ func (p Pass) List() (map[string]string, error) {
206199
return nil, fmt.Errorf("no usernames for %s", serverURL)
207200
}
208201

209-
resp[string(serverURL)] = strings.TrimSuffix(usernames[0].Name(), ".gpg")
210-
decodedUsername, err := base64.URLEncoding.DecodeString(strings.TrimSuffix(usernames[0].Name(), ".gpg"))
211-
if err == nil {
202+
username := strings.TrimSuffix(usernames[0].Name(), ".gpg")
203+
resp[string(serverURL)] = username
204+
if decodedUsername, err := base64.URLEncoding.DecodeString(username); err == nil {
212205
resp[string(serverURL)] = string(decodedUsername)
213206
}
214207
}

pass/pass_test.go

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,67 @@
44
package pass
55

66
import (
7+
"encoding/base64"
8+
"path"
79
"strings"
810
"testing"
911

1012
"github.com/docker/docker-credential-helpers/credentials"
1113
)
1214

1315
func TestPassHelper(t *testing.T) {
16+
tests := []struct {
17+
name string
18+
creds *credentials.Credentials
19+
}{
20+
{
21+
name: "create nothing",
22+
creds: &credentials.Credentials{
23+
ServerURL: "https://foobar.docker.io:2376/v1",
24+
Username: "nothing",
25+
Secret: "isthebestmeshuggahalbum",
26+
},
27+
},
28+
{
29+
name: "create foo/bar",
30+
creds: &credentials.Credentials{
31+
ServerURL: "https://foobar.docker.io:2376/v1",
32+
Username: "foo/bar",
33+
Secret: "foobarbaz",
34+
},
35+
},
36+
}
37+
38+
helper := Pass{}
39+
_ = helper.CheckInitialized()
40+
41+
for _, tc := range tests {
42+
tc := tc
43+
t.Run(tc.name, func(t *testing.T) {
44+
if err := helper.Add(tc.creds); err != nil {
45+
t.Error(err)
46+
}
47+
u, s, err := helper.Get(tc.creds.ServerURL)
48+
if err != nil {
49+
t.Error(err)
50+
}
51+
if u != tc.creds.Username {
52+
t.Errorf("invalid username %s", u)
53+
}
54+
if s != tc.creds.Secret {
55+
t.Errorf("invalid secret: %s", s)
56+
}
57+
if err = helper.Delete(tc.creds.ServerURL); err != nil {
58+
t.Error(err)
59+
}
60+
if _, _, err = helper.Get(tc.creds.ServerURL); !credentials.IsErrCredentialsNotFound(err) {
61+
t.Errorf("expected credentials not found, actual: %v", err)
62+
}
63+
})
64+
}
65+
}
66+
67+
func TestPassHelperBackwardCompat(t *testing.T) {
1468
creds := &credentials.Credentials{
1569
ServerURL: "https://foobar.docker.io:2376/v1",
1670
Username: "nothing",
@@ -20,26 +74,32 @@ func TestPassHelper(t *testing.T) {
2074
helper := Pass{}
2175
_ = helper.CheckInitialized()
2276

77+
// add a credential with the old format
78+
encodedServerURL := base64.URLEncoding.EncodeToString([]byte(creds.ServerURL))
79+
if _, err := helper.runPass(creds.Secret, "insert", "-f", "-m", path.Join(PASS_FOLDER, encodedServerURL, creds.Username)); err != nil {
80+
t.Error(err)
81+
}
82+
2383
if err := helper.Add(creds); err != nil {
24-
t.Fatal(err)
84+
t.Error(err)
2585
}
2686

2787
u, s, err := helper.Get(creds.ServerURL)
2888
if err != nil {
29-
t.Fatal(err)
89+
t.Error(err)
3090
}
3191
if u != creds.Username {
32-
t.Fatalf("invalid username %s", u)
92+
t.Errorf("invalid username %s", u)
3393
}
3494
if s != creds.Secret {
35-
t.Fatalf("invalid secret: %s", s)
95+
t.Errorf("invalid secret: %s", s)
3696
}
3797

3898
if err = helper.Delete(creds.ServerURL); err != nil {
39-
t.Fatal(err)
99+
t.Error(err)
40100
}
41101
if _, _, err = helper.Get(creds.ServerURL); !credentials.IsErrCredentialsNotFound(err) {
42-
t.Fatalf("expected credentials not found, actual: %v", err)
102+
t.Errorf("expected credentials not found, actual: %v", err)
43103
}
44104
}
45105

0 commit comments

Comments
 (0)