Files
ucan/token/read.go

127 lines
3.7 KiB
Go
Raw Permalink Normal View History

2024-10-01 17:02:49 +02:00
package token
2024-10-01 13:23:37 +02:00
import (
"fmt"
"io"
2024-10-01 13:23:37 +02:00
"code.sonr.org/go/did-it"
"github.com/ipfs/go-cid"
2024-10-01 13:23:37 +02:00
"github.com/ipld/go-ipld-prime"
"github.com/ipld/go-ipld-prime/codec"
2024-10-01 13:23:37 +02:00
"github.com/ipld/go-ipld-prime/codec/dagcbor"
"github.com/ipld/go-ipld-prime/codec/dagjson"
"github.com/ipld/go-ipld-prime/datamodel"
2024-10-01 13:23:37 +02:00
"code.sonr.org/go/ucan/token/delegation"
"code.sonr.org/go/ucan/token/internal/envelope"
"code.sonr.org/go/ucan/token/invocation"
2024-10-01 13:23:37 +02:00
)
// 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, resolvOpts ...did.ResolutionOption) (Token, cid.Cid, error) {
tkn, err := FromDagCbor(data, resolvOpts...)
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, resolvOpts ...did.ResolutionOption) (Token, cid.Cid, error) {
cidReader := envelope.NewCIDReader(r)
tkn, err := FromDagCborReader(cidReader, resolvOpts...)
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, resolvOpts ...did.ResolutionOption) (Token, error) {
node, err := ipld.Decode(b, decFn)
if err != nil {
return nil, err
}
return fromIPLD(node, resolvOpts...)
}
// DecodeReader is the same as Decode, but accept an io.Reader.
func DecodeReader(r io.Reader, decFn codec.Decoder, resolvOpts ...did.ResolutionOption) (Token, error) {
node, err := ipld.DecodeStreaming(r, decFn)
2024-10-01 13:23:37 +02:00
if err != nil {
return nil, err
}
return fromIPLD(node, resolvOpts...)
}
// FromDagCbor unmarshals an arbitrary DagCbor encoded 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 FromDagCbor(b []byte, resolvOpts ...did.ResolutionOption) (Token, error) {
return Decode(b, dagcbor.Decode, resolvOpts...)
}
// FromDagCborReader is the same as FromDagCbor, but accept an io.Reader.
func FromDagCborReader(r io.Reader, resolvOpts ...did.ResolutionOption) (Token, error) {
return DecodeReader(r, dagcbor.Decode, resolvOpts...)
}
// FromDagJson unmarshals an arbitrary DagJson encoded 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 FromDagJson(b []byte, resolvOpts ...did.ResolutionOption) (Token, error) {
return Decode(b, dagjson.Decode, resolvOpts...)
}
// FromDagJsonReader is the same as FromDagJson, but accept an io.Reader.
func FromDagJsonReader(r io.Reader, resolvOpts ...did.ResolutionOption) (Token, error) {
return DecodeReader(r, dagjson.Decode, resolvOpts...)
}
2024-10-01 13:23:37 +02:00
func fromIPLD(node datamodel.Node, resolvOpts ...did.ResolutionOption) (Token, error) {
2024-10-01 13:23:37 +02:00
tag, err := envelope.FindTag(node)
if err != nil {
return nil, err
}
switch tag {
case delegation.Tag:
return delegation.FromIPLD(node, resolvOpts...)
2024-10-02 10:53:30 +02:00
case invocation.Tag:
return invocation.FromIPLD(node, resolvOpts...)
2024-10-01 13:23:37 +02:00
default:
return nil, fmt.Errorf(`unknown tag "%s"`, tag)
}
}