Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds custom marshal/unmarshal to Go Statement struct, fixes #363, see sigstore/sigstore-go#326 #403

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add custom marshal/unmarshal, fixes #363, see sigstore/sigstore-go#326
Signed-off-by: Andrew Gillis <[email protected]>
gillisandrew committed Nov 1, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
commit 938abe24cc2d1541c965c14973d797770ddfebf4
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module github.com/in-toto/attestation

go 1.20
go 1.21

toolchain go1.21.0

require (
github.com/stretchr/testify v1.9.0
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
14 changes: 13 additions & 1 deletion go/v1/statement.go
Original file line number Diff line number Diff line change
@@ -4,7 +4,11 @@ Wrapper APIs for in-toto attestation Statement layer protos.

package v1

import "errors"
import (
"errors"

"google.golang.org/protobuf/encoding/protojson"
)

const StatementTypeUri = "https://in-toto.io/Statement/v1"

@@ -48,3 +52,11 @@ func (s *Statement) Validate() error {

return nil
}

func (s *Statement) MarshalJSON() ([]byte, error) {
return protojson.Marshal(s)
}

func (s *Statement) UnmarshalJSON(data []byte) error {
return protojson.Unmarshal(data, s)
}
36 changes: 34 additions & 2 deletions go/v1/statement_test.go
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ Tests for in-toto attestation ResourceDescriptor protos.
package v1

import (
"encoding/json"
"fmt"
"testing"

@@ -39,18 +40,46 @@ func createTestStatement(t *testing.T) *Statement {
}
}

func TestJsonUnmarshalStatement(t *testing.T) {
func TestProtojsonUnmarshalStatement(t *testing.T) {
var wantSt = `{"_type":"https://in-toto.io/Statement/v1","subject":[{"name":"theSub","digest":{"alg1":"abc123"}}],"predicateType":"thePredicate","predicate":{"keyObj":{"subKey":"subVal"}}}`

got := &Statement{}
err := protojson.Unmarshal([]byte(wantSt), got)
assert.NoError(t, err, "error during JSON unmarshalling")

want := createTestStatement(t)
assert.NoError(t, err, "unexpected error during test Statement creation")
assert.True(t, proto.Equal(got, want), "protos do not match")
}

func TestJsonUnmarshalStatement(t *testing.T) {
var wantSt = `{"_type":"https://in-toto.io/Statement/v1","subject":[{"name":"theSub","digest":{"alg1":"abc123"}}],"predicateType":"thePredicate","predicate":{"keyObj":{"subKey":"subVal"}}}`

got := &Statement{}
err := json.Unmarshal([]byte(wantSt), got)
assert.NoError(t, err, "error during JSON unmarshalling")

want := createTestStatement(t)
assert.True(t, proto.Equal(got, want), "protos do not match")
}

func TestProtojsonMarshalStatement(t *testing.T) {
var wantSt = `{"_type":"https://in-toto.io/Statement/v1","subject":[{"name":"theSub","digest":{"alg1":"abc123"}}],"predicateType":"thePredicate","predicate":{"keyObj":{"subKey":"subVal"}}}`
want := createTestStatement(t)

gotSt, err := protojson.Marshal(want)
assert.NoError(t, err, "error during JSON marshalling")
assert.JSONEq(t, wantSt, string(gotSt), "JSON objects do not match")
}

func TestJsonMarshalStatement(t *testing.T) {
var wantSt = `{"_type":"https://in-toto.io/Statement/v1","subject":[{"name":"theSub","digest":{"alg1":"abc123"}}],"predicateType":"thePredicate","predicate":{"keyObj":{"subKey":"subVal"}}}`
want := createTestStatement(t)

gotSt, err := json.Marshal(want)
assert.NoError(t, err, "error during JSON marshalling")
assert.JSONEq(t, wantSt, string(gotSt), "JSON objects do not match")
}

func TestBadStatementType(t *testing.T) {
var badStType = `{"_type":"https://in-toto.io/Statement/v0","subject":[{"name":"theSub","digest":{"alg1":"abc123"}}],"predicateType":"thePredicate","predicate":{"keyObj":{"subKey":"subVal"}}}`

@@ -62,6 +91,8 @@ func TestBadStatementType(t *testing.T) {
assert.ErrorIs(t, err, ErrInvalidStatementType, "created malformed Statement (bad type)")
}



func TestBadStatementSubject(t *testing.T) {
tests := map[string]struct {
input string
@@ -122,3 +153,4 @@ func TestBadStatementPredicate(t *testing.T) {
assert.ErrorIs(t, err, test.err, fmt.Sprintf("%s in test '%s'", test.noErrMessage, name))
}
}