From e5c210cf9700c80c44e96d6d162bc024f9921c79 Mon Sep 17 00:00:00 2001 From: Junjie Gao Date: Thu, 18 Apr 2024 09:02:01 +0800 Subject: [PATCH] fix: improve error message for --signature-format flag (#925) Signed-off-by: Junjie Gao --- internal/envelope/envelope.go | 2 +- internal/envelope/envelope_test.go | 76 ++++++++++++++++++++ test/e2e/run.sh | 4 +- test/e2e/suite/command/cert.go | 108 +++++++++++++++++++++++++++++ 4 files changed, 187 insertions(+), 3 deletions(-) create mode 100644 test/e2e/suite/command/cert.go diff --git a/internal/envelope/envelope.go b/internal/envelope/envelope.go index 93466bdb2..4f49ca0f8 100644 --- a/internal/envelope/envelope.go +++ b/internal/envelope/envelope.go @@ -46,7 +46,7 @@ func GetEnvelopeMediaType(sigFormat string) (string, error) { case COSE: return cose.MediaTypeEnvelope, nil } - return "", fmt.Errorf("signature format %q not supported", sigFormat) + return "", fmt.Errorf("signature format %q not supported\nSupported signature envelope formats are \"jws\" and \"cose\"", sigFormat) } // ValidatePayloadContentType validates signature payload's content type. diff --git a/internal/envelope/envelope_test.go b/internal/envelope/envelope_test.go index 850dee624..b3575aab2 100644 --- a/internal/envelope/envelope_test.go +++ b/internal/envelope/envelope_test.go @@ -15,6 +15,8 @@ package envelope import ( "testing" + + "github.com/notaryproject/notation-core-go/signature" ) func TestGetEnvelopeMediaType(t *testing.T) { @@ -59,3 +61,77 @@ func TestGetEnvelopeMediaType(t *testing.T) { }) } } + +func TestValidatePayloadContentType(t *testing.T) { + tests := []struct { + name string + payload *signature.Payload + wantErr bool + }{ + { + name: "valid content type", + payload: &signature.Payload{ + ContentType: MediaTypePayloadV1, + }, + wantErr: false, + }, + { + name: "invalid content type", + payload: &signature.Payload{ + ContentType: "invalid", + }, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := ValidatePayloadContentType(tt.payload) + if (err != nil) != tt.wantErr { + t.Errorf("ValidatePayloadContentType() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestDescriptorFromSignaturePayload(t *testing.T) { + validPayload := &signature.Payload{ + ContentType: MediaTypePayloadV1, + Content: []byte(`{"targetArtifact": {"mediaType": "application/vnd.oci.image.manifest.v1+json", "size": 314159, "digest": "sha256:abcd1234", "urls": ["http://example.com"]}}`), + } + invalidPayload := &signature.Payload{ + ContentType: "invalid", + Content: []byte(`invalid`), + } + + tests := []struct { + name string + payload *signature.Payload + wantErr bool + }{ + { + name: "valid payload", + payload: validPayload, + wantErr: false, + }, + { + name: "invalid content type", + payload: invalidPayload, + wantErr: true, + }, + { + name: "nil payload", + payload: nil, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := DescriptorFromSignaturePayload(tt.payload) + if (err != nil) != tt.wantErr { + t.Errorf("DescriptorFromSignaturePayload() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/test/e2e/run.sh b/test/e2e/run.sh index 7da050cb4..1d3559788 100755 --- a/test/e2e/run.sh +++ b/test/e2e/run.sh @@ -69,7 +69,7 @@ if [ ! -f "$NOTATION_E2E_OLD_BINARY_PATH" ]; then fi # install dependency -go install -mod=mod github.com/onsi/ginkgo/v2/ginkgo@v2.9.5 +go install -mod=mod github.com/onsi/ginkgo/v2/ginkgo@v2.11.0 # build e2e plugin and tar.gz PLUGIN_NAME=notation-e2e-plugin @@ -111,4 +111,4 @@ export NOTATION_E2E_PLUGIN_TAR_GZ_PATH=$CWD/plugin/bin/$PLUGIN_NAME.tar.gz export NOTATION_E2E_MALICIOUS_PLUGIN_ARCHIVE_PATH=$CWD/testdata/malicious-plugin # run tests -ginkgo -r -p -v \ No newline at end of file +ginkgo -r -p -v diff --git a/test/e2e/suite/command/cert.go b/test/e2e/suite/command/cert.go new file mode 100644 index 000000000..418a8a6ca --- /dev/null +++ b/test/e2e/suite/command/cert.go @@ -0,0 +1,108 @@ +// Copyright The Notary Project Authors. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package command + +import ( + . "github.com/notaryproject/notation/test/e2e/internal/notation" + "github.com/notaryproject/notation/test/e2e/internal/utils" + + // . "github.com/notaryproject/notation/test/e2e/suite/common" + . "github.com/onsi/ginkgo/v2" +) + +var _ = Describe("notation cert", func() { + It("show all", func() { + Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { + notation.Exec("cert", "list"). + MatchKeyWords( + "STORE TYPE STORE NAME CERTIFICATE", + ) + }) + }) + + It("delete all", func() { + Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { + notation.Exec("cert", "delete", "--all", "--type", "ca", "--store", "e2e", "-y"). + MatchKeyWords( + "Successfully deleted", + ) + }) + }) + + It("delete a specfic cert", func() { + Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { + notation.Exec("cert", "delete", "--type", "ca", "--store", "e2e", "e2e.crt", "-y"). + MatchKeyWords( + "Successfully deleted e2e.crt", + ) + }) + }) + + It("delete a non-exist cert", func() { + Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { + notation.ExpectFailure().Exec("cert", "delete", "--type", "ca", "--store", "e2e", "non-exist.crt", "-y"). + MatchErrKeyWords( + "failed to delete the certificate file", + ) + }) + }) + + It("show e2e cert", func() { + Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { + notation.Exec("cert", "show", "--type", "ca", "--store", "e2e", "e2e.crt"). + MatchKeyWords( + "Issuer: CN=e2e,O=Notary,L=Seattle,ST=WA,C=US", + ) + }) + }) + + It("list", func() { + Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { + notation.Exec("cert", "list"). + MatchKeyWords( + "STORE TYPE STORE NAME CERTIFICATE", + ) + }) + }) + + It("list with type", func() { + Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { + notation.Exec("cert", "list", "--type", "ca"). + MatchKeyWords( + "STORE TYPE STORE NAME CERTIFICATE", + "e2e.crt", + ) + }) + }) + + It("list with store", func() { + Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { + notation.Exec("cert", "list", "--store", "e2e"). + MatchKeyWords( + "STORE TYPE STORE NAME CERTIFICATE", + "e2e.crt", + ) + }) + }) + + It("list with type and store", func() { + Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) { + notation.Exec("cert", "list", "--type", "ca", "--store", "e2e"). + MatchKeyWords( + "STORE TYPE STORE NAME CERTIFICATE", + "e2e.crt", + ) + }) + }) +})