Skip to content

Commit

Permalink
Fix field names in generated json statement (#1129)
Browse files Browse the repository at this point in the history
To keep backwards compatibility with previous struct versions (e.g, github.com/in-toto/in-toto-golang/in_toto) we have to use protojson.Marshal function to transform the struct to its json representation so the tags defined in the intoto.Statement are follow and applied to the resulting string.
  • Loading branch information
renzodavid9 committed Jun 5, 2024
1 parent dc4e8ac commit 3bf8cac
Show file tree
Hide file tree
Showing 11 changed files with 119 additions and 19 deletions.
20 changes: 19 additions & 1 deletion pkg/chains/signing.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"fmt"

"github.com/hashicorp/go-multierror"
intoto "github.com/in-toto/attestation/go/v1"
"github.com/tektoncd/chains/pkg/artifacts"
"github.com/tektoncd/chains/pkg/chains/formats"
"github.com/tektoncd/chains/pkg/chains/objects"
Expand All @@ -29,6 +30,7 @@ import (
"github.com/tektoncd/chains/pkg/chains/storage"
"github.com/tektoncd/chains/pkg/config"
versioned "github.com/tektoncd/pipeline/pkg/client/clientset/versioned"
"google.golang.org/protobuf/encoding/protojson"
"k8s.io/apimachinery/pkg/util/sets"
"knative.dev/pkg/logging"
)
Expand Down Expand Up @@ -169,7 +171,7 @@ func (o *ObjectSigner) Sign(ctx context.Context, tektonObj objects.TektonObject)
}

logger.Infof("Signing object with %s", signerType)
rawPayload, err := json.Marshal(payload)
rawPayload, err := getRawPayload(payload)
if err != nil {
logger.Warnf("Unable to marshal payload: %v", signerType, obj)
continue
Expand Down Expand Up @@ -248,3 +250,19 @@ func HandleRetry(ctx context.Context, obj objects.TektonObject, ps versioned.Int
}
return MarkFailed(ctx, obj, ps, annotations)
}

// getRawPayload returns the payload as a json string. If the given payload is a intoto.Statement type, protojson.Marshal
// is used to get the proper labels/field names in the resulting json.
func getRawPayload(payload interface{}) ([]byte, error) {
switch payloadObj := payload.(type) {
case intoto.Statement:
return protojson.Marshal(&payloadObj)
case *intoto.Statement:
if payloadObj == nil {
return json.Marshal(payload)
}
return protojson.Marshal(payloadObj)
default:
return json.Marshal(payload)
}
}
82 changes: 82 additions & 0 deletions pkg/chains/signing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,16 @@ limitations under the License.
package chains

import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"reflect"
"testing"

"github.com/google/go-cmp/cmp"
intoto "github.com/in-toto/attestation/go/v1"
"github.com/sigstore/rekor/pkg/generated/models"
"github.com/tektoncd/chains/pkg/chains/objects"
"github.com/tektoncd/chains/pkg/chains/signing"
Expand Down Expand Up @@ -405,6 +409,84 @@ func TestSigningObjects(t *testing.T) {
}
}

func TestGetRawPayload(t *testing.T) {
tests := []struct {
name string
payload interface{}
expected string
}{
{
name: "intoto.Statement object",
payload: intoto.Statement{
Type: "type1",
PredicateType: "predicate-type1",
},
expected: compactJSON(t, []byte(`{"_type":"type1","predicateType":"predicate-type1"}`)),
},
{
name: "*intoto.Statement object",
payload: &intoto.Statement{
Type: "type1",
PredicateType: "predicate-type1",
},
expected: compactJSON(t, []byte(`{"_type":"type1","predicateType":"predicate-type1"}`)),
},
{
name: "*intoto.Statement object - nil",
payload: (func() *intoto.Statement { return nil })(),
expected: "null",
},
{
name: "other object - nil",
payload: nil,
expected: "null",
},
{
name: "other object with value",
payload: struct {
Name string
ID int
Inner any
}{
Name: "wrapper",
ID: 1,
Inner: struct {
InnerID int
Description string
IsArtifact bool
}{
InnerID: 2,
Description: "some description",
IsArtifact: true,
},
},
expected: compactJSON(t, []byte(`{"Name":"wrapper","ID":1,"Inner": {"InnerID":2,"Description":"some description","IsArtifact":true}}`)),
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
got, err := getRawPayload(test.payload)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
compactExpected := compactJSON(t, got)
if diff := cmp.Diff(test.expected, compactExpected); diff != "" {
t.Errorf("getRawPayload(), -want +got, diff = %s", diff)
}
})
}
}

