2024-09-18 12:20:54 -04:00
|
|
|
package delegation_test
|
|
|
|
|
|
|
|
|
|
import (
|
2025-07-31 14:43:42 +02:00
|
|
|
_ "embed"
|
2024-10-31 18:24:54 +01:00
|
|
|
"encoding/base64"
|
2024-09-18 12:20:54 -04:00
|
|
|
"testing"
|
2024-09-18 15:54:46 -04:00
|
|
|
"time"
|
2024-09-18 12:20:54 -04:00
|
|
|
|
2026-01-08 15:45:53 -05:00
|
|
|
"code.sonr.org/go/did-it/didtest"
|
2024-09-18 12:20:54 -04:00
|
|
|
"github.com/stretchr/testify/require"
|
2024-09-19 10:48:25 +02:00
|
|
|
|
2026-01-08 15:45:53 -05:00
|
|
|
"code.sonr.org/go/ucan/pkg/command"
|
|
|
|
|
"code.sonr.org/go/ucan/pkg/policy"
|
|
|
|
|
"code.sonr.org/go/ucan/token/delegation"
|
2024-09-18 12:20:54 -04:00
|
|
|
)
|
|
|
|
|
|
2025-07-31 14:43:42 +02:00
|
|
|
//go:embed testdata/new.dagjson
|
|
|
|
|
var newDagJson []byte
|
|
|
|
|
|
|
|
|
|
//go:embed testdata/powerline.dagjson
|
|
|
|
|
var powerlineDagJson []byte
|
|
|
|
|
|
|
|
|
|
//go:embed testdata/root.dagjson
|
|
|
|
|
var rootDagJson []byte
|
|
|
|
|
|
2024-09-18 12:20:54 -04:00
|
|
|
const (
|
|
|
|
|
nonce = "6roDhGi0kiNriQAz7J3d+bOeoI/tj8ENikmQNbtjnD0"
|
|
|
|
|
|
2024-11-25 15:12:29 -05:00
|
|
|
subJectCmd = "/foo/bar"
|
|
|
|
|
subjectPol = `
|
2024-09-18 12:20:54 -04:00
|
|
|
[
|
2025-01-29 14:07:49 +01:00
|
|
|
["==", ".status", "draft"],
|
|
|
|
|
["all", ".reviewer",
|
|
|
|
|
["like", ".email", "*@example.com"]
|
|
|
|
|
],
|
|
|
|
|
["any", ".tags",
|
|
|
|
|
["or", [
|
|
|
|
|
["==", ".", "news"],
|
|
|
|
|
["==", ".", "press"]
|
|
|
|
|
]]
|
|
|
|
|
]
|
2024-09-18 12:20:54 -04:00
|
|
|
]
|
|
|
|
|
`
|
2024-09-19 13:29:33 -04:00
|
|
|
|
2024-10-31 18:24:54 +01:00
|
|
|
aesKey = "xQklMmNTnVrmaPBq/0pwV5fEwuv/iClF5HWak9MsgI8="
|
2024-09-18 12:20:54 -04:00
|
|
|
)
|
|
|
|
|
|
2024-09-18 15:54:46 -04:00
|
|
|
func TestConstructors(t *testing.T) {
|
|
|
|
|
t.Parallel()
|
2024-09-18 12:20:54 -04:00
|
|
|
|
2024-09-18 15:54:46 -04:00
|
|
|
cmd, err := command.Parse(subJectCmd)
|
|
|
|
|
require.NoError(t, err)
|
2024-09-18 12:20:54 -04:00
|
|
|
|
2024-09-18 15:54:46 -04:00
|
|
|
pol, err := policy.FromDagJson(subjectPol)
|
|
|
|
|
require.NoError(t, err)
|
2024-09-18 12:20:54 -04:00
|
|
|
|
2024-09-18 15:54:46 -04:00
|
|
|
exp, err := time.Parse(time.RFC3339, "2200-01-01T00:00:00Z")
|
|
|
|
|
require.NoError(t, err)
|
2024-09-18 12:20:54 -04:00
|
|
|
|
2024-09-18 15:54:46 -04:00
|
|
|
t.Run("New", func(t *testing.T) {
|
2024-12-10 12:19:47 +01:00
|
|
|
tkn, err := delegation.New(didtest.PersonaAlice.DID(), didtest.PersonaBob.DID(), cmd, pol, didtest.PersonaCarol.DID(),
|
2024-09-19 11:16:33 +02:00
|
|
|
delegation.WithNonce([]byte(nonce)),
|
2024-09-19 10:48:25 +02:00
|
|
|
delegation.WithExpiration(exp),
|
|
|
|
|
delegation.WithMeta("foo", "fooo"),
|
|
|
|
|
delegation.WithMeta("bar", "barr"),
|
|
|
|
|
)
|
2024-09-18 15:54:46 -04:00
|
|
|
require.NoError(t, err)
|
2024-09-18 12:20:54 -04:00
|
|
|
|
2025-01-29 14:07:49 +01:00
|
|
|
require.False(t, tkn.IsRoot())
|
|
|
|
|
require.False(t, tkn.IsPowerline())
|
|
|
|
|
|
2024-11-25 15:12:29 -05:00
|
|
|
data, err := tkn.ToDagJson(didtest.PersonaAlice.PrivKey())
|
2024-09-18 15:54:46 -04:00
|
|
|
require.NoError(t, err)
|
2024-09-18 12:20:54 -04:00
|
|
|
|
2025-07-31 14:43:42 +02:00
|
|
|
require.Equal(t, newDagJson, data)
|
2024-09-18 15:54:46 -04:00
|
|
|
})
|
2024-09-18 12:20:54 -04:00
|
|
|
|
2024-09-18 15:54:46 -04:00
|
|
|
t.Run("Root", func(t *testing.T) {
|
2024-11-25 15:12:29 -05:00
|
|
|
tkn, err := delegation.Root(didtest.PersonaAlice.DID(), didtest.PersonaBob.DID(), cmd, pol,
|
2024-09-19 11:16:33 +02:00
|
|
|
delegation.WithNonce([]byte(nonce)),
|
2024-09-19 10:48:25 +02:00
|
|
|
delegation.WithExpiration(exp),
|
|
|
|
|
delegation.WithMeta("foo", "fooo"),
|
|
|
|
|
delegation.WithMeta("bar", "barr"),
|
|
|
|
|
)
|
2024-09-18 15:54:46 -04:00
|
|
|
require.NoError(t, err)
|
2024-09-18 12:20:54 -04:00
|
|
|
|
2025-01-29 14:07:49 +01:00
|
|
|
require.True(t, tkn.IsRoot())
|
|
|
|
|
require.False(t, tkn.IsPowerline())
|
|
|
|
|
|
2024-11-25 15:12:29 -05:00
|
|
|
data, err := tkn.ToDagJson(didtest.PersonaAlice.PrivKey())
|
2024-09-18 15:54:46 -04:00
|
|
|
require.NoError(t, err)
|
2024-09-18 12:20:54 -04:00
|
|
|
|
2025-07-31 14:43:42 +02:00
|
|
|
require.Equal(t, rootDagJson, data)
|
2024-09-18 15:54:46 -04:00
|
|
|
})
|
2024-12-09 20:39:47 +01:00
|
|
|
|
|
|
|
|
t.Run("Powerline", func(t *testing.T) {
|
|
|
|
|
tkn, err := delegation.Powerline(didtest.PersonaAlice.DID(), didtest.PersonaBob.DID(), cmd, pol,
|
|
|
|
|
delegation.WithNonce([]byte(nonce)),
|
|
|
|
|
delegation.WithExpiration(exp),
|
|
|
|
|
delegation.WithMeta("foo", "fooo"),
|
|
|
|
|
delegation.WithMeta("bar", "barr"),
|
|
|
|
|
)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
2025-01-29 14:07:49 +01:00
|
|
|
require.False(t, tkn.IsRoot())
|
|
|
|
|
require.True(t, tkn.IsPowerline())
|
|
|
|
|
|
2024-12-09 20:39:47 +01:00
|
|
|
data, err := tkn.ToDagJson(didtest.PersonaAlice.PrivKey())
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
2025-07-31 14:43:42 +02:00
|
|
|
require.Equal(t, powerlineDagJson, data)
|
2024-12-09 20:39:47 +01:00
|
|
|
})
|
2024-09-18 15:54:46 -04:00
|
|
|
}
|
2024-09-18 12:20:54 -04:00
|
|
|
|
2024-10-31 18:24:54 +01:00
|
|
|
func TestEncryptedMeta(t *testing.T) {
|
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
|
|
cmd, err := command.Parse(subJectCmd)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
pol, err := policy.FromDagJson(subjectPol)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
encryptionKey, err := base64.StdEncoding.DecodeString(aesKey)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Len(t, encryptionKey, 32)
|
|
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
key string
|
|
|
|
|
value string
|
|
|
|
|
expectError bool
|
|
|
|
|
}{
|
|
|
|
|
{
|
|
|
|
|
name: "simple string",
|
|
|
|
|
key: "secret1",
|
|
|
|
|
value: "hello world",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "empty string",
|
|
|
|
|
key: "secret2",
|
|
|
|
|
value: "",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "special characters",
|
|
|
|
|
key: "secret3",
|
|
|
|
|
value: "!@#$%^&*()_+-=[]{}|;:,.<>?",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "unicode characters",
|
|
|
|
|
key: "secret4",
|
|
|
|
|
value: "Hello, 世界! 👋",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
|
tt := tt
|
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
|
t.Parallel()
|
|
|
|
|
|
2024-12-09 20:39:47 +01:00
|
|
|
tkn, err := delegation.Root(didtest.PersonaAlice.DID(), didtest.PersonaBob.DID(), cmd, pol,
|
2024-11-12 16:07:39 +01:00
|
|
|
delegation.WithEncryptedMetaString(tt.key, tt.value, encryptionKey),
|
2024-10-31 18:24:54 +01:00
|
|
|
)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
2024-11-25 15:12:29 -05:00
|
|
|
data, err := tkn.ToDagCbor(didtest.PersonaAlice.PrivKey())
|
2024-10-31 18:24:54 +01:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
decodedTkn, _, err := delegation.FromSealed(data)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
2024-11-12 16:37:53 +01:00
|
|
|
_, err = decodedTkn.Meta().GetString(tt.key)
|
|
|
|
|
require.Error(t, err)
|
2024-10-31 18:24:54 +01:00
|
|
|
|
|
|
|
|
decrypted, err := decodedTkn.Meta().GetEncryptedString(tt.key, encryptionKey)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
// Verify the decrypted value is equal to the original
|
|
|
|
|
require.Equal(t, tt.value, decrypted)
|
|
|
|
|
|
|
|
|
|
// Try to decrypt with wrong key
|
|
|
|
|
wrongKey := make([]byte, 32)
|
|
|
|
|
_, err = decodedTkn.Meta().GetEncryptedString(tt.key, wrongKey)
|
|
|
|
|
require.Error(t, err)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
t.Run("multiple encrypted values in the same token", func(t *testing.T) {
|
|
|
|
|
values := map[string]string{
|
|
|
|
|
"secret1": "value1",
|
|
|
|
|
"secret2": "value2",
|
|
|
|
|
"secret3": "value3",
|
|
|
|
|
}
|
2024-11-04 19:11:25 +01:00
|
|
|
var opts []delegation.Option
|
|
|
|
|
for k, v := range values {
|
2024-11-12 16:07:39 +01:00
|
|
|
opts = append(opts, delegation.WithEncryptedMetaString(k, v, encryptionKey))
|
2024-11-04 19:11:25 +01:00
|
|
|
}
|
2024-10-31 18:24:54 +01:00
|
|
|
|
|
|
|
|
// Create token with multiple encrypted values
|
2024-12-09 20:39:47 +01:00
|
|
|
tkn, err := delegation.Root(didtest.PersonaAlice.DID(), didtest.PersonaBob.DID(), cmd, pol, opts...)
|
2024-10-31 18:24:54 +01:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
2024-11-25 15:12:29 -05:00
|
|
|
data, err := tkn.ToDagCbor(didtest.PersonaAlice.PrivKey())
|
2024-10-31 18:24:54 +01:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
decodedTkn, _, err := delegation.FromSealed(data)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
for k, v := range values {
|
|
|
|
|
decrypted, err := decodedTkn.Meta().GetEncryptedString(k, encryptionKey)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, v, decrypted)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|