container: Reader should keep around and expose the sealed bytes

This commit is contained in:
Michael Muré
2025-01-23 17:12:26 +01:00
parent e218b49577
commit 9d047f038d
6 changed files with 83 additions and 29 deletions

View File

@@ -21,7 +21,12 @@ var ErrNotFound = fmt.Errorf("not found")
var ErrMultipleInvocations = fmt.Errorf("multiple invocations")
// Reader is a token container reader. It exposes the tokens conveniently decoded.
type Reader map[cid.Cid]token.Token
type Reader map[cid.Cid]bundle
type bundle struct {
sealed []byte
token token.Token
}
// FromBytes decodes a container from a []byte
func FromBytes(data []byte) (Reader, error) {
@@ -92,11 +97,36 @@ func FromReader(r io.Reader) (Reader, error) {
// GetToken returns an arbitrary decoded token, from its CID.
// If not found, ErrNotFound is returned.
func (ctn Reader) GetToken(cid cid.Cid) (token.Token, error) {
tkn, ok := ctn[cid]
bndl, ok := ctn[cid]
if !ok {
return nil, ErrNotFound
}
return tkn, nil
return bndl.token, nil
}
// GetSealed returns an arbitrary sealed token, from its CID.
// If not found, ErrNotFound is returned.
func (ctn Reader) GetSealed(cid cid.Cid) ([]byte, error) {
bndl, ok := ctn[cid]
if !ok {
return nil, ErrNotFound
}
return bndl.sealed, nil
}
// GetAllTokens return all the tokens in the container.
func (ctn Reader) GetAllTokens() iter.Seq[token.Bundle[token.Token]] {
return func(yield func(token.Bundle[token.Token]) bool) {
for c, bndl := range ctn {
if !yield(token.Bundle[token.Token]{
Cid: c,
Decoded: bndl.token,
Sealed: bndl.sealed,
}) {
return
}
}
}
}
// GetDelegation is the same as GetToken but only return a delegation.Token, with the right type.
@@ -113,11 +143,15 @@ func (ctn Reader) GetDelegation(cid cid.Cid) (*delegation.Token, error) {
}
// GetAllDelegations returns all the delegation.Token in the container.
func (ctn Reader) GetAllDelegations() iter.Seq2[cid.Cid, *delegation.Token] {
return func(yield func(cid.Cid, *delegation.Token) bool) {
for c, t := range ctn {
if t, ok := t.(*delegation.Token); ok {
if !yield(c, t) {
func (ctn Reader) GetAllDelegations() iter.Seq[token.Bundle[*delegation.Token]] {
return func(yield func(token.Bundle[*delegation.Token]) bool) {
for c, bndl := range ctn {
if t, ok := bndl.token.(*delegation.Token); ok {
if !yield(token.Bundle[*delegation.Token]{
Cid: c,
Decoded: t,
Sealed: bndl.sealed,
}) {
return
}
}
@@ -130,8 +164,8 @@ func (ctn Reader) GetAllDelegations() iter.Seq2[cid.Cid, *delegation.Token] {
// If more than one invocation exists, ErrMultipleInvocations is returned.
func (ctn Reader) GetInvocation() (*invocation.Token, error) {
var res *invocation.Token
for _, t := range ctn {
if inv, ok := t.(*invocation.Token); ok {
for _, bndl := range ctn {
if inv, ok := bndl.token.(*invocation.Token); ok {
if res != nil {
return nil, ErrMultipleInvocations
}
@@ -145,11 +179,15 @@ func (ctn Reader) GetInvocation() (*invocation.Token, error) {
}
// GetAllInvocations returns all the invocation.Token in the container.
func (ctn Reader) GetAllInvocations() iter.Seq2[cid.Cid, *invocation.Token] {
return func(yield func(cid.Cid, *invocation.Token) bool) {
for c, t := range ctn {
if t, ok := t.(*invocation.Token); ok {
if !yield(c, t) {
func (ctn Reader) GetAllInvocations() iter.Seq[token.Bundle[*invocation.Token]] {
return func(yield func(token.Bundle[*invocation.Token]) bool) {
for c, bndl := range ctn {
if t, ok := bndl.token.(*invocation.Token); ok {
if !yield(token.Bundle[*invocation.Token]{
Cid: c,
Decoded: t,
Sealed: bndl.sealed,
}) {
return
}
}
@@ -162,6 +200,19 @@ func (ctn Reader) addToken(data []byte) error {
if err != nil {
return err
}
ctn[c] = tkn
ctn[c] = bundle{
sealed: data,
token: tkn,
}
return nil
}
// ToWriter convert a container Reader into a Writer.
// Most likely, you only want to use this in tests for convenience.
func (ctn Reader) ToWriter() Writer {
writer := NewWriter()
for _, bndl := range ctn {
writer.AddSealed(bndl.sealed)
}
return writer
}

View File

@@ -217,6 +217,7 @@ func (g *generator) writeGoFile() error {
Println("import (")
Println("\t\"github.com/ipfs/go-cid\"")
Println()
Println("\t\"github.com/ucan-wg/go-ucan/token\"")
Println("\t\"github.com/ucan-wg/go-ucan/token/delegation\"")
Println(")")
@@ -242,7 +243,7 @@ func (g *generator) writeGoFile() error {
Println("}")
Println()
Println("var AllBundles = []*delegation.Bundle{")
Println("var AllBundles = []token.Bundle[*delegation.Token]{")
for _, d := range g.dlgs {
Printf("\t%sBundle,\n", d.name)
}

View File

@@ -8,6 +8,7 @@ import (
"github.com/ipfs/go-cid"
"github.com/ucan-wg/go-ucan/pkg/command"
"github.com/ucan-wg/go-ucan/token"
"github.com/ucan-wg/go-ucan/token/delegation"
)
@@ -38,7 +39,7 @@ var fs embed.FS
var _ delegation.Loader = (*DelegationLoader)(nil)
type DelegationLoader struct {
bundles map[cid.Cid]*delegation.Bundle
bundles map[cid.Cid]token.Bundle[*delegation.Token]
}
var (
@@ -75,7 +76,7 @@ func loadDelegations() (*DelegationLoader, error) {
return nil, err
}
bundles := make(map[cid.Cid]*delegation.Bundle, len(dirEntries))
bundles := make(map[cid.Cid]token.Bundle[*delegation.Token], len(dirEntries))
for _, dirEntry := range dirEntries {
data, err := fs.ReadFile(filepath.Join(TokenDir, dirEntry.Name()))
@@ -88,7 +89,7 @@ func loadDelegations() (*DelegationLoader, error) {
return nil, err
}
bundles[id] = &delegation.Bundle{Cid: id, Decoded: tkn, Sealed: data}
bundles[id] = token.Bundle[*delegation.Token]{Cid: id, Decoded: tkn, Sealed: data}
}
return &DelegationLoader{
@@ -106,7 +107,7 @@ func CidToName(id cid.Cid) string {
return cidToName[id]
}
func mustGetBundle(id cid.Cid) *delegation.Bundle {
func mustGetBundle(id cid.Cid) token.Bundle[*delegation.Token] {
bundle, ok := GetDelegationLoader().bundles[id]
if !ok {
panic(delegation.ErrDelegationNotFound)

View File

@@ -5,6 +5,7 @@ package delegationtest
import (
"github.com/ipfs/go-cid"
"github.com/ucan-wg/go-ucan/token"
"github.com/ucan-wg/go-ucan/token/delegation"
)
@@ -195,7 +196,7 @@ var AllTokens = []*delegation.Token{
TokenErinFrank_ValidExamplePolicy,
}
var AllBundles = []*delegation.Bundle{
var AllBundles = []token.Bundle[*delegation.Token]{
TokenAliceBobBundle,
TokenBobCarolBundle,
TokenCarolDanBundle,

View File

@@ -15,10 +15,3 @@ type Loader interface {
// If not found, ErrDelegationNotFound is returned.
GetDelegation(cid cid.Cid) (*Token, error)
}
// Bundle carries together a decoded delegation with its Cid and raw signed data.
type Bundle struct {
Cid cid.Cid
Decoded *Token
Sealed []byte
}

View File

@@ -39,3 +39,10 @@ type Marshaller interface {
// ToDagJsonWriter is the same as ToDagJson, but it accepts an io.Writer.
ToDagJsonWriter(w io.Writer, privKey crypto.PrivKey) error
}
// Bundle carries together a decoded token with its Cid and raw signed data.
type Bundle[T Token] struct {
Cid cid.Cid
Decoded T
Sealed []byte
}