func compactJSON(t *testing.T, jsonString []byte) string {
t.Helper()
dst := &bytes.Buffer{}
if err := json.Compact(dst, jsonString); err != nil {
t.Fatalf("error getting compact JSON: %v", err)
}
return dst.String()
}

func fakeAllBackends(backends []*mockBackend) map[string]storage.Backend {
newBackends := map[string]storage.Backend{}
for _, m := range backends {
Expand Down
4 changes: 2 additions & 2 deletions test/testdata/slsa/v1/pipeline-output-image.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"type": "https://in-toto.io/Statement/v0.1",
"predicate_type": "https://slsa.dev/provenance/v0.2",
"_type": "https://in-toto.io/Statement/v0.1",
"predicateType": "https://slsa.dev/provenance/v0.2",
"subject": [
{
"name": "gcr.io/foo/bar",
Expand Down
4 changes: 2 additions & 2 deletions test/testdata/slsa/v1/task-output-image.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"type": "https://in-toto.io/Statement/v0.1",
"predicate_type": "https://slsa.dev/provenance/v0.2",
"_type": "https://in-toto.io/Statement/v0.1",
"predicateType": "https://slsa.dev/provenance/v0.2",
"subject": [
{
"name": "gcr.io/foo/bar",
Expand Down
4 changes: 2 additions & 2 deletions test/testdata/slsa/v2/task-output-image.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"type": "https://in-toto.io/Statement/v0.1",
"predicate_type": "https://slsa.dev/provenance/v0.2",
"_type": "https://in-toto.io/Statement/v0.1",
"predicateType": "https://slsa.dev/provenance/v0.2",
"subject": [
{
"name": "gcr.io/foo/bar",
Expand Down
4 changes: 2 additions & 2 deletions test/testdata/slsa/v2alpha3/pipeline-output-image.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"type": "https://in-toto.io/Statement/v1",
"predicate_type": "https://slsa.dev/provenance/v1",
"_type": "https://in-toto.io/Statement/v1",
"predicateType": "https://slsa.dev/provenance/v1",
"subject": [
{
"name": "gcr.io/foo/bar",
Expand Down
4 changes: 2 additions & 2 deletions test/testdata/slsa/v2alpha3/task-output-image.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"type": "https://in-toto.io/Statement/v1",
"predicate_type": "https://slsa.dev/provenance/v1",
"_type": "https://in-toto.io/Statement/v1",
"predicateType": "https://slsa.dev/provenance/v1",
"subject": [
{
"name": "gcr.io/foo/bar",
Expand Down
4 changes: 2 additions & 2 deletions test/testdata/slsa/v2alpha4/pipeline-output-image.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"type": "https://in-toto.io/Statement/v1",
"predicate_type": "https://slsa.dev/provenance/v1",
"_type": "https://in-toto.io/Statement/v1",
"predicateType": "https://slsa.dev/provenance/v1",
"subject": [
{
"name": "gcr.io/foo/bar",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"type": "https://in-toto.io/Statement/v1",
"predicate_type": "https://slsa.dev/provenance/v1",
"_type": "https://in-toto.io/Statement/v1",
"predicateType": "https://slsa.dev/provenance/v1",
"subject": [
{
"name": "gcr.io/foo/img1",
Expand Down
4 changes: 2 additions & 2 deletions test/testdata/slsa/v2alpha4/task-output-image.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"type": "https://in-toto.io/Statement/v1",
"predicate_type": "https://slsa.dev/provenance/v1",
"_type": "https://in-toto.io/Statement/v1",
"predicateType": "https://slsa.dev/provenance/v1",
"subject": [
{
"name": "gcr.io/foo/bar",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"type": "https://in-toto.io/Statement/v1",
"predicate_type": "https://slsa.dev/provenance/v1",
"_type": "https://in-toto.io/Statement/v1",
"predicateType": "https://slsa.dev/provenance/v1",
"subject": [
{
"name": "gcr.io/foo/img2",
Expand Down

0 comments on commit 3bf8cac

Please sign in to comment.