Skip to content

Commit 7af8de6

Browse files
committed
fix: some container fixes
1 parent 8a02d55 commit 7af8de6

8 files changed

Lines changed: 93 additions & 28 deletions

File tree

ipld/codec/dagcbor/dagcbor.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package dagcbor
22

3-
import cbg "github.com/whyrusleeping/cbor-gen"
3+
import (
4+
cbg "github.com/whyrusleeping/cbor-gen"
5+
)
6+
7+
const Code = 0x71
48

59
type CBORMarshaler = cbg.CBORMarshaler
610
type CBORUnmarshaler = cbg.CBORUnmarshaler

ucan/container/container.go

Lines changed: 71 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@ import (
77
"errors"
88
"fmt"
99
"io"
10+
"slices"
1011

1112
"github.com/alanshaw/ucantone/ucan"
1213
"github.com/alanshaw/ucantone/ucan/container/datamodel"
14+
"github.com/alanshaw/ucantone/ucan/delegation"
1315
"github.com/alanshaw/ucantone/ucan/invocation"
1416
"github.com/ipfs/go-cid"
17+
"github.com/multiformats/go-multihash"
1518
)
1619

1720
const (
@@ -46,21 +49,36 @@ func FormatCodec(codec byte) string {
4649
}
4750

4851
type Container struct {
52+
model *datamodel.ContainerModel
4953
invs []ucan.Invocation
5054
rcpts []ucan.Receipt
5155
dlgs []ucan.Delegation
5256
}
5357

54-
func (c *Container) Invocations() []ucan.Invocation {
55-
return c.invs
56-
}
57-
5858
func (c *Container) Delegations() []ucan.Delegation {
5959
return c.dlgs
6060
}
6161

6262
func (c *Container) Delegation(root cid.Cid) (ucan.Delegation, error) {
63-
panic("not implemented")
63+
for _, b := range c.model.Ctn1 {
64+
digest, err := multihash.Sum(b, multihash.SHA2_256, -1)
65+
if err != nil {
66+
return nil, err
67+
}
68+
if bytes.Equal(root.Hash(), digest) {
69+
return delegation.Decode(b)
70+
}
71+
}
72+
return nil, ErrNotFound
73+
}
74+
75+
func (c *Container) Invocations() []ucan.Invocation {
76+
return c.invs
77+
}
78+
79+
// The datamodel this container is built from.
80+
func (c *Container) Model() *datamodel.ContainerModel {
81+
return c.model
6482
}
6583

6684
func (c *Container) Receipts() []ucan.Receipt {
@@ -98,13 +116,38 @@ func WithReceipts(receipts ...ucan.Receipt) Option {
98116
}
99117
}
100118

101-
// TODO: create and store model on container and add accessor (`Model()`)
102-
func New(options ...Option) *Container {
119+
func New(options ...Option) (*Container, error) {
103120
ct := Container{}
104121
for _, opt := range options {
105122
opt(&ct)
106123
}
107-
return &ct
124+
125+
var tokens [][]byte
126+
for _, inv := range ct.invs {
127+
b, err := invocation.Encode(inv)
128+
if err != nil {
129+
return nil, fmt.Errorf("encoding invocation: %w", err)
130+
}
131+
tokens = append(tokens, b)
132+
}
133+
for _, dlg := range ct.dlgs {
134+
b, err := delegation.Encode(dlg)
135+
if err != nil {
136+
return nil, fmt.Errorf("encoding delegation: %w", err)
137+
}
138+
tokens = append(tokens, b)
139+
}
140+
slices.SortFunc(tokens, bytes.Compare)
141+
142+
model := datamodel.ContainerModel{Ctn1: tokens}
143+
var buf bytes.Buffer
144+
err := model.MarshalCBOR(&buf)
145+
if err != nil {
146+
return nil, fmt.Errorf("marshaling container to CBOR: %w", err)
147+
}
148+
ct.model = &model
149+
150+
return &ct, nil
108151
}
109152

110153
func Encode(codec byte, container ucan.Container) ([]byte, error) {
@@ -116,20 +159,22 @@ func Encode(codec byte, container ucan.Container) ([]byte, error) {
116159
}
117160
tokens = append(tokens, b)
118161
}
119-
// for _, dlg := range container.Delegations() {
120-
// b, err := delegation.Encode(dlg)
121-
// if err != nil {
122-
// return nil, fmt.Errorf("encoding delegation: %w", err)
123-
// }
124-
// tokens = append(tokens, b)
125-
// }
162+
for _, dlg := range container.Delegations() {
163+
b, err := delegation.Encode(dlg)
164+
if err != nil {
165+
return nil, fmt.Errorf("encoding delegation: %w", err)
166+
}
167+
tokens = append(tokens, b)
168+
}
126169
// for _, rcpt := range container.Receipts() {
127170
// b, err := receipt.Encode(rcpt)
128171
// if err != nil {
129172
// return nil, fmt.Errorf("encoding receipt: %w", err)
130173
// }
131174
// tokens = append(tokens, b)
132175
// }
176+
slices.SortFunc(tokens, bytes.Compare)
177+
133178
model := datamodel.ContainerModel{Ctn1: tokens}
134179
var buf bytes.Buffer
135180
err := model.MarshalCBOR(&buf)
@@ -213,10 +258,14 @@ func Decode(input []byte) (*Container, error) {
213258
return nil, fmt.Errorf("unmarshalling container from CBOR: %w", err)
214259
}
215260

261+
var dlgs []ucan.Delegation
216262
var invs []ucan.Invocation
217263
var rcpts []ucan.Receipt
218-
var dlgs []ucan.Delegation
219264
for _, b := range model.Ctn1 {
265+
if dlg, err := delegation.Decode(b); err == nil {
266+
dlgs = append(dlgs, dlg)
267+
continue
268+
}
220269
if inv, err := invocation.Decode(b); err == nil {
221270
invs = append(invs, inv)
222271
continue
@@ -226,11 +275,12 @@ func Decode(input []byte) (*Container, error) {
226275
// rcpts = append(rcpts, rcpt)
227276
// continue
228277
// }
229-
// if dlg, err := delegation.Decode(b); err != nil {
230-
// dlgs = append(dlgs, dlg)
231-
// continue
232-
// }
233278
}
234279

235-
return New(WithInvocations(invs...), WithDelegations(dlgs...), WithReceipts(rcpts...)), nil
280+
return &Container{
281+
model: model,
282+
invs: invs,
283+
dlgs: dlgs,
284+
rcpts: rcpts,
285+
}, nil
236286
}

ucan/container/container_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ func TestContainer(t *testing.T) {
2929
inv, err := invocation.Invoke(issuer, subject, command, arguments)
3030
require.NoError(t, err)
3131

32-
initial := container.New(container.WithInvocations(inv))
32+
initial, err := container.New(container.WithInvocations(inv))
33+
require.NoError(t, err)
3334

3435
bytes, err := container.Encode(code, initial)
3536
require.NoError(t, err)

ucan/delegation/datamodel/delegation.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ import (
77
cbg "github.com/whyrusleeping/cbor-gen"
88
)
99

10+
const Tag = "ucan/dlg@1.0.0-rc.1"
11+
1012
type TokenPayloadModel1_0_0_rc1 struct {
1113
// Issuer DID (sender).
1214
Iss did.DID `cborgen:"iss"`
1315
// The DID of the intended Executor if different from the Subject.
1416
Aud did.DID `cborgen:"aud"`
1517
// The principal the chain is about.
16-
Sub ucan.Subject `cborgen:"sub"`
18+
Sub did.DID `cborgen:"sub"`
1719
// The command to eventually invoke.
1820
Cmd ucan.Command `cborgen:"cmd"`
1921
// TODO

ucan/delegation/delegation.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ func (d *Delegation) Signature() ucan.Signature {
9494
// https://github.com/ucan-wg/delegation/blob/main/README.md#subject
9595
func (d *Delegation) Subject() ucan.Principal {
9696
sub := d.model.SigPayload.TokenPayload1_0_0_rc1.Sub
97-
if sub == (ucan.Subject{}) {
97+
if sub == (did.DID{}) {
9898
return nil
9999
}
100100
return sub
@@ -159,6 +159,9 @@ func Decode(data []byte) (*Delegation, error) {
159159
if err != nil {
160160
return nil, fmt.Errorf("unmarshaling delegation envelope CBOR: %w", err)
161161
}
162+
if model.SigPayload.TokenPayload1_0_0_rc1 == nil {
163+
return nil, errors.New("invalid or unsupported delegation token payload")
164+
}
162165
header, err := varsig.Decode(model.SigPayload.Header)
163166
if err != nil {
164167
return nil, fmt.Errorf("decoding varsig header: %w", err)

ucan/invocation/datamodel/invocation.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ import (
88
cbg "github.com/whyrusleeping/cbor-gen"
99
)
1010

11+
const Tag = "ucan/inv@1.0.0-rc.1"
12+
1113
type TokenPayloadModel1_0_0_rc1 struct {
1214
// Issuer DID (sender).
1315
Iss did.DID `cborgen:"iss"`
1416
// The Subject being invoked.
15-
Sub ucan.Subject `cborgen:"sub"`
17+
Sub did.DID `cborgen:"sub"`
1618
// The DID of the intended Executor if different from the Subject.
1719
Aud *did.DID `cborgen:"aud,omitempty"`
1820
// The command to invoke.

ucan/invocation/invocation.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,9 @@ func Decode(data []byte) (*Invocation, error) {
208208
if err != nil {
209209
return nil, fmt.Errorf("unmarshaling invocation envelope CBOR: %w", err)
210210
}
211+
if model.SigPayload.TokenPayload1_0_0_rc1 == nil {
212+
return nil, errors.New("invalid or unsupported invocation token payload")
213+
}
211214
header, err := varsig.Decode(model.SigPayload.Header)
212215
if err != nil {
213216
return nil, fmt.Errorf("decoding varsig header: %w", err)
@@ -308,7 +311,7 @@ func Invoke(
308311

309312
tokenPayload := &idm.TokenPayloadModel1_0_0_rc1{
310313
Iss: issuer.DID(),
311-
Sub: subject,
314+
Sub: subject.DID(),
312315
Aud: cfg.aud,
313316
Cmd: cmd,
314317
Args: args,

ucan/ucan.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import (
1616
// the Agent that a capability is for. A Subject MUST be referenced by DID.
1717
//
1818
// https://github.com/ucan-wg/spec/blob/main/README.md#subject
19-
type Subject = did.DID
19+
type Subject = Principal
2020

2121
// Commands are concrete messages ("verbs") that MUST be unambiguously
2222
// interpretable by the Subject of a UCAN.

0 commit comments

Comments
 (0)