Skip to content

Commit a7e698e

Browse files
committed
toolkit/client: fix FindProof to handle self-delegation properly
1 parent 4b3a0c5 commit a7e698e

File tree

3 files changed

+84
-17
lines changed

3 files changed

+84
-17
lines changed

token/invocation/invocation_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ func TestToken_ExecutionAllowed(t *testing.T) {
197197
cmd: delegationtest.NominalCommand,
198198
args: emptyArguments,
199199
proofs: []cid.Cid{delegationtest.TokenBobBobCID},
200-
err: invocation.ErrBrokenChain,
200+
err: invocation.ErrWrongSub,
201201
},
202202
} {
203203
t.Run(tc.name, func(t *testing.T) {
@@ -206,6 +206,8 @@ func TestToken_ExecutionAllowed(t *testing.T) {
206206
tkn, err := invocation.New(tc.issuer.DID(), tc.cmd, didtest.PersonaAlice.DID(), tc.proofs, tc.opts...)
207207
require.NoError(t, err)
208208

209+
t.Log(tkn.String())
210+
209211
err = tkn.ExecutionAllowed(delegationtest.GetDelegationLoader())
210212

211213
if tc.err != nil {

toolkit/client/proof.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ import (
2121
// Note: the returned delegation(s) don't have to match exactly the parameters, as long as they allow them.
2222
// Note: the implemented algorithm won't perform well with a large number of delegations.
2323
func FindProof(dlgs func() iter.Seq[*delegation.Bundle], issuer did.DID, cmd command.Command, subject did.DID) []cid.Cid {
24-
// TODO: maybe that should be part of delegation.Token directly?
25-
dlgMatch := func(dlg *delegation.Token, issuer did.DID, cmd command.Command, subject did.DID) bool {
24+
continuePath := func(dlg *delegation.Token, issuer did.DID, cmd command.Command, subject did.DID) bool {
2625
// The Subject of each delegation must equal the invocation's Subject (or Audience if defined). - 4f
2726
if !dlg.Subject().Equal(subject) {
2827
return false
@@ -47,7 +46,7 @@ func FindProof(dlgs func() iter.Seq[*delegation.Bundle], issuer did.DID, cmd com
4746
var candidateLeaf []*delegation.Bundle
4847

4948
for bundle := range dlgs() {
50-
if !dlgMatch(bundle.Decoded, issuer, cmd, subject) {
49+
if !continuePath(bundle.Decoded, issuer, cmd, subject) {
5150
continue
5251
}
5352
candidateLeaf = append(candidateLeaf, bundle)
@@ -83,7 +82,12 @@ func FindProof(dlgs func() iter.Seq[*delegation.Bundle], issuer did.DID, cmd com
8382

8483
// find parent delegation for our current delegation
8584
for candidate := range dlgs() {
86-
if !dlgMatch(candidate.Decoded, at.Decoded.Issuer(), at.Decoded.Command(), subject) {
85+
// Prune the delegations that don't match the current proof.
86+
if !continuePath(candidate.Decoded, at.Decoded.Issuer(), at.Decoded.Command(), subject) {
87+
continue
88+
}
89+
// Prune the self-delegations as they can't get us closer to what we are looking for.
90+
if candidate.Decoded.Issuer().Equal(candidate.Decoded.Audience()) {
8791
continue
8892
}
8993

toolkit/client/proof_test.go

Lines changed: 73 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import (
44
"iter"
55
"testing"
66

7+
"github.com/MetaMask/go-did-it"
78
"github.com/MetaMask/go-did-it/didtest"
9+
"github.com/ipfs/go-cid"
810
"github.com/stretchr/testify/require"
911

1012
"github.com/ucan-wg/go-ucan/pkg/command"
@@ -23,17 +25,76 @@ func TestFindProof(t *testing.T) {
2325
}
2426
}
2527

26-
require.Equal(t, delegationtest.ProofAliceBob,
27-
FindProof(dlgs, didtest.PersonaBob.DID(), delegationtest.NominalCommand, didtest.PersonaAlice.DID()))
28-
require.Equal(t, delegationtest.ProofAliceBobCarol,
29-
FindProof(dlgs, didtest.PersonaCarol.DID(), delegationtest.NominalCommand, didtest.PersonaAlice.DID()))
30-
require.Equal(t, delegationtest.ProofAliceBobCarolDan,
31-
FindProof(dlgs, didtest.PersonaDan.DID(), delegationtest.NominalCommand, didtest.PersonaAlice.DID()))
32-
require.Equal(t, delegationtest.ProofAliceBobCarolDanErin,
33-
FindProof(dlgs, didtest.PersonaErin.DID(), delegationtest.NominalCommand, didtest.PersonaAlice.DID()))
34-
require.Equal(t, delegationtest.ProofAliceBobCarolDanErinFrank,
35-
FindProof(dlgs, didtest.PersonaFrank.DID(), delegationtest.NominalCommand, didtest.PersonaAlice.DID()))
28+
for _, tc := range []struct {
29+
name string
30+
issuer did.DID
31+
command command.Command
32+
subject did.DID
33+
expected []cid.Cid
34+
}{
35+
// Passes
36+
{
37+
name: "Alice --> Alice (self-delegation)",
38+
issuer: didtest.PersonaAlice.DID(),
39+
command: delegationtest.NominalCommand,
40+
subject: didtest.PersonaAlice.DID(),
41+
expected: []cid.Cid{delegationtest.TokenAliceAliceCID},
42+
},
43+
{
44+
name: "Alice --> Bob",
45+
issuer: didtest.PersonaBob.DID(),
46+
command: delegationtest.NominalCommand,
47+
subject: didtest.PersonaAlice.DID(),
48+
expected: delegationtest.ProofAliceBob,
49+
},
50+
{
51+
name: "Alice --> Bob --> Carol",
52+
issuer: didtest.PersonaCarol.DID(),
53+
command: delegationtest.NominalCommand,
54+
subject: didtest.PersonaAlice.DID(),
55+
expected: delegationtest.ProofAliceBobCarol,
56+
},
57+
{
58+
name: "Alice --> Bob --> Carol --> Dan",
59+
issuer: didtest.PersonaDan.DID(),
60+
command: delegationtest.NominalCommand,
61+
subject: didtest.PersonaAlice.DID(),
62+
expected: delegationtest.ProofAliceBobCarolDan,
63+
},
64+
{
65+
name: "Alice --> Bob --> Carol --> Dan --> Erin",
66+
issuer: didtest.PersonaErin.DID(),
67+
command: delegationtest.NominalCommand,
68+
subject: didtest.PersonaAlice.DID(),
69+
expected: delegationtest.ProofAliceBobCarolDanErin,
70+
},
71+
{
72+
name: "Alice --> Bob --> Carol --> Dan --> Erin --> Frank",
73+
issuer: didtest.PersonaFrank.DID(),
74+
command: delegationtest.NominalCommand,
75+
subject: didtest.PersonaAlice.DID(),
76+
expected: delegationtest.ProofAliceBobCarolDanErinFrank,
77+
},
3678

37-
// wrong command
38-
require.Empty(t, FindProof(dlgs, didtest.PersonaBob.DID(), command.New("foo"), didtest.PersonaAlice.DID()))
79+
// Fails
80+
{
81+
name: "wrong command",
82+
issuer: didtest.PersonaBob.DID(),
83+
command: command.New("foo"),
84+
subject: didtest.PersonaAlice.DID(),
85+
expected: nil,
86+
},
87+
{
88+
name: "wrong subject",
89+
issuer: didtest.PersonaBob.DID(),
90+
command: delegationtest.NominalCommand,
91+
subject: didtest.PersonaDan.DID(),
92+
expected: nil,
93+
},
94+
} {
95+
t.Run(tc.name, func(t *testing.T) {
96+
res := FindProof(dlgs, tc.issuer, tc.command, tc.subject)
97+
require.Equal(t, tc.expected, res)
98+
})
99+
}
39100
}

0 commit comments

Comments
 (0)