Skip to content

Commit b99d860

Browse files
committed
refactor: many tweaks
1 parent 8eb6a24 commit b99d860

18 files changed

Lines changed: 368 additions & 176 deletions

File tree

client/client.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,11 @@ func (c *Client[Req, Res]) Execute(execRequest execution.Request) (execution.Res
3030
delegations = append(delegations, execRequest.Metadata().Delegations()...)
3131
receipts = append(receipts, execRequest.Metadata().Receipts()...)
3232
}
33-
reqContainer, err := container.New(
33+
reqContainer := container.New(
3434
container.WithInvocations(invocations...),
3535
container.WithDelegations(delegations...),
3636
container.WithReceipts(receipts...),
3737
)
38-
if err != nil {
39-
return nil, fmt.Errorf("creating request container: %w", err)
40-
}
4138
request, err := c.Codec.Encode(reqContainer)
4239
if err != nil {
4340
return nil, fmt.Errorf("encoding container: %w", err)

client/http.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package client
22

33
import (
4+
"fmt"
45
"net/http"
56
"net/url"
67

@@ -26,7 +27,19 @@ func NewHTTP(serviceURL *url.URL, options ...HTTPOption) (*HTTPClient, error) {
2627
}
2728

2829
func (c *HTTPClient) Execute(execRequest execution.Request) (execution.Response, error) {
29-
return c.Client.Execute(execRequest)
30+
res, err := c.Client.Execute(execRequest)
31+
if err != nil {
32+
return nil, fmt.Errorf("executing request: %w", err)
33+
}
34+
httpMeta, ok := res.Metadata().(*transport.HTTPResponseContainer)
35+
if !ok {
36+
return nil, fmt.Errorf("expected HTTPResponseContainer, got %T", res.Metadata())
37+
}
38+
err = httpMeta.Response.Body.Close()
39+
if err != nil {
40+
return nil, fmt.Errorf("closing body: %w", err)
41+
}
42+
return res, nil
3043
}
3144

3245
type httpTransport struct {

examples/capability_definition_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"testing"
66

77
"github.com/alanshaw/ucantone/examples/types"
8-
"github.com/alanshaw/ucantone/ipld/datamodel"
8+
"github.com/alanshaw/ucantone/ipld"
99
"github.com/alanshaw/ucantone/principal/ed25519"
1010
"github.com/alanshaw/ucantone/ucan/delegation/policy"
1111
"github.com/alanshaw/ucantone/ucan/invocation"
@@ -41,7 +41,7 @@ func TestCapabilityDefinition(t *testing.T) {
4141
panic(err)
4242
}
4343

44-
args := datamodel.Map{
44+
args := ipld.Map{
4545
"to": []string{"bob@example.com"},
4646
"subject": "Hello!",
4747
"message": "Hello Bob, How do you do?",

examples/container_test.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,10 @@ func TestContainer(t *testing.T) {
5757
}
5858
fmt.Println("Invocation:", inv.Link())
5959

60-
ct, err := container.New(
60+
ct := container.New(
6161
container.WithDelegations(dlg),
6262
container.WithInvocations(inv),
6363
)
64-
if err != nil {
65-
panic(err)
66-
}
6764

6865
buf, err := container.Encode(container.Base64Gzip, ct)
6966
if err != nil {

examples/server_test.go

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package examples
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"net"
7+
"net/http"
8+
"net/url"
9+
"testing"
10+
11+
"github.com/alanshaw/ucantone/client"
12+
"github.com/alanshaw/ucantone/execution"
13+
"github.com/alanshaw/ucantone/ipld"
14+
"github.com/alanshaw/ucantone/principal/ed25519"
15+
"github.com/alanshaw/ucantone/result"
16+
"github.com/alanshaw/ucantone/server"
17+
"github.com/alanshaw/ucantone/ucan/invocation"
18+
"github.com/alanshaw/ucantone/validator/capability"
19+
)
20+
21+
func TestServer(t *testing.T) {
22+
echoCapability, err := capability.New("/example/echo")
23+
if err != nil {
24+
panic(err)
25+
}
26+
27+
serviceID, err := ed25519.Generate()
28+
if err != nil {
29+
panic(err)
30+
}
31+
32+
ucanSrv := server.NewHTTP(serviceID)
33+
34+
// Register an echo handler that returns the invocation arguments as the result
35+
ucanSrv.Handle(echoCapability, func(req execution.Request) (execution.Response, error) {
36+
return execution.NewResponse(execution.WithSuccess(req.Invocation().Arguments()))
37+
})
38+
39+
// Start the server on a random available port
40+
listener, err := net.Listen("tcp", ":0")
41+
if err != nil {
42+
panic(err)
43+
}
44+
45+
httpSrv := http.Server{Handler: ucanSrv}
46+
47+
go func() {
48+
err := httpSrv.Serve(listener)
49+
if err != nil && err != http.ErrServerClosed {
50+
panic(err)
51+
}
52+
}()
53+
54+
serviceURL, err := url.Parse("http://" + listener.Addr().String())
55+
if err != nil {
56+
panic(err)
57+
}
58+
fmt.Printf("UCAN Server is running at %s\n", serviceURL.String())
59+
60+
// Server is now running and can accept invocations!
61+
62+
alice, err := ed25519.Generate()
63+
if err != nil {
64+
panic(err)
65+
}
66+
67+
// Allow alice to invoke the echo capability
68+
dlg, err := echoCapability.Delegate(serviceID, alice, serviceID)
69+
if err != nil {
70+
panic(err)
71+
}
72+
73+
inv, err := echoCapability.Invoke(
74+
alice,
75+
serviceID,
76+
ipld.Map{"message": "Hello, UCAN!"},
77+
invocation.WithProofs(dlg.Link()),
78+
)
79+
if err != nil {
80+
panic(err)
81+
}
82+
83+
// create a client to send the invocation to the server
84+
c, err := client.NewHTTP(serviceURL)
85+
if err != nil {
86+
panic(err)
87+
}
88+
89+
resp, err := c.Execute(execution.NewRequest(context.Background(), inv, execution.WithProofs(dlg)))
90+
if err != nil {
91+
panic(err)
92+
}
93+
94+
result.MatchResultR0(
95+
resp.Result(),
96+
func(o ipld.Any) {
97+
fmt.Printf("Echo response: %v\n", o)
98+
},
99+
func(x ipld.Any) {
100+
fmt.Printf("Invocation failed: %v\n", x)
101+
},
102+
)
103+
104+
err = httpSrv.Shutdown(context.Background())
105+
if err != nil {
106+
panic(err)
107+
}
108+
}

execution/bindexec/handler.go

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,39 @@ type Success interface {
1919
}
2020

2121
type requestConfig struct {
22-
metadata ucan.Container
22+
invocations []ucan.Invocation
23+
delegations []ucan.Delegation
24+
receipts []ucan.Receipt
2325
}
2426

2527
type RequestOption = func(cfg *requestConfig)
2628

27-
func WithRequestMetadata(meta ucan.Container) RequestOption {
29+
// WithProofs adds delegations to the execution request. They should be linked
30+
// from the invocation to be executed.
31+
func WithProofs(delegations ...ucan.Delegation) RequestOption {
2832
return func(cfg *requestConfig) {
29-
cfg.metadata = meta
33+
cfg.delegations = append(cfg.delegations, delegations...)
34+
}
35+
}
36+
37+
// WithDelegations adds delegations to the execution request.
38+
func WithDelegations(delegations ...ucan.Delegation) RequestOption {
39+
return func(cfg *requestConfig) {
40+
cfg.delegations = append(cfg.delegations, delegations...)
41+
}
42+
}
43+
44+
// WithReceipts adds receipts to the execution request.
45+
func WithReceipts(receipts ...ucan.Receipt) RequestOption {
46+
return func(cfg *requestConfig) {
47+
cfg.receipts = append(cfg.receipts, receipts...)
48+
}
49+
}
50+
51+
// WithInvocations adds additional invocations to the execution request.
52+
func WithInvocations(invocations ...ucan.Invocation) RequestOption {
53+
return func(cfg *requestConfig) {
54+
cfg.invocations = append(cfg.invocations, invocations...)
3055
}
3156
}
3257

@@ -40,7 +65,15 @@ func NewRequest[A Arguments](ctx context.Context, inv ucan.Invocation, options .
4065
for _, opt := range options {
4166
opt(&cfg)
4267
}
43-
return Request[A]{Request: execution.NewRequest(ctx, inv, execution.WithRequestMetadata(cfg.metadata))}
68+
return Request[A]{
69+
Request: execution.NewRequest(
70+
ctx,
71+
inv,
72+
execution.WithInvocations(cfg.invocations...),
73+
execution.WithDelegations(cfg.delegations...),
74+
execution.WithReceipts(cfg.receipts...),
75+
),
76+
}
4477
}
4578

4679
func (r *Request[A]) Task() *Task[A] {

execution/dispatcher/dispatcher.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ func (d *Dispatcher) Handle(capability validator.Capability, fn execution.Handle
4242

4343
func (d *Dispatcher) Execute(req execution.Request) (execution.Response, error) {
4444
aud := req.Invocation().Audience()
45+
if aud == nil {
46+
aud = req.Invocation().Subject()
47+
}
4548
if aud.DID() != d.authority.DID() {
4649
return execution.NewResponse(
4750
execution.WithFailure(execution.NewInvalidAudienceError(d.authority, aud)),
@@ -54,12 +57,17 @@ func (d *Dispatcher) Execute(req execution.Request) (execution.Response, error)
5457
return execution.NewResponse(execution.WithFailure(NewHandlerNotFoundError(cmd)))
5558
}
5659

60+
opts := append([]validator.Option{}, d.validationOpts...)
61+
if req.Metadata() != nil {
62+
opts = append(opts, validator.WithProofs(req.Metadata().Delegations()...))
63+
}
64+
5765
_, err := validator.Access(
5866
req.Context(),
5967
d.authority,
6068
handler.Capability,
6169
req.Invocation(),
62-
d.validationOpts...,
70+
opts...,
6371
)
6472
if err != nil {
6573
return execution.NewResponse(execution.WithFailure(err))

execution/dispatcher/dispatcher_test.go

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"fmt"
55
"testing"
66

7-
"github.com/alanshaw/ucantone/errors"
87
"github.com/alanshaw/ucantone/execution"
98
"github.com/alanshaw/ucantone/execution/dispatcher"
109
"github.com/alanshaw/ucantone/ipld"
@@ -90,9 +89,7 @@ func TestDispatcher(t *testing.T) {
9089
require.NotNil(t, x)
9190
t.Log(x)
9291

93-
namedErr, ok := x.(errors.Named)
94-
require.True(t, ok)
95-
require.Equal(t, dispatcher.HandlerNotFoundErrorName, namedErr.Name())
92+
require.Equal(t, dispatcher.HandlerNotFoundErrorName, x.(ipld.Map)["name"])
9693
})
9794

9895
t.Run("invalid audience", func(t *testing.T) {
@@ -114,9 +111,7 @@ func TestDispatcher(t *testing.T) {
114111
require.NotNil(t, x)
115112
t.Log(x)
116113

117-
namedErr, ok := x.(errors.Named)
118-
require.True(t, ok)
119-
require.Equal(t, execution.InvalidAudienceErrorName, namedErr.Name())
114+
require.Equal(t, execution.InvalidAudienceErrorName, x.(ipld.Map)["name"])
120115
})
121116

122117
t.Run("handler execution error", func(t *testing.T) {
@@ -142,9 +137,7 @@ func TestDispatcher(t *testing.T) {
142137
require.NotNil(t, x)
143138
t.Log(x)
144139

145-
namedErr, ok := x.(errors.Named)
146-
require.True(t, ok)
147-
require.Equal(t, execution.HandlerExecutionErrorName, namedErr.Name())
140+
require.Equal(t, execution.HandlerExecutionErrorName, x.(ipld.Map)["name"])
148141
})
149142

150143
t.Run("validation error", func(t *testing.T) {
@@ -169,8 +162,6 @@ func TestDispatcher(t *testing.T) {
169162
require.NotNil(t, x)
170163
t.Log(x)
171164

172-
namedErr, ok := x.(errors.Named)
173-
require.True(t, ok)
174-
require.Equal(t, verrs.InvalidClaimErrorName, namedErr.Name())
165+
require.Equal(t, verrs.InvalidClaimErrorName, x.(ipld.Map)["name"])
175166
})
176167
}

0 commit comments

Comments
 (0)