feat(delegation): update to provide encoding/decoding straight from/to View
This commit is contained in:
1
delegation/delegation.go
Normal file
1
delegation/delegation.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package delegation
|
||||||
142
delegation/delegation_test.go
Normal file
142
delegation/delegation_test.go
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
package delegation_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/libp2p/go-libp2p/core/crypto"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/ucan-wg/go-ucan/did"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
nonce = "6roDhGi0kiNriQAz7J3d+bOeoI/tj8ENikmQNbtjnD0"
|
||||||
|
|
||||||
|
AudiencePrivKeyCfg = "CAESQL1hvbXpiuk2pWr/XFbfHJcZNpJ7S90iTA3wSCTc/BPRneCwPnCZb6c0vlD6ytDWqaOt0HEOPYnqEpnzoBDprSM="
|
||||||
|
AudienceDID = "did:key:z6Mkq5YmbJcTrPExNDi26imrTCpKhepjBFBSHqrBDN2ArPkv"
|
||||||
|
|
||||||
|
issuerPrivKeyCfg = "CAESQLSql38oDmQXIihFFaYIjb73mwbPsc7MIqn4o8PN4kRNnKfHkw5gRP1IV9b6d0estqkZayGZ2vqMAbhRixjgkDU="
|
||||||
|
issuerDID = "did:key:z6Mkpzn2n3ZGT2VaqMGSQC3tzmzV4TS9S71iFsDXE1WnoNH2"
|
||||||
|
|
||||||
|
subjectPrivKeyCfg = "CAESQL9RtjZ4dQBeXtvDe53UyvslSd64kSGevjdNiA1IP+hey5i/3PfRXSuDr71UeJUo1fLzZ7mGldZCOZL3gsIQz5c="
|
||||||
|
subjectDID = "did:key:z6MktA1uBdCpq4uJBqE9jjMiLyxZBg9a6xgPPKJjMqss6Zc2"
|
||||||
|
subJectCmd = "/foo/bar"
|
||||||
|
subjectPol = `
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"==",
|
||||||
|
".status",
|
||||||
|
"draft"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"all",
|
||||||
|
".reviewer",
|
||||||
|
[
|
||||||
|
"like",
|
||||||
|
".email",
|
||||||
|
"*@example.com"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"any",
|
||||||
|
".tags",
|
||||||
|
[
|
||||||
|
"or",
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"==",
|
||||||
|
".",
|
||||||
|
"news"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"==",
|
||||||
|
".",
|
||||||
|
"press"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
`
|
||||||
|
)
|
||||||
|
|
||||||
|
// func TestConstructors(t *testing.T) {
|
||||||
|
// t.Parallel()
|
||||||
|
|
||||||
|
// privKey := privKey(t, issuerPrivKeyCfg)
|
||||||
|
|
||||||
|
// aud, err := did.Parse(AudienceDID)
|
||||||
|
|
||||||
|
// sub, err := did.Parse(subjectDID)
|
||||||
|
// require.NoError(t, err)
|
||||||
|
|
||||||
|
// cmd, err := command.Parse(subJectCmd)
|
||||||
|
// require.NoError(t, err)
|
||||||
|
|
||||||
|
// pol, err := policy.FromDagJson(subjectPol)
|
||||||
|
// require.NoError(t, err)
|
||||||
|
|
||||||
|
// exp := time.Time{}
|
||||||
|
|
||||||
|
// meta := map[string]datamodel.Node{
|
||||||
|
// "foo": basicnode.NewString("fooo"),
|
||||||
|
// "bar": basicnode.NewString("barr"),
|
||||||
|
// }
|
||||||
|
|
||||||
|
// t.Run("New", func(t *testing.T) {
|
||||||
|
// dlg, err := delegation.New(privKey, aud, &sub, cmd, pol, []byte(nonce), delegation.WithExpiration(&exp), delegation.WithMeta(meta))
|
||||||
|
// require.NoError(t, err)
|
||||||
|
|
||||||
|
// data, err := dlg.ToDagJson()
|
||||||
|
// require.NoError(t, err)
|
||||||
|
|
||||||
|
// t.Log(string(data))
|
||||||
|
|
||||||
|
// golden.Assert(t, string(data), "new.dagjson")
|
||||||
|
// })
|
||||||
|
|
||||||
|
// t.Run("Root", func(t *testing.T) {
|
||||||
|
// t.Parallel()
|
||||||
|
|
||||||
|
// dlg, err := delegation.Root(privKey, aud, cmd, pol, []byte(nonce), delegation.WithExpiration(&exp), delegation.WithMeta(meta))
|
||||||
|
// require.NoError(t, err)
|
||||||
|
|
||||||
|
// data, err := dlg.ToDagJson()
|
||||||
|
// require.NoError(t, err)
|
||||||
|
|
||||||
|
// t.Log(string(data))
|
||||||
|
|
||||||
|
// golden.Assert(t, string(data), "root.dagjson")
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
|
func privKey(t *testing.T, privKeyCfg string) crypto.PrivKey {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
privKeyMar, err := crypto.ConfigDecodeKey(privKeyCfg)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
privKey, err := crypto.UnmarshalPrivateKey(privKeyMar)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
return privKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestKey(t *testing.T) {
|
||||||
|
t.Skip()
|
||||||
|
|
||||||
|
priv, _, err := crypto.GenerateEd25519Key(rand.Reader)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
privMar, err := crypto.MarshalPrivateKey(priv)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
privCfg := crypto.ConfigEncodeKey(privMar)
|
||||||
|
t.Log(privCfg)
|
||||||
|
|
||||||
|
id, err := did.FromPubKey(priv.GetPublic())
|
||||||
|
require.NoError(t, err)
|
||||||
|
t.Log(id)
|
||||||
|
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
package delegation
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/ipld/go-ipld-prime"
|
|
||||||
"github.com/ipld/go-ipld-prime/codec/dagcbor"
|
|
||||||
"github.com/ipld/go-ipld-prime/codec/dagjson"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (p *PayloadModel) EncodeDagCbor() ([]byte, error) {
|
|
||||||
return ipld.Marshal(dagcbor.Encode, p, PayloadType())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PayloadModel) EncodeDagJson() ([]byte, error) {
|
|
||||||
return ipld.Marshal(dagjson.Encode, p, PayloadType())
|
|
||||||
}
|
|
||||||
|
|
||||||
func DecodeDagCbor(data []byte) (*PayloadModel, error) {
|
|
||||||
var p PayloadModel
|
|
||||||
_, err := ipld.Unmarshal(data, dagcbor.Decode, &p, PayloadType())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &p, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func DecodeDagJson(data []byte) (*PayloadModel, error) {
|
|
||||||
var p PayloadModel
|
|
||||||
_, err := ipld.Unmarshal(data, dagjson.Decode, &p, PayloadType())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &p, nil
|
|
||||||
}
|
|
||||||
168
delegation/ipld.go
Normal file
168
delegation/ipld.go
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
package delegation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/ipld/go-ipld-prime"
|
||||||
|
"github.com/ipld/go-ipld-prime/codec"
|
||||||
|
"github.com/ipld/go-ipld-prime/codec/dagcbor"
|
||||||
|
"github.com/ipld/go-ipld-prime/codec/dagjson"
|
||||||
|
"github.com/ipld/go-ipld-prime/datamodel"
|
||||||
|
"github.com/libp2p/go-libp2p/core/crypto"
|
||||||
|
|
||||||
|
"github.com/ucan-wg/go-ucan/did"
|
||||||
|
"github.com/ucan-wg/go-ucan/internal/envelope"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Encode marshals a View to the format specified by the provided
|
||||||
|
// codec.Encoder.
|
||||||
|
func (d *View) Encode(privKey crypto.PrivKey, encFn codec.Encoder) ([]byte, error) {
|
||||||
|
node, err := d.ToIPLD(privKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ipld.Encode(node, encFn)
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncodeWriter is the same as Encode but accepts an io.Writer.
|
||||||
|
func (d *View) EncodeWriter(w io.Writer, privKey crypto.PrivKey, encFn codec.Encoder) error {
|
||||||
|
node, err := d.ToIPLD(privKey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ipld.EncodeStreaming(w, node, encFn)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToDagCbor marshals the View to the DAG-CBOR format.
|
||||||
|
func (d *View) ToDagCbor(privKey crypto.PrivKey) ([]byte, error) {
|
||||||
|
return d.Encode(privKey, dagcbor.Encode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToDagCborWriter is the same as ToDagCbor but it accepts an io.Writer.
|
||||||
|
func (d *View) ToDagCborWriter(w io.Writer, privKey crypto.PrivKey) error {
|
||||||
|
return d.EncodeWriter(w, privKey, dagcbor.Encode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToDagJson marshals the View to the DAG-JSON format.
|
||||||
|
func (d *View) ToDagJson(privKey crypto.PrivKey) ([]byte, error) {
|
||||||
|
return d.Encode(privKey, dagjson.Encode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToDagJsonWriter is the same as ToDagJson but it accepts an io.Writer.
|
||||||
|
func (d *View) ToDagJsonWriter(w io.Writer, privKey crypto.PrivKey) error {
|
||||||
|
return d.EncodeWriter(w, privKey, dagjson.Encode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToIPLD wraps the View in an IPLD datamodel.Node.
|
||||||
|
func (d *View) ToIPLD(privKey crypto.PrivKey) (datamodel.Node, error) {
|
||||||
|
var sub *string
|
||||||
|
if d.Subject != did.Undef {
|
||||||
|
s := d.Subject.String()
|
||||||
|
sub = &s
|
||||||
|
}
|
||||||
|
|
||||||
|
pol, err := d.Policy.ToIPLD()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
metaKeys := make([]string, len(d.Meta))
|
||||||
|
i := 0
|
||||||
|
|
||||||
|
for k := range d.Meta {
|
||||||
|
metaKeys[i] = k
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
var nbf *int64
|
||||||
|
if d.NotBefore != nil {
|
||||||
|
u := d.NotBefore.Unix()
|
||||||
|
nbf = &u
|
||||||
|
}
|
||||||
|
|
||||||
|
var exp *int64
|
||||||
|
if d.Expiration != nil {
|
||||||
|
u := d.Expiration.Unix()
|
||||||
|
exp = &u
|
||||||
|
}
|
||||||
|
|
||||||
|
model := &PayloadModel{
|
||||||
|
Iss: d.Issuer.String(),
|
||||||
|
Aud: d.Audience.String(),
|
||||||
|
Sub: sub,
|
||||||
|
Cmd: d.Command.String(),
|
||||||
|
Pol: pol,
|
||||||
|
Nonce: d.Nonce,
|
||||||
|
Meta: MetaModel{
|
||||||
|
Keys: metaKeys,
|
||||||
|
Values: d.Meta,
|
||||||
|
},
|
||||||
|
Nbf: nbf,
|
||||||
|
Exp: exp,
|
||||||
|
}
|
||||||
|
|
||||||
|
return envelope.ToIPLD(privKey, model)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode unmarshals the input data using the format specified by the
|
||||||
|
// provided codec.Decoder into a View.
|
||||||
|
//
|
||||||
|
// An error is returned if the conversion fails, or if the resulting
|
||||||
|
// View is invalid.
|
||||||
|
func Decode(b []byte, decFn codec.Decoder) (*View, error) {
|
||||||
|
node, err := ipld.Decode(b, decFn)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return FromIPLD(node)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeReader is the same as Decode, but accept an io.Reader.
|
||||||
|
func DecodeReader(r io.Reader, decFn codec.Decoder) (*View, error) {
|
||||||
|
node, err := ipld.DecodeStreaming(r, decFn)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return FromIPLD(node)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromDagCbor unmarshals the input data into a View.
|
||||||
|
//
|
||||||
|
// An error is returned if the conversion fails, or if the resulting
|
||||||
|
// View is invalid.
|
||||||
|
func FromDagCbor(data []byte) (*View, error) {
|
||||||
|
return Decode(data, dagcbor.Decode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromDagCborReader is the same as FromDagCbor, but accept an io.Reader.
|
||||||
|
func FromDagCborReader(r io.Reader) (*View, error) {
|
||||||
|
return DecodeReader(r, dagcbor.Decode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromDagJson unmarshals the input data into a View.
|
||||||
|
//
|
||||||
|
// An error is returned if the conversion fails, or if the resulting
|
||||||
|
// View is invalid.
|
||||||
|
func FromDagJson(data []byte) (*View, error) {
|
||||||
|
return Decode(data, dagjson.Decode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromDagJsonReader is the same as FromDagJson, but accept an io.Reader.
|
||||||
|
func FromDagJsonReader(r io.Reader) (*View, error) {
|
||||||
|
return DecodeReader(r, dagjson.Decode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromIPLD unwraps a View from the provided IPLD datamodel.Node
|
||||||
|
//
|
||||||
|
// An error is returned if the conversion fails, or if the resulting
|
||||||
|
// View is invalid.
|
||||||
|
func FromIPLD(node datamodel.Node) (*View, error) {
|
||||||
|
tkn, _, err := envelope.FromIPLD[*PayloadModel](node) // TODO add CID to view
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ViewFromModel(*tkn)
|
||||||
|
}
|
||||||
@@ -7,9 +7,13 @@ import (
|
|||||||
|
|
||||||
"github.com/ipld/go-ipld-prime"
|
"github.com/ipld/go-ipld-prime"
|
||||||
"github.com/ipld/go-ipld-prime/datamodel"
|
"github.com/ipld/go-ipld-prime/datamodel"
|
||||||
|
"github.com/ipld/go-ipld-prime/node/bindnode"
|
||||||
"github.com/ipld/go-ipld-prime/schema"
|
"github.com/ipld/go-ipld-prime/schema"
|
||||||
|
"github.com/ucan-wg/go-ucan/internal/envelope"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const Tag = "ucan/dlg@1.0.0-rc.1"
|
||||||
|
|
||||||
//go:embed delegation.ipldsch
|
//go:embed delegation.ipldsch
|
||||||
var schemaBytes []byte
|
var schemaBytes []byte
|
||||||
|
|
||||||
@@ -33,6 +37,8 @@ func PayloadType() schema.Type {
|
|||||||
return mustLoadSchema().TypeByName("Payload")
|
return mustLoadSchema().TypeByName("Payload")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ envelope.Tokener = (*PayloadModel)(nil)
|
||||||
|
|
||||||
type PayloadModel struct {
|
type PayloadModel struct {
|
||||||
// Issuer DID (sender)
|
// Issuer DID (sender)
|
||||||
Iss string
|
Iss string
|
||||||
@@ -63,6 +69,14 @@ type PayloadModel struct {
|
|||||||
Exp *int64
|
Exp *int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *PayloadModel) Prototype() schema.TypedPrototype {
|
||||||
|
return bindnode.Prototype((*PayloadModel)(nil), PayloadType())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*PayloadModel) Tag() string {
|
||||||
|
return Tag
|
||||||
|
}
|
||||||
|
|
||||||
type MetaModel struct {
|
type MetaModel struct {
|
||||||
Keys []string
|
Keys []string
|
||||||
Values map[string]datamodel.Node
|
Values map[string]datamodel.Node
|
||||||
|
|||||||
@@ -1,66 +1,76 @@
|
|||||||
package delegation
|
package delegation_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
_ "embed"
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/ipld/go-ipld-prime"
|
"github.com/ipld/go-ipld-prime"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/ucan-wg/go-ucan/delegation"
|
||||||
|
"gotest.tools/v3/golden"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//go:embed delegation.ipldsch
|
||||||
|
var schemaBytes []byte
|
||||||
|
|
||||||
func TestSchemaRoundTrip(t *testing.T) {
|
func TestSchemaRoundTrip(t *testing.T) {
|
||||||
const delegationJson = `
|
// const delegationJson = `
|
||||||
{
|
// {
|
||||||
"aud":"did:key:def456",
|
// "aud":"did:key:def456",
|
||||||
"cmd":"/foo/bar",
|
// "cmd":"/foo/bar",
|
||||||
"exp":123456,
|
// "exp":123456,
|
||||||
"iss":"did:key:abc123",
|
// "iss":"did:key:abc123",
|
||||||
"meta":{
|
// "meta":{
|
||||||
"bar":"baaar",
|
// "bar":"baaar",
|
||||||
"foo":"fooo"
|
// "foo":"fooo"
|
||||||
},
|
// },
|
||||||
"nbf":123456,
|
// "nbf":123456,
|
||||||
"nonce":{
|
// "nonce":{
|
||||||
"/":{
|
// "/":{
|
||||||
"bytes":"c3VwZXItcmFuZG9t"
|
// "bytes":"c3VwZXItcmFuZG9t"
|
||||||
}
|
// }
|
||||||
},
|
// },
|
||||||
"pol":[
|
// "pol":[
|
||||||
["==", ".status", "draft"],
|
// ["==", ".status", "draft"],
|
||||||
["all", ".reviewer", [
|
// ["all", ".reviewer", [
|
||||||
["like", ".email", "*@example.com"]]
|
// ["like", ".email", "*@example.com"]]
|
||||||
],
|
// ],
|
||||||
["any", ".tags", [
|
// ["any", ".tags", [
|
||||||
["or", [
|
// ["or", [
|
||||||
["==", ".", "news"],
|
// ["==", ".", "news"],
|
||||||
["==", ".", "press"]]
|
// ["==", ".", "press"]]
|
||||||
]]
|
// ]]
|
||||||
]
|
// ]
|
||||||
],
|
// ],
|
||||||
"sub":""
|
// "sub":""
|
||||||
}
|
// }
|
||||||
`
|
// `
|
||||||
|
|
||||||
|
delegationJson := golden.Get(t, "new.dagjson")
|
||||||
|
privKey := privKey(t, issuerPrivKeyCfg)
|
||||||
|
|
||||||
// format: dagJson --> PayloadModel --> dagCbor --> PayloadModel --> dagJson
|
// format: dagJson --> PayloadModel --> dagCbor --> PayloadModel --> dagJson
|
||||||
// function: DecodeDagJson() EncodeDagCbor() DecodeDagCbor() EncodeDagJson()
|
// function: DecodeDagJson() EncodeDagCbor() DecodeDagCbor() EncodeDagJson()
|
||||||
|
|
||||||
p1, err := DecodeDagJson([]byte(delegationJson))
|
p1, err := delegation.FromDagJson([]byte(delegationJson))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
cborBytes, err := p1.EncodeDagCbor()
|
cborBytes, err := p1.ToDagCbor(privKey)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
fmt.Println("cborBytes length", len(cborBytes))
|
fmt.Println("cborBytes length", len(cborBytes))
|
||||||
fmt.Println("cbor", string(cborBytes))
|
fmt.Println("cbor", string(cborBytes))
|
||||||
|
|
||||||
p2, err := DecodeDagCbor(cborBytes)
|
p2, err := delegation.FromDagCbor(cborBytes)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
fmt.Println("read Cbor", p2)
|
fmt.Println("read Cbor", p2)
|
||||||
|
|
||||||
readJson, err := p2.EncodeDagJson()
|
readJson, err := p2.ToDagJson(privKey)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
fmt.Println("readJson length", len(readJson))
|
fmt.Println("readJson length", len(readJson))
|
||||||
fmt.Println("json: ", string(readJson))
|
fmt.Println("json: ", string(readJson))
|
||||||
|
|
||||||
require.JSONEq(t, delegationJson, string(readJson))
|
require.JSONEq(t, string(delegationJson), string(readJson))
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkSchemaLoad(b *testing.B) {
|
func BenchmarkSchemaLoad(b *testing.B) {
|
||||||
|
|||||||
1
delegation/testdata/new.dagjson
vendored
Normal file
1
delegation/testdata/new.dagjson
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"/":{"bytes":"P2lPLfdMuZuc4NPZ0mbozU+/bn5xoWlJsu+Fvaxi4ICYXVJb9/wiTTht3WJEFqjxXLxfTl4BMZF3J1CNvMPqBg"}},{"h":{"/":{"bytes":"NO0BcQ"}},"ucan/dlg@1.0.0-rc.1":{"aud":"did:key:z6Mkq5YmbJcTrPExNDi26imrTCpKhepjBFBSHqrBDN2ArPkv","cmd":"/foo/bar","exp":-62135596800,"iss":"did:key:z6Mkpzn2n3ZGT2VaqMGSQC3tzmzV4TS9S71iFsDXE1WnoNH2","meta":{"bar":"barr","foo":"fooo"},"nonce":{"/":{"bytes":"NnJvRGhHaTBraU5yaVFBejdKM2QrYk9lb0kvdGo4RU5pa21RTmJ0am5EMA"}},"pol":[["==",".status","draft"],["all",".reviewer",["like",".email","*@example.com"]],["any",".tags",["or",[["==",".","news"],["==",".","press"]]]]],"sub":"did:key:z6MktA1uBdCpq4uJBqE9jjMiLyxZBg9a6xgPPKJjMqss6Zc2"}}]
|
||||||
@@ -27,9 +27,9 @@ type View struct {
|
|||||||
// Arbitrary Metadata
|
// Arbitrary Metadata
|
||||||
Meta map[string]datamodel.Node
|
Meta map[string]datamodel.Node
|
||||||
// "Not before" UTC Unix Timestamp in seconds (valid from), 53-bits integer
|
// "Not before" UTC Unix Timestamp in seconds (valid from), 53-bits integer
|
||||||
NotBefore time.Time
|
NotBefore *time.Time
|
||||||
// The timestamp at which the Invocation becomes invalid
|
// The timestamp at which the Invocation becomes invalid
|
||||||
Expiration time.Time
|
Expiration *time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
// ViewFromModel build a decoded view of the raw IPLD data.
|
// ViewFromModel build a decoded view of the raw IPLD data.
|
||||||
@@ -76,11 +76,13 @@ func ViewFromModel(m PayloadModel) (*View, error) {
|
|||||||
view.Meta = m.Meta.Values
|
view.Meta = m.Meta.Values
|
||||||
|
|
||||||
if m.Nbf != nil {
|
if m.Nbf != nil {
|
||||||
view.NotBefore = time.Unix(*m.Nbf, 0)
|
t := time.Unix(*m.Nbf, 0)
|
||||||
|
view.NotBefore = &t
|
||||||
}
|
}
|
||||||
|
|
||||||
if m.Exp != nil {
|
if m.Exp != nil {
|
||||||
view.Expiration = time.Unix(*m.Exp, 0)
|
t := time.Unix(*m.Exp, 0)
|
||||||
|
view.Expiration = &t
|
||||||
}
|
}
|
||||||
|
|
||||||
return &view, nil
|
return &view, nil
|
||||||
|
|||||||
Reference in New Issue
Block a user