-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(delegation): update to provide encoding/decoding straight from/t…
…o View
- Loading branch information
Showing
8 changed files
with
379 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
package delegation |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,9 +7,13 @@ import ( | |
|
||
"github.com/ipld/go-ipld-prime" | ||
"github.com/ipld/go-ipld-prime/datamodel" | ||
"github.com/ipld/go-ipld-prime/node/bindnode" | ||
"github.com/ipld/go-ipld-prime/schema" | ||
"github.com/ucan-wg/go-ucan/internal/envelope" | ||
) | ||
|
||
const Tag = "ucan/[email protected]" | ||
|
||
//go:embed delegation.ipldsch | ||
var schemaBytes []byte | ||
|
||
|
@@ -33,6 +37,8 @@ func PayloadType() schema.Type { | |
return mustLoadSchema().TypeByName("Payload") | ||
} | ||
|
||
var _ envelope.Tokener = (*PayloadModel)(nil) | ||
|
||
type PayloadModel struct { | ||
// Issuer DID (sender) | ||
Iss string | ||
|
@@ -63,6 +69,14 @@ type PayloadModel struct { | |
Exp *int64 | ||
} | ||
|
||
func (e *PayloadModel) Prototype() schema.TypedPrototype { | ||
return bindnode.Prototype((*PayloadModel)(nil), PayloadType()) | ||
} | ||
|
||
func (*PayloadModel) Tag() string { | ||
return Tag | ||
} | ||
|
||
type MetaModel struct { | ||
Keys []string | ||
Values map[string]datamodel.Node | ||
|
Oops, something went wrong.