From d9739a3bab7ee36d36adaf293ecbe7cb1b47cfff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Mur=C3=A9?= Date: Wed, 2 Oct 2024 11:57:24 +0200 Subject: [PATCH] token: don't store the CID in the token, symmetric API for sealed --- token/delegation/delegation.go | 11 -------- token/delegation/examples_test.go | 4 +-- token/delegation/ipld.go | 20 ++++++--------- token/delegation/schema_test.go | 17 ++++++------- token/invocation/invocation.go | 11 -------- token/invocation/ipld.go | 20 ++++++--------- token/read.go | 42 +++++++++++++++++++++++++++++++ 7 files changed, 68 insertions(+), 57 deletions(-) diff --git a/token/delegation/delegation.go b/token/delegation/delegation.go index 2590a67..ccaed08 100644 --- a/token/delegation/delegation.go +++ b/token/delegation/delegation.go @@ -15,7 +15,6 @@ import ( "fmt" "time" - "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p/core/crypto" "github.com/ucan-wg/go-ucan/did" @@ -44,8 +43,6 @@ type Token struct { notBefore *time.Time // The timestamp at which the Invocation becomes invalid expiration *time.Time - // The CID of the Token when enclosed in an Envelope and encoded to DAG-CBOR - cid cid.Cid } // New creates a validated Token from the provided parameters and options. @@ -67,7 +64,6 @@ func New(privKey crypto.PrivKey, aud did.DID, cmd command.Command, pol policy.Po policy: pol, meta: meta.NewMeta(), nonce: nil, - cid: cid.Undef, } for _, opt := range opts { @@ -156,13 +152,6 @@ func (t *Token) Expiration() *time.Time { return t.expiration } -// CID returns the content identifier of the Token model when enclosed -// in an Envelope and encoded to DAG-CBOR. -// Returns cid.Undef if the token has not been serialized or deserialized yet. -func (t *Token) CID() cid.Cid { - return t.cid -} - func (t *Token) validate() error { var errs error diff --git a/token/delegation/examples_test.go b/token/delegation/examples_test.go index a9d5522..ebd3650 100644 --- a/token/delegation/examples_test.go +++ b/token/delegation/examples_test.go @@ -223,10 +223,10 @@ func ExampleToken_FromSealed() { cborBytes := exampleCBORData() fmt.Println("DAG-CBOR (base64) in:", base64.StdEncoding.EncodeToString(cborBytes)) - tkn, err := delegation.FromSealed(cborBytes) + tkn, c, err := delegation.FromSealed(cborBytes) printThenPanicOnErr(err) - fmt.Println("CID (base58BTC):", envelope.CIDToBase58BTC(tkn.CID())) + fmt.Println("CID (base58BTC):", envelope.CIDToBase58BTC(c)) fmt.Println("Issuer (iss):", tkn.Issuer().String()) fmt.Println("Audience (aud):", tkn.Audience().String()) fmt.Println("Subject (sub):", tkn.Subject().String()) diff --git a/token/delegation/ipld.go b/token/delegation/ipld.go index 7c21b79..004a49b 100644 --- a/token/delegation/ipld.go +++ b/token/delegation/ipld.go @@ -47,39 +47,35 @@ func (t *Token) ToSealedWriter(w io.Writer, privKey crypto.PrivKey) (cid.Cid, er // verifies that the envelope's signature is correct based on the public // key taken from the issuer (iss) field and calculates the CID of the // incoming data. -func FromSealed(data []byte) (*Token, error) { +func FromSealed(data []byte) (*Token, cid.Cid, error) { tkn, err := FromDagCbor(data) if err != nil { - return nil, err + return nil, cid.Undef, err } id, err := envelope.CIDFromBytes(data) if err != nil { - return nil, err + return nil, cid.Undef, err } - tkn.cid = id - - return tkn, nil + return tkn, id, nil } // FromSealedReader is the same as Unseal but accepts an io.Reader. -func FromSealedReader(r io.Reader) (*Token, error) { +func FromSealedReader(r io.Reader) (*Token, cid.Cid, error) { cidReader := envelope.NewCIDReader(r) tkn, err := FromDagCborReader(cidReader) if err != nil { - return nil, err + return nil, cid.Undef, err } id, err := cidReader.CID() if err != nil { - return nil, err + return nil, cid.Undef, err } - tkn.cid = id - - return tkn, nil + return tkn, id, nil } // Encode marshals a Token to the format specified by the provided diff --git a/token/delegation/schema_test.go b/token/delegation/schema_test.go index 685f6c8..8866cc7 100644 --- a/token/delegation/schema_test.go +++ b/token/delegation/schema_test.go @@ -39,9 +39,9 @@ func TestSchemaRoundTrip(t *testing.T) { fmt.Println("cborBytes length", len(cborBytes)) fmt.Println("cbor", string(cborBytes)) - p2, err := delegation.FromSealed(cborBytes) + p2, c2, err := delegation.FromSealed(cborBytes) require.NoError(t, err) - assert.Equal(t, id, p2.CID()) + assert.Equal(t, id, c2) fmt.Println("read Cbor", p2) readJson, err := p2.ToDagJson(privKey) @@ -70,10 +70,9 @@ func TestSchemaRoundTrip(t *testing.T) { assert.Equal(t, newCID, envelope.CIDToBase58BTC(id)) // buf = bytes.NewBuffer(cborBytes.Bytes()) - p2, err := delegation.FromSealedReader(cborBytes) + p2, c2, err := delegation.FromSealedReader(cborBytes) require.NoError(t, err) - t.Log(len(p2.CID().Bytes()), p2.CID().Bytes()) - assert.Equal(t, envelope.CIDToBase58BTC(id), envelope.CIDToBase58BTC(p2.CID())) + assert.Equal(t, envelope.CIDToBase58BTC(id), envelope.CIDToBase58BTC(c2)) readJson := &bytes.Buffer{} require.NoError(t, p2.ToDagJsonWriter(readJson, privKey)) @@ -96,7 +95,7 @@ func BenchmarkRoundTrip(b *testing.B) { b.Run("via buffers", func(b *testing.B) { p1, _ := delegation.FromDagJson(delegationJson) cborBytes, _, _ := p1.ToSealed(privKey) - p2, _ := delegation.FromSealed(cborBytes) + p2, _, _ := delegation.FromSealed(cborBytes) b.ResetTimer() @@ -117,7 +116,7 @@ func BenchmarkRoundTrip(b *testing.B) { b.Run("Unseal", func(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { - _, _ = delegation.FromSealed(cborBytes) + _, _, _ = delegation.FromSealed(cborBytes) } }) @@ -134,7 +133,7 @@ func BenchmarkRoundTrip(b *testing.B) { cborBuf := &bytes.Buffer{} _, _ = p1.ToSealedWriter(cborBuf, privKey) cborBytes := cborBuf.Bytes() - p2, _ := delegation.FromSealedReader(bytes.NewReader(cborBytes)) + p2, _, _ := delegation.FromSealedReader(bytes.NewReader(cborBytes)) b.ResetTimer() @@ -161,7 +160,7 @@ func BenchmarkRoundTrip(b *testing.B) { reader := bytes.NewReader(cborBytes) for i := 0; i < b.N; i++ { _, _ = reader.Seek(0, 0) - _, _ = delegation.FromSealedReader(reader) + _, _, _ = delegation.FromSealedReader(reader) } }) diff --git a/token/invocation/invocation.go b/token/invocation/invocation.go index 84a97a9..3152540 100644 --- a/token/invocation/invocation.go +++ b/token/invocation/invocation.go @@ -13,8 +13,6 @@ import ( "fmt" "time" - "github.com/ipfs/go-cid" - "github.com/ucan-wg/go-ucan/did" "github.com/ucan-wg/go-ucan/pkg/command" "github.com/ucan-wg/go-ucan/pkg/meta" @@ -41,8 +39,6 @@ type Token struct { // The timestamp at which the Invocation was created invokedAt *time.Time // TODO: cause - // The CID of the Token when enclosed in an Envelope and encoded to DAG-CBOR - cid cid.Cid } // Issuer returns the did.DID representing the Token's issuer. @@ -84,13 +80,6 @@ func (t *Token) Expiration() *time.Time { return t.expiration } -// CID returns the content identifier of the Token model when enclosed -// in an Envelope and encoded to DAG-CBOR. -// Returns cid.Undef if the token has not been serialized or deserialized yet. -func (t *Token) CID() cid.Cid { - return t.cid -} - func (t *Token) validate() error { var errs error diff --git a/token/invocation/ipld.go b/token/invocation/ipld.go index cf9ce10..897f608 100644 --- a/token/invocation/ipld.go +++ b/token/invocation/ipld.go @@ -47,39 +47,35 @@ func (t *Token) ToSealedWriter(w io.Writer, privKey crypto.PrivKey) (cid.Cid, er // verifies that the envelope's signature is correct based on the public // key taken from the issuer (iss) field and calculates the CID of the // incoming data. -func FromSealed(data []byte) (*Token, error) { +func FromSealed(data []byte) (*Token, cid.Cid, error) { tkn, err := FromDagCbor(data) if err != nil { - return nil, err + return nil, cid.Undef, err } id, err := envelope.CIDFromBytes(data) if err != nil { - return nil, err + return nil, cid.Undef, err } - tkn.cid = id - - return tkn, nil + return tkn, id, nil } // FromSealedReader is the same as Unseal but accepts an io.Reader. -func FromSealedReader(r io.Reader) (*Token, error) { +func FromSealedReader(r io.Reader) (*Token, cid.Cid, error) { cidReader := envelope.NewCIDReader(r) tkn, err := FromDagCborReader(cidReader) if err != nil { - return nil, err + return nil, cid.Undef, err } id, err := cidReader.CID() if err != nil { - return nil, err + return nil, cid.Undef, err } - tkn.cid = id - - return tkn, nil + return tkn, id, nil } // Encode marshals a Token to the format specified by the provided diff --git a/token/read.go b/token/read.go index 513f2a3..6a3f36d 100644 --- a/token/read.go +++ b/token/read.go @@ -4,6 +4,7 @@ import ( "fmt" "io" + "github.com/ipfs/go-cid" "github.com/ipld/go-ipld-prime" "github.com/ipld/go-ipld-prime/codec" "github.com/ipld/go-ipld-prime/codec/dagcbor" @@ -15,12 +16,51 @@ import ( "github.com/ucan-wg/go-ucan/token/invocation" ) +// FromSealed decodes an arbitrary token type from the binary data, +// verifies that the envelope's signature is correct based on the public +// key taken from the issuer (iss) field and calculates the CID of the +// incoming data. +// Supported and returned types are: +// - delegation.Token +// - invocation.Token +func FromSealed(data []byte) (Token, cid.Cid, error) { + tkn, err := FromDagCbor(data) + if err != nil { + return nil, cid.Undef, err + } + + id, err := envelope.CIDFromBytes(data) + if err != nil { + return nil, cid.Undef, err + } + + return tkn, id, nil +} + +// FromSealedReader is the same as Unseal but accepts an io.Reader. +func FromSealedReader(r io.Reader) (Token, cid.Cid, error) { + cidReader := envelope.NewCIDReader(r) + + tkn, err := FromDagCborReader(cidReader) + if err != nil { + return nil, cid.Undef, err + } + + id, err := cidReader.CID() + if err != nil { + return nil, cid.Undef, err + } + + return tkn, id, nil +} + // Decode unmarshals the input data using the format specified by the // provided codec.Decoder into an arbitrary UCAN token. // An error is returned if the conversion fails, or if the resulting // Token is invalid. // Supported and returned types are: // - delegation.Token +// - invocation.Token func Decode(b []byte, decFn codec.Decoder) (Token, error) { node, err := ipld.Decode(b, decFn) if err != nil { @@ -43,6 +83,7 @@ func DecodeReader(r io.Reader, decFn codec.Decoder) (Token, error) { // Token is invalid. // Supported and returned types are: // - delegation.Token +// - invocation.Token func FromDagCbor(b []byte) (Token, error) { return Decode(b, dagcbor.Decode) } @@ -57,6 +98,7 @@ func FromDagCborReader(r io.Reader) (Token, error) { // Token is invalid. // Supported and returned types are: // - delegation.Token +// - invocation.Token func FromDagJson(b []byte) (Token, error) { return Decode(b, dagjson.Decode) }