86 lines
1.9 KiB
Go
86 lines
1.9 KiB
Go
package extargs
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
|
|
"github.com/ipld/go-ipld-prime"
|
|
"github.com/ipld/go-ipld-prime/datamodel"
|
|
"github.com/ipld/go-ipld-prime/fluent/qp"
|
|
"github.com/ipld/go-ipld-prime/node/basicnode"
|
|
|
|
"github.com/ucan-wg/go-ucan/pkg/args"
|
|
"github.com/ucan-wg/go-ucan/pkg/policy"
|
|
)
|
|
|
|
type CustomExtArgs struct {
|
|
key string
|
|
pol policy.Policy
|
|
originalArgs args.ReadOnly
|
|
assembler func(ma datamodel.MapAssembler)
|
|
|
|
once sync.Once
|
|
args *args.Args
|
|
argsIpld ipld.Node
|
|
}
|
|
|
|
func NewCustomExtArgs(key string, pol policy.Policy, assembler func(ma datamodel.MapAssembler)) *CustomExtArgs {
|
|
return &CustomExtArgs{key: key, pol: pol, assembler: assembler}
|
|
}
|
|
|
|
func (cea *CustomExtArgs) Verify() error {
|
|
if err := cea.makeArgs(); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Note: CustomExtArgs doesn't support verifying a hash computed client-side like the other
|
|
// external args, as the arguments are by nature dynamic. The client can't generate a meaningful hash.
|
|
|
|
ok, leaf := cea.pol.PartialMatch(cea.argsIpld)
|
|
if !ok {
|
|
return fmt.Errorf("the following UCAN policy is not satisfied: %v", leaf.String())
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (cea *CustomExtArgs) Args() (*args.Args, error) {
|
|
if err := cea.makeArgs(); err != nil {
|
|
return nil, err
|
|
}
|
|
return cea.args, nil
|
|
}
|
|
|
|
func (cea *CustomExtArgs) makeArgs() error {
|
|
var outerErr error
|
|
cea.once.Do(func() {
|
|
var err error
|
|
|
|
cea.args, err = makeCustomArgs(cea.key, cea.assembler)
|
|
if err != nil {
|
|
outerErr = err
|
|
return
|
|
}
|
|
|
|
cea.argsIpld, err = cea.args.ToIPLD()
|
|
if err != nil {
|
|
outerErr = err
|
|
return
|
|
}
|
|
})
|
|
return outerErr
|
|
}
|
|
|
|
func makeCustomArgs(key string, assembler func(ma datamodel.MapAssembler)) (*args.Args, error) {
|
|
n, err := qp.BuildMap(basicnode.Prototype.Any, -1, assembler)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
res := args.New()
|
|
err = res.Add(key, n)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return res, nil
|
|
}
|