mesh/delivery merged: source.main moved to novox/mesh-sdk@db26f7e8b6f5
mesh/check pass d4ae4b6790b8 on db26f7e8b6f5 | unit 1102 run, 680 kept, 2 skipped | integration 1103 run, 722 kept, 2 skipped | over bound: unit (slow…
93 lines
3.5 KiB
Go
93 lines
3.5 KiB
Go
package delivery
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"reflect"
|
|
"strings"
|
|
)
|
|
|
|
// The controller's grants (novox/hq ADR 0528 clause 2, ADR 0429 §6 rule 6): when the controller has issued a module's
|
|
// bus credential for a fingerprint, it writes `<module>.<fingerprint hex>` in its bucket grants. The assigner reads
|
|
// it: a node's want moves to a fingerprint only once its grant exists. Only the controller writes the bucket.
|
|
//
|
|
// The names say Controller, since the catalogue's GrantKey (catalogue/streams.go) is a stream's grant pattern, unrelated.
|
|
const (
|
|
// ControllerGrantsBucket is the controller's bucket of issued credentials by fingerprint.
|
|
ControllerGrantsBucket = "mesh-controller_grants"
|
|
// ControllerGrantsHistory is the revisions the bucket keeps per key.
|
|
ControllerGrantsHistory = 5
|
|
)
|
|
|
|
// ControllerGrantKey is the key, in ControllerGrantsBucket, of a module's credential issued for a fingerprint:
|
|
// `<module>.<hex>`, the hex being the fingerprint's key part (FingerprintKeyPart).
|
|
func ControllerGrantKey(module, fingerprint string) (string, error) {
|
|
return BuilderBuildKey(module, fingerprint)
|
|
}
|
|
|
|
// ParseControllerGrantKey is the inverse of ControllerGrantKey; it refuses a want or held key, naming it.
|
|
func ParseControllerGrantKey(key string) (module, fingerprint string, err error) {
|
|
if module, fingerprint, err = ParseBuilderBuildKey(key); err != nil {
|
|
return "", "", fmt.Errorf("delivery: %q is not a grant key, <module>.<fingerprint hex>: %w", key, err)
|
|
}
|
|
return module, fingerprint, nil
|
|
}
|
|
|
|
// ControllerGrant is the value of a grant key: the bus accounts (their public keys) the module's processes were issued
|
|
// for that fingerprint, none for a module whose grants the tool runner's account carries, so a reissue for another
|
|
// account is a new revision. The entry's own time says when it was issued.
|
|
type ControllerGrant struct {
|
|
V int `json:"v"`
|
|
Accounts []string `json:"accounts,omitempty"`
|
|
}
|
|
|
|
func (g ControllerGrant) check() error {
|
|
for _, a := range g.Accounts {
|
|
if strings.TrimSpace(a) == "" || strings.ContainsAny(a, " \t\n") {
|
|
return fmt.Errorf("delivery: a grant names an empty or spaced account %q", a)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// EncodeControllerGrant is g as JSON at Version; it refuses an empty or spaced account.
|
|
func EncodeControllerGrant(g ControllerGrant) ([]byte, error) {
|
|
if err := g.check(); err != nil {
|
|
return nil, err
|
|
}
|
|
g.V = Version
|
|
return json.Marshal(g)
|
|
}
|
|
|
|
// DecodeControllerGrant reads a grant; it refuses an unknown version (ErrUnknownVersion) and an empty or spaced account.
|
|
func DecodeControllerGrant(data []byte) (ControllerGrant, error) {
|
|
var g ControllerGrant
|
|
if err := decode(data, &g); err != nil {
|
|
return ControllerGrant{}, err
|
|
}
|
|
if err := g.check(); err != nil {
|
|
return ControllerGrant{}, err
|
|
}
|
|
return g, nil
|
|
}
|
|
|
|
// SameControllerGrant says whether two grants are the same value.
|
|
func SameControllerGrant(a, b ControllerGrant) bool { return reflect.DeepEqual(a, b) }
|
|
|
|
// NamesNode says whether the grant names module's accounts on node: its own `<node>.<module>` or a process's
|
|
// `<node>.<module>.<process>`. A grant that names no account (a module that does not speak on the bus) names every
|
|
// node. The assigner wants a node only once the grant names its account (issue 1945), and a put waits for it (ADR
|
|
// 0546 clause 4).
|
|
func (g ControllerGrant) NamesNode(node, module string) bool {
|
|
if len(g.Accounts) == 0 {
|
|
return true
|
|
}
|
|
own := node + "." + module
|
|
for _, a := range g.Accounts {
|
|
if a == own || strings.HasPrefix(a, own+".") {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|