meta: make a read-only version to enforce token immutability

This commit is contained in:
Michael Muré
2024-11-06 15:17:35 +01:00
parent cfb4446a05
commit 6aeb6a8b70
5 changed files with 54 additions and 8 deletions

View File

@@ -1,7 +1,6 @@
package meta
import (
"errors"
"fmt"
"reflect"
"strings"
@@ -12,9 +11,9 @@ import (
"github.com/ipld/go-ipld-prime/printer"
)
var ErrUnsupported = errors.New("failure adding unsupported type to meta")
var ErrUnsupported = fmt.Errorf("failure adding unsupported type to meta")
var ErrNotFound = errors.New("key-value not found in meta")
var ErrNotFound = fmt.Errorf("key-value not found in meta")
// Meta is a container for meta key-value pairs in a UCAN token.
// This also serves as a way to construct the underlying IPLD data with minimum allocations and transformations,
@@ -160,6 +159,11 @@ func (m *Meta) String() string {
return buf.String()
}
// ReadOnly returns a read-only version of Meta.
func (m *Meta) ReadOnly() ReadOnly {
return ReadOnly{m: m}
}
func fqtn(val any) string {
var name string

42
pkg/meta/readonly.go Normal file
View File

@@ -0,0 +1,42 @@
package meta
import (
"github.com/ipld/go-ipld-prime"
)
// ReadOnly wraps a Meta into a read-only facade.
type ReadOnly struct {
m *Meta
}
func (r ReadOnly) GetBool(key string) (bool, error) {
return r.m.GetBool(key)
}
func (r ReadOnly) GetString(key string) (string, error) {
return r.m.GetString(key)
}
func (r ReadOnly) GetInt64(key string) (int64, error) {
return r.m.GetInt64(key)
}
func (r ReadOnly) GetFloat64(key string) (float64, error) {
return r.m.GetFloat64(key)
}
func (r ReadOnly) GetBytes(key string) ([]byte, error) {
return r.m.GetBytes(key)
}
func (r ReadOnly) GetNode(key string) (ipld.Node, error) {
return r.m.GetNode(key)
}
func (r ReadOnly) Equals(other ReadOnly) bool {
return r.m.Equals(other.m)
}
func (r ReadOnly) String() string {
return r.m.String()
}

View File

@@ -142,8 +142,8 @@ func (t *Token) Nonce() []byte {
}
// Meta returns the Token's metadata.
func (t *Token) Meta() *meta.Meta {
return t.meta
func (t *Token) Meta() meta.ReadOnly {
return t.meta.ReadOnly()
}
// NotBefore returns the time at which the Token becomes "active".

View File

@@ -17,7 +17,7 @@ type Token interface {
// Issuer returns the did.DID representing the Token's issuer.
Issuer() did.DID
// Meta returns the Token's metadata.
Meta() *meta.Meta
Meta() meta.ReadOnly
}
type Marshaller interface {

View File

@@ -71,8 +71,8 @@ func (t *Token) Nonce() []byte {
}
// Meta returns the Token's metadata.
func (t *Token) Meta() *meta.Meta {
return t.meta
func (t *Token) Meta() meta.ReadOnly {
return t.meta.ReadOnly()
}
// Expiration returns the time at which the Token expires.