Skip to content

Commit 21aa7af

Browse files
committed
Merge remote-tracking branch 'upstream/main' into test/crl_e2e
Signed-off-by: Junjie Gao <[email protected]>
2 parents 3d8fb76 + 83c6c89 commit 21aa7af

File tree

20 files changed

+361
-42
lines changed

20 files changed

+361
-42
lines changed

.github/.codecov.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,7 @@ coverage:
1515
status:
1616
project:
1717
default:
18-
target: 70%
18+
target: 70%
19+
patch:
20+
default:
21+
target: 80%

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,6 @@ jobs:
5959
make e2e-covdata
6060
fi
6161
- name: Upload coverage to codecov.io
62-
uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0
62+
uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0
6363
env:
6464
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIEizCCAvOgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJVUzEL
3+
MAkGA1UECBMCV0ExEDAOBgNVBAcTB1NlYXR0bGUxDzANBgNVBAoTBk5vdGFyeTEb
4+
MBkGA1UEAxMSTm90YXRpb24gVGVzdCBSb290MCAXDTIwMDkwOTA3MDAwMFoYDzIx
5+
MjIwOTA1MjAzODQ1WjBaMQswCQYDVQQGEwJVUzELMAkGA1UECBMCV0ExEDAOBgNV
6+
BAcTB1NlYXR0bGUxDzANBgNVBAoTBk5vdGFyeTEbMBkGA1UEAxMSTm90YXRpb24g
7+
VGVzdCBSb290MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAxxAZ8VZe
8+
gqBUctz3BkwhObZKnW+KsN5/N1/u2vPLmEzHDj6xgd8Hn0JoughDaxeQCV66NC2o
9+
bqPnPp4+68G/qZnxkXVXdFyqVodu4FgPUjiqcJjft7bh45BVgLFpOqSqDQ3ko30B
10+
7gdGfIIkoBj/8gz3tHnmIvl3MywtOhDeGnlLNzBY52wVmhPIdKOaW/7WkMrXKFCk
11+
LkNICGnIpWuyBtC+7RfM8hG6eRW1KCm5xrkRmn5ptonjxix/JTGj4me/NMkwdVkz
12+
6wcCSAJnqTgHi2oqk73qqNu0LHsEMFBF8IGqmVkn2MOHkFamPBokzQ6HXXfvR4nb
13+
cWQZCUgRinPTVg9CF0B6XSCEMCSH5kveZxTQtAFRB6NosbzuU5jDmJgpbDfauev7
14+
Eg/6bZzphcugRkVuwulymzsake5Jbvs9Kyw3CNPYH2G3Kli1FNhfc46ugXHbIfXg
15+
NQcou3xabcu+r6cFRqqK6NmV9ouMQRj8Ri95Gp2BUlpTEFhcvMb9d4nXAgMBAAGj
16+
WjBYMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDAzASBgNVHRMB
17+
Af8ECDAGAQH/AgEBMB0GA1UdDgQWBBS5FZjt9UsEPkcKrStrnjSpTq4kDTANBgkq
18+
hkiG9w0BAQsFAAOCAYEAKtxfv12LzM85bxOMp5++pIDa6eMcBaurYbAM2yC9B6Lu
19+
Hf0JGeFdNqt4Fw38Ajooj2vWMWBrARVEZRVqTC5+ZSN2meGBXBXlT4n8FdEdmv+0
20+
5iwVYdmDFp8FKeoOZZZF23u+r2OrazJo1ufWmoSI2P0lEfZQQFQElltWu3QH+OLO
21+
WXJmB7KbLKyheelGK5XhtAYYapRdW4sKJ398ybpv5C1oALCcTwoSmvH8wW5J4/gj
22+
mhKICYh2goMauf0lesdxj+0His7E8blOWrUmfOB5dp73XawLKcd/UxHN8zAPC08L
23+
DL9NMcihn3ZHKi7/dtkiV2iSaDPD1ChSGdqfXIysYqOhYoktgAfBZ43CWnqQhgB8
24+
NezRKdOStYC3P2AGJW18irxxTRp2CO+gnXEcyhyr+cvyf0j8MkRSaHLXzjIrECu8
25+
BUitB6sKughdN13fs5t5SIiO6foeFdvIpZFFKO8s+4oTOSDCos2WFoC+8TZS6r58
26+
3OtFLmywl1HRgQkobGgw
27+
-----END CERTIFICATE-----
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
invalid test cert
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDPjCCAiagAwIBAgIBeTANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzEL
3+
MAkGA1UECBMCV0ExEDAOBgNVBAcTB1NlYXR0bGUxDzANBgNVBAoTBk5vdGFyeTEP
4+
MA0GA1UEAxMGYWxwaW5lMB4XDTIzMDUwOTA0NTUxMloXDTMzMDUxMDA0NTUxMlow
5+
TjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMQ8w
6+
DQYDVQQKEwZOb3RhcnkxDzANBgNVBAMTBmFscGluZTCCASIwDQYJKoZIhvcNAQEB
7+
BQADggEPADCCAQoCggEBAK5hpq1229GGLjMK6i9KZhuUO+SV7rUFnWIDiIPO5yWx
8+
YDkl+bGroeAvJYu6MVCMQ6FMRXD9jhnG6R+sAHwY7gVgcJ1OXak87PkLp/Ii1Cr7
9+
XkkySZeD+Br1vSQzfxs3pFG+iBCeVVkeZdsg+xqwnAlqAILXwIbTGRyJP1Xiu9nw
10+
OeuX1YmxPl2m29Pt1EtfVCL9COsVKt5LgOVyWP/9ISWevOBqSCU9bk35HFo9VTeU
11+
f6+ffhSMjv0Y9uwkFFOKXpcV8Sa3ArqyBmgQlUfGg1iwYlqiDE0fTYxiB3gLgETA
12+
lmTm50J+WB9LoDrnrQpbXFLoegm+JV+uSD8J8H7DL2sCAwEAAaMnMCUwDgYDVR0P
13+
AQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBCwUAA4IB
14+
AQAt0Nvna1c4pPn8kzoN5VvmFmeIgdO/BJpmdhdg0WIQ9aeN/xPXXaVjPp1Mk7ed
15+
XHAvBwQr0Gyzqyy7g/h0gdnAFG7f6blrRNzbrRBCq6cNqX8iwgK/9+2OYKxk1QWj
16+
8Gx0cvu1DN1aXjPPGgQ2j3tHjJvJv32J/zuZa8gU40RPPSLaBlc5ZjpFmyi29sKl
17+
TeeZ+F/Ssic51qXXw2CsYGGWK5yQ3xSCxbw6bb2G/s/YI7/KlWg9BktBJHzRu04Z
18+
NR77W7/dyJ3Lj17PlW1XKmMOFHsQivagXeRCbmYZ43fX4ugFRFKL7KE0EgmGOWpJ
19+
0xv+6ig93sqHzQ/0uv1YgFov
20+
-----END CERTIFICATE-----
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDPjCCAiagAwIBAgIBeTANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzEL
3+
MAkGA1UECBMCV0ExEDAOBgNVBAcTB1NlYXR0bGUxDzANBgNVBAoTBk5vdGFyeTEP
4+
MA0GA1UEAxMGYWxwaW5lMB4XDTIzMDUwOTA0NTUxMloXDTMzMDUxMDA0NTUxMlow
5+
TjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMQ8w
6+
DQYDVQQKEwZOb3RhcnkxDzANBgNVBAMTBmFscGluZTCCASIwDQYJKoZIhvcNAQEB
7+
BQADggEPADCCAQoCggEBAK5hpq1229GGLjMK6i9KZhuUO+SV7rUFnWIDiIPO5yWx
8+
YDkl+bGroeAvJYu6MVCMQ6FMRXD9jhnG6R+sAHwY7gVgcJ1OXak87PkLp/Ii1Cr7
9+
XkkySZeD+Br1vSQzfxs3pFG+iBCeVVkeZdsg+xqwnAlqAILXwIbTGRyJP1Xiu9nw
10+
OeuX1YmxPl2m29Pt1EtfVCL9COsVKt5LgOVyWP/9ISWevOBqSCU9bk35HFo9VTeU
11+
f6+ffhSMjv0Y9uwkFFOKXpcV8Sa3ArqyBmgQlUfGg1iwYlqiDE0fTYxiB3gLgETA
12+
lmTm50J+WB9LoDrnrQpbXFLoegm+JV+uSD8J8H7DL2sCAwEAAaMnMCUwDgYDVR0P
13+
AQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBCwUAA4IB
14+
AQAt0Nvna1c4pPn8kzoN5VvmFmeIgdO/BJpmdhdg0WIQ9aeN/xPXXaVjPp1Mk7ed
15+
XHAvBwQr0Gyzqyy7g/h0gdnAFG7f6blrRNzbrRBCq6cNqX8iwgK/9+2OYKxk1QWj
16+
8Gx0cvu1DN1aXjPPGgQ2j3tHjJvJv32J/zuZa8gU40RPPSLaBlc5ZjpFmyi29sKl
17+
TeeZ+F/Ssic51qXXw2CsYGGWK5yQ3xSCxbw6bb2G/s/YI7/KlWg9BktBJHzRu04Z
18+
NR77W7/dyJ3Lj17PlW1XKmMOFHsQivagXeRCbmYZ43fX4ugFRFKL7KE0EgmGOWpJ
19+
0xv+6ig93sqHzQ/0uv1YgFov
20+
-----END CERTIFICATE-----

