Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 148 additions & 0 deletions commands/principal/cbor_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

79 changes: 79 additions & 0 deletions commands/principal/codec_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//go:build !codegen

package principal_test

import (
"bytes"
"reflect"
"testing"

"github.com/fil-forge/libforge/commands/principal"
"github.com/fil-forge/ucantone/binding"
"github.com/fil-forge/ucantone/did"
"github.com/fil-forge/ucantone/execution"
"github.com/fil-forge/ucantone/testutil"
"github.com/fil-forge/ucantone/ucan/invocation"
"github.com/stretchr/testify/require"
)

var tenant = did.MustParse("did:plc:ewvi7nxzyoun6zhxrhs64oiz")

func TestInvalidateArgumentsRoundTrip(t *testing.T) {
in := &principal.InvalidateArguments{
Tenant: tenant,
Principal: "8f2c9e14",
}

var cb bytes.Buffer
require.NoError(t, in.MarshalCBOR(&cb))
var outCBOR principal.InvalidateArguments
require.NoError(t, outCBOR.UnmarshalCBOR(bytes.NewReader(cb.Bytes())))
require.True(t, reflect.DeepEqual(*in, outCBOR), "CBOR round-trip mismatch:\n got %#v\nwant %#v", outCBOR, *in)

var jb bytes.Buffer
require.NoError(t, in.MarshalDagJSON(&jb))
require.Equal(t, `{"principal":"8f2c9e14","tenant":"`+tenant.String()+`"}`, jb.String())
var outJSON principal.InvalidateArguments
require.NoError(t, outJSON.UnmarshalDagJSON(bytes.NewReader(jb.Bytes())), "json: %s", jb.String())
require.True(t, reflect.DeepEqual(*in, outJSON), "DAG-JSON round-trip mismatch:\n got %#v\nwant %#v", outJSON, *in)
}

// The command is self-signed: Hilt is both issuer and subject, because no
// delegation names a principal and Swarf authorizes the invocation from its
// publisher list instead of a proof chain.
func TestInvalidateInvokeUnpack(t *testing.T) {
hilt := testutil.RandomIssuer(t)
swarf := testutil.RandomIssuer(t)

args := &principal.InvalidateArguments{Tenant: tenant, Principal: "8f2c9e14"}
inv, err := principal.Invalidate.Invoke(
hilt,
hilt.DID(),
args,
invocation.WithAudience(swarf.DID()),
invocation.WithNoNonce(),
invocation.WithNoExpiration(),
)
require.NoError(t, err)
require.Equal(t, "/principal/invalidate", inv.Command().String())
require.Equal(t, hilt.DID(), inv.Issuer())
require.Equal(t, hilt.DID(), inv.Subject())
require.Equal(t, swarf.DID(), inv.Audience())
require.Empty(t, inv.Proofs())

var seen *principal.InvalidateArguments
handler := principal.Invalidate.Handler(func(req *binding.Request[*principal.InvalidateArguments], res *binding.Response[*principal.InvalidateOK]) error {
seen = req.Task().Arguments()
return res.SetSuccess(&principal.InvalidateOK{})
})

res, err := execution.NewResponse(inv.Task().Link(), execution.WithIssuer(swarf))
require.NoError(t, err)
require.NoError(t, handler(execution.NewRequest(t.Context(), inv), res))

require.Equal(t, args, seen)

out, err := principal.Invalidate.Unpack(res.Receipt())
require.NoError(t, err)
require.Equal(t, &principal.InvalidateOK{}, out)
}
41 changes: 41 additions & 0 deletions commands/principal/gen/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//go:generate go run -tags codegen .

package main

import (
"os"

jsg "github.com/alanshaw/dag-json-gen"
"github.com/fil-forge/libforge/commands/principal"
cbg "github.com/whyrusleeping/cbor-gen"
)

const buildTag = "//go:build !codegen\n\n"

func tag(path string) {
data, err := os.ReadFile(path)
if err != nil {
panic(err)
}
if err := os.WriteFile(path, append([]byte(buildTag), data...), 0644); err != nil {
panic(err)
}
}

func main() {
models := []any{
principal.InvalidateArguments{},
}
const (
cborFile = "../cbor_gen.go"
jsonFile = "../json_gen.go"
)
if err := cbg.WriteMapEncodersToFile(cborFile, "principal", models...); err != nil {
panic(err)
}
if err := jsg.WriteMapEncodersToFile(jsonFile, "principal", models...); err != nil {
panic(err)
}
tag(cborFile)
tag(jsonFile)
}
19 changes: 19 additions & 0 deletions commands/principal/invalidate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//go:build !codegen

package principal

import (
"github.com/fil-forge/libforge/commands"
"github.com/fil-forge/ucantone/binding"
"github.com/fil-forge/ucantone/ucan/command"
)

type InvalidateOK = commands.Unit

// Invalidate is the `/principal/invalidate` command. Hilt invokes it on Swarf
// as its service identity before it commits a change to what a principal can
// reach, recording that every proof a gateway cached for that principal's
// access keys is void. No delegation names a principal, so there is no proof
// chain to carry the authority: Swarf accepts the command only from issuers in
// its publisher list.
var Invalidate = binding.Bind[*InvalidateArguments, *InvalidateOK](command.MustParse("/principal/invalidate"))
Loading