cmd/notation/internal/truststore/truststore.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ func DeleteCert(storeType, namedStore, cert string, confirmed bool) error {
194194
return nil
195195
}
196196

197-
// CheckNonErrNotExistError returns nil when no err or err is fs.ErrNotExist
197+
// CheckNonErrNotExistError returns nil when err is nil or err is fs.ErrNotExist
198198
func CheckNonErrNotExistError(err error) error {
199199
if err != nil && !errors.Is(err, fs.ErrNotExist) {
200200
return err

cmd/notation/internal/truststore/truststore_test.go

Lines changed: 99 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,107 @@ package truststore
1515

1616
import (
1717
"errors"
18+
"os"
1819
"path/filepath"
20+
"runtime"
21+
"strings"
1922
"testing"
23+
24+
"github.com/notaryproject/notation-go/dir"
2025
)
2126

22-
func TestEmptyCertFile(t *testing.T) {
23-
path := filepath.FromSlash("../../../../internal/testdata/Empty.txt")
24-
expectedErr := errors.New("no valid certificate found in the empty file")
25-
err := AddCert(path, "ca", "test", false)
26-
if err == nil || err.Error() != "no valid certificate found in the file" {
27-
t.Fatalf("expected err: %v, got: %v", expectedErr, err)
28-
}
27+
func TestAddCert(t *testing.T) {
28+
defer func(oldDir string) {
29+
dir.UserConfigDir = oldDir
30+
}(dir.UserConfigDir)
31+
32+
t.Run("empty store type", func(t *testing.T) {
33+
expectedErrMsg := "store type cannot be empty"
34+
err := AddCert("", "", "test", false)
35+
if err == nil || err.Error() != expectedErrMsg {
36+
t.Fatalf("expected err: %v, but got: %v", expectedErrMsg, err)
37+
}
38+
})
39+
40+
t.Run("invalid store type", func(t *testing.T) {
41+
expectedErrMsg := "unsupported store type: invalid"
42+
err := AddCert("", "invalid", "test", false)
43+
if err == nil || err.Error() != expectedErrMsg {
44+
t.Fatalf("expected err: %v, but got: %v", expectedErrMsg, err)
45+
}
46+
})
47+
48+
t.Run("invalid store name", func(t *testing.T) {
49+
expectedErrMsg := "named store name needs to follow [a-zA-Z0-9_.-]+ format"
50+
err := AddCert("", "ca", "test%", false)
51+
if err == nil || err.Error() != expectedErrMsg {
52+
t.Fatalf("expected err: %v, but got: %v", expectedErrMsg, err)
53+
}
54+
})
55+
56+
t.Run("no valid certificate in file", func(t *testing.T) {
57+
path := filepath.FromSlash("testdata/invalid.txt")
58+
expectedErrMsg := "x509: malformed certificate"
59+
err := AddCert(path, "ca", "test", false)
60+
if err == nil || err.Error() != expectedErrMsg {
61+
t.Fatalf("expected err: %v, but got: %v", expectedErrMsg, err)
62+
}
63+
})
64+
65+
t.Run("cert already exists", func(t *testing.T) {
66+
dir.UserConfigDir = "testdata"
67+
path := filepath.FromSlash("testdata/self-signed.crt")
68+
expectedErrMsg := "certificate already exists in the Trust Store"
69+
err := AddCert(path, "ca", "test", false)
70+
if err == nil || err.Error() != expectedErrMsg {
71+
t.Fatalf("expected err: %v, but got: %v", expectedErrMsg, err)
72+
}
73+
})
74+
75+
t.Run("empty file", func(t *testing.T) {
76+
path := filepath.FromSlash("../../../../internal/testdata/Empty.txt")
77+
expectedErr := errors.New("no valid certificate found in the empty file")
78+
err := AddCert(path, "ca", "test", false)
79+
if err == nil || err.Error() != "no valid certificate found in the file" {
80+
t.Fatalf("expected err: %v, but got: %v", expectedErr, err)
81+
}
82+
})
83+
84+
t.Run("failed to add cert to store", func(t *testing.T) {
85+
if runtime.GOOS == "windows" {
86+
t.Skip("skipping test on Windows")
87+
}
88+
89+
dir.UserConfigDir = t.TempDir()
90+
if err := os.Chmod(dir.UserConfigDir, 0000); err != nil {
91+
t.Fatal(err)
92+
}
93+
defer os.Chmod(dir.UserConfigDir, 0700)
94+
95+
path := filepath.FromSlash("testdata/NotationTestRoot.pem")
96+
expectedErrMsg := "permission denied"
97+
err := AddCert(path, "ca", "test", false)
98+
if err == nil || !strings.Contains(err.Error(), expectedErrMsg) {
99+
t.Fatalf("expected err: %v, but got: %v", expectedErrMsg, err)
100+
}
101+
})
102+
}
103+
104+
func TestDeleteAllCerts(t *testing.T) {
105+
defer func(oldDir string) {
106+
dir.UserConfigDir = oldDir
107+
}(dir.UserConfigDir)
108+
109+
t.Run("store does not exist", func(t *testing.T) {
110+
if runtime.GOOS == "windows" {
111+
t.Skip("skipping test on Windows")
112+
}
113+
114+
dir.UserConfigDir = "testdata"
115+
expectedErrMsg := `stat testdata/truststore/x509/tsa/test: no such file or directory`
116+
err := DeleteAllCerts("tsa", "test", true)
117+
if err == nil || err.Error() != expectedErrMsg {
118+
t.Fatalf("expected err: %v, but got: %v", expectedErrMsg, err)
119+
}
120+
})
29121
}

cmd/notation/plugin/install.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ func install(command *cobra.Command, opts *pluginInstallOpts) error {
132132
}
133133
pluginURL, err := url.Parse(opts.pluginSource)
134134
if err != nil {
135-
return fmt.Errorf("failed to parse plugin download URL %s with error: %w", pluginURL, err)
135+
return fmt.Errorf("failed to parse plugin download URL %s with error: %w", opts.pluginSource, err)
136136
}
137137
if pluginURL.Scheme != "https" {
138138
return fmt.Errorf("failed to download plugin from URL: only the HTTPS scheme is supported, but got %s", pluginURL.Scheme)
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// Copyright The Notary Project Authors.
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
package plugin
15+
16+
import (
17+
"context"
18+
"os"
19+
"path/filepath"
20+
"runtime"
21+
"strings"
22+
"testing"
23+
24+
notationplugin "github.com/notaryproject/notation/cmd/notation/internal/plugin"
25+
"github.com/notaryproject/notation/internal/osutil"
26+
"github.com/spf13/cobra"
27+
)
28+
29+
func TestInstall(t *testing.T) {
30+
t.Run("invalid plugin source url", func(t *testing.T) {
31+
opts := &pluginInstallOpts{
32+
pluginSourceType: notationplugin.PluginSourceTypeURL,
33+
inputChecksum: "dummy",
34+
pluginSource: "http://[::1]/%",
35+
}
36+
expectedErrMsg := `failed to parse plugin download URL http://[::1]/% with error: parse "http://[::1]/%": invalid URL escape "%"`
37+
err := install(&cobra.Command{}, opts)
38+
if err == nil || err.Error() != expectedErrMsg {
39+
t.Fatalf("expected error %s, but got %s", expectedErrMsg, err)
40+
}
41+
})
42+
43+
t.Run("unknown plugin source type", func(t *testing.T) {
44+
opts := &pluginInstallOpts{
45+
pluginSourceType: -1,
46+
}
47+
expectedErrMsg := `plugin installation failed: unknown plugin source type`
48+
err := install(&cobra.Command{}, opts)
49+
if err == nil || err.Error() != expectedErrMsg {
50+
t.Fatalf("expected error %s, but got %s", expectedErrMsg, err)
51+
}
52+
})
53+
}
54+
55+
func TestInstallPlugin(t *testing.T) {
56+
ctx := context.Background()
57+
t.Run("input path does not exist", func(t *testing.T) {
58+
if runtime.GOOS == "windows" {
59+
t.Skip("skipping test on Windows")
60+
}
61+
expectedErrMsg := `stat invalid: no such file or directory`
62+
err := installPlugin(ctx, "invalid", "", false)
63+
if err == nil || err.Error() != expectedErrMsg {
64+
t.Fatalf("expected error %s, but got %s", expectedErrMsg, err)
65+
}
66+
})
67+
68+
t.Run("failed to get file type", func(t *testing.T) {
69+
if runtime.GOOS == "windows" {
70+
t.Skip("skipping test on Windows")
71+
}
72+
73+
tempDir := t.TempDir()
74+
data := []byte("data")
75+
filename := filepath.Join(tempDir, "a", "file.txt")
76+
if err := osutil.WriteFile(filename, data); err != nil {
77+
t.Fatal(err)
78+
}
79+
err := os.Chmod(tempDir, 0)
80+
if err != nil {
81+
t.Fatal(err)
82+
}
83+
defer func() {
84+
err := os.Chmod(tempDir, 0700)
85+
if err != nil {
86+
t.Fatal(err)
87+
}
88+
}()
89+
90+
expectedErrMsg := `permission denied`
91+
err = installPlugin(ctx, filename, "", false)
92+
if err == nil || !strings.Contains(err.Error(), expectedErrMsg) {
93+
t.Fatalf("expected permission denied error, but got %s", err)
94+
}
95+
})
96+
}

0 commit comments

Comments
 (0)