graphvent

package module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 28, 2023 License: AGPL-3.0 Imports: 39 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ListenerExtType = ExtType("LISTENER")
	LockableExtType = ExtType("LOCKABLE")
	GQLExtType      = ExtType("GQL")
	GroupExtType    = ExtType("GROUP")
	ECDHExtType     = ExtType("ECDH")

	GQLNodeType = NodeType("GQL")
)

ExtType and NodeType constants

View Source
const (
	Unlocked     = ReqState(0)
	Unlocking    = ReqState(1)
	Locked       = ReqState(2)
	Locking      = ReqState(3)
	AbortingLock = ReqState(4)
)
View Source
const (
	// Magic first four bytes of serialized DB content, stored big endian
	NODE_DB_MAGIC = 0x2491df14
	// Total length of the node database header, has magic to verify and type_hash to map to load function
	NODE_DB_HEADER_LEN      = 32
	EXTENSION_DB_HEADER_LEN = 16
	QSIGNAL_DB_HEADER_LEN   = 24
	POLICY_DB_HEADER_LEN    = 16
)
View Source
const (
	MemberOfPolicyType      = PolicyType("USER_OF")
	RequirementOfPolicyType = PolicyType("REQUIEMENT_OF")
	PerNodePolicyType       = PolicyType("PER_NODE")
	AllNodesPolicyType      = PolicyType("ALL_NODES")
)
View Source
const (
	StopSignalType       = SignalType("STOP")
	NewSignalType        = SignalType("NEW")
	StartSignalType      = SignalType("START")
	ErrorSignalType      = SignalType("ERROR")
	StatusSignalType     = SignalType("STATUS")
	LinkSignalType       = SignalType("LINK")
	LockSignalType       = SignalType("LOCK")
	ReadSignalType       = SignalType("READ")
	ReadResultSignalType = SignalType("READ_RESULT")
	ECDHSignalType       = SignalType("ECDH")
	ECDHProxySignalType  = SignalType("ECDH_PROXY")
	ACLTimeoutSignalType = SignalType("ACL_TIMEOUT")

	Up SignalDirection = iota
	Down
	Direct
)
View Source
const DEFAULT_ECDH_WINDOW = time.Second
View Source
const SIGNAL_SER_HEADER_LENGTH = 20
View Source
const SIGNAL_SER_MAGIC uint32 = 0x753a64de

Variables

View Source
var (
	NodeNotFoundError = errors.New("Node not found in DB")
	ECDH              = ecdh.X25519()
)
View Source
var (
	// Base NodeID, used as a special value
	ZeroUUID = uuid.UUID{}
	ZeroID   = NodeID{ZeroUUID}
)
View Source
var DefaultPolicy = NewAllNodesPolicy(Tree{
	ErrorSignalType.String():      nil,
	ReadResultSignalType.String(): nil,
})

Functions

func AddNodeFields added in v0.2.0

func AddNodeFields(object *graphql.Object)

func BuildSchema added in v0.2.0

func BuildSchema(ctx *GQLExtContext) (graphql.Schema, error)

func CopyNodeRules added in v0.4.0

func CopyNodeRules(rules map[NodeID]Tree) map[NodeID]Tree

func ExtractList added in v0.2.0

func ExtractList[K interface{}](p graphql.ResolveParams, name string) ([]K, error)

func ExtractParam added in v0.2.0

func ExtractParam[K interface{}](p graphql.ResolveParams, name string) (K, error)

TODO: Make composabe by checkinf if K is a slice, then recursing in the same way that ExtractList does

func GQLHandler

func GQLHandler(ctx *Context, server *Node, gql_ext *GQLExt) func(http.ResponseWriter, *http.Request)

func GQLInterfaces added in v0.2.6

func GQLInterfaces(ctx *GQLExtContext, interface_names []string) ([]*graphql.Interface, error)

func GQLWSDo

func GQLWSDo(ctx *Context, p graphql.Params) chan *graphql.Result

func GQLWSHandler

func GQLWSHandler(ctx *Context, server *Node, gql_ext *GQLExt) func(http.ResponseWriter, *http.Request)

func GetCtx added in v0.2.0

func GetCtx[T Extension, C any](ctx *Context) (C, error)

func GetExt added in v0.2.0

func GetExt[T Extension](node *Node) (T, error)

func GetFieldNames added in v0.2.6

func GetFieldNames(ctx *Context, selection_set *ast.SelectionSet) []string

func GetResolveFields added in v0.2.6

func GetResolveFields(ctx *Context, p graphql.ResolveParams) []string

func GraphiQLHandler

func GraphiQLHandler() func(http.ResponseWriter, *http.Request)

func Hash added in v0.2.3

func Hash(t TypeName) uint64

Hashed a Type to a uint64

func LockLockable added in v0.2.0

func LockLockable(ctx *Context, owner *Node, target NodeID) (uuid.UUID, error)

Send the signal to lock a node from itself

func MergeNodeRules added in v0.4.0

func MergeNodeRules(first map[NodeID]Tree, second map[NodeID]Tree) map[NodeID]Tree

func NewField added in v0.2.0

func NewField(init func() *graphql.Field) *graphql.Field

func NodeInterfaceDefaultIsType added in v0.2.6

func NodeInterfaceDefaultIsType(required_extensions []ExtType) func(graphql.IsTypeOfParams) bool

func NodeInterfaceResolveType added in v0.2.6

func NodeInterfaceResolveType(required_extensions []ExtType, default_type **graphql.Object) func(graphql.ResolveTypeParams) *graphql.Object

func RegisterExtension added in v0.3.2

func RegisterExtension[T any, E interface {
	*T
	Extension
}](ctx *Context, data interface{}) error

Add a node to a context, returns an error if the def is invalid or already exists in the context

func RegisterField added in v0.2.6

func RegisterField[T any](ctx *GQLExtContext, gql_type graphql.Type, gql_name string, ext_type ExtType, acl_name string, resolve_fn func(graphql.ResolveParams, T) (interface{}, error)) error

func RegisterSignal added in v0.3.2

func RegisterSignal[T any, S interface {
	*T
	Signal
}](ctx *Context, signal_type SignalType) error

func ResolveFields added in v0.2.6

func ResolveFields[T Extension](t T, name string, field_funcs map[string]func(T) interface{}) interface{}

func ResolveNodeID added in v0.2.6

func ResolveNodeID(p graphql.ResolveParams) (interface{}, error)

func ResolveNodeResult added in v0.2.6

func ResolveNodeResult(p graphql.ResolveParams, resolve_fn func(graphql.ResolveParams, NodeResult) (interface{}, error)) (interface{}, error)

func ResolveNodeTypeHash added in v0.2.6

func ResolveNodeTypeHash(p graphql.ResolveParams) (interface{}, error)

func SerializeSignal added in v0.2.6

func SerializeSignal(signal Signal, block_size int) ([]byte, error)

func UnlockLockable added in v0.2.1

func UnlockLockable(ctx *Context, owner *Node, target NodeID) (uuid.UUID, error)

Send the signal to unlock a node from itself

func VerifyECDHSignal added in v0.2.6

func VerifyECDHSignal(now time.Time, sig *ECDHSignal, window time.Duration) error

func WaitForSignal added in v0.2.6

func WaitForSignal[S Signal](listener chan Signal, timeout time.Duration, signal_type SignalType, check func(S) bool) (S, error)

func WriteNode added in v0.2.0

func WriteNode(ctx *Context, node *Node) error

Write a node to the database

Types

type AllNodesPolicy added in v0.2.0

type AllNodesPolicy struct {
	Rules Tree
}

func NewAllNodesPolicy added in v0.2.0

func NewAllNodesPolicy(rules Tree) AllNodesPolicy

func (*AllNodesPolicy) Allows added in v0.2.0

func (policy *AllNodesPolicy) Allows(principal_id NodeID, action Tree, node *Node) (Messages, RuleResult)

func (*AllNodesPolicy) ContinueAllows added in v0.4.0

func (policy *AllNodesPolicy) ContinueAllows(current PendingACL, signal Signal) RuleResult

func (*AllNodesPolicy) Copy added in v0.3.2

func (policy *AllNodesPolicy) Copy() Policy

func (*AllNodesPolicy) Deserialize added in v0.3.2

func (policy *AllNodesPolicy) Deserialize(ctx *Context, data []byte) error

func (*AllNodesPolicy) Merge added in v0.2.5

func (policy *AllNodesPolicy) Merge(p Policy) Policy

func (*AllNodesPolicy) Serialize added in v0.2.0

func (policy *AllNodesPolicy) Serialize() ([]byte, error)

func (*AllNodesPolicy) Type added in v0.2.0

func (policy *AllNodesPolicy) Type() PolicyType

type BaseSignal

type BaseSignal struct {
	SignalDirection SignalDirection `json:"direction"`
	SignalType      SignalType      `json:"type"`
	UUID            uuid.UUID       `json:"id"`
	ReqUUID         uuid.UUID       `json:"req_uuid"`
}

func NewBaseSignal

func NewBaseSignal(signal_type SignalType, direction SignalDirection) BaseSignal

func NewRespSignal added in v0.4.0

func NewRespSignal(id uuid.UUID, signal_type SignalType, direction SignalDirection) BaseSignal

func (*BaseSignal) Deserialize added in v0.3.2

func (signal *BaseSignal) Deserialize(ctx *Context, data []byte) error

func (*BaseSignal) Direction

func (signal *BaseSignal) Direction() SignalDirection

func (*BaseSignal) ID added in v0.3.1

func (signal *BaseSignal) ID() uuid.UUID

func (*BaseSignal) Permission added in v0.2.5

func (signal *BaseSignal) Permission() Tree

func (*BaseSignal) ReqID added in v0.4.0

func (signal *BaseSignal) ReqID() uuid.UUID

func (*BaseSignal) Serialize added in v0.2.0

func (signal *BaseSignal) Serialize() ([]byte, error)

func (*BaseSignal) String

func (signal *BaseSignal) String() string

func (*BaseSignal) Type

func (signal *BaseSignal) Type() SignalType

type ConsoleLogger

type ConsoleLogger struct {
	// contains filtered or unexported fields
}

A ConsoleLogger logs to stdout

func NewConsoleLogger

func NewConsoleLogger(components []string) *ConsoleLogger

func (*ConsoleLogger) Logf

func (logger *ConsoleLogger) Logf(component string, format string, items ...interface{})

func (*ConsoleLogger) Logj

func (logger *ConsoleLogger) Logj(component string, s interface{}, format string, items ...interface{})

func (*ConsoleLogger) Logm

func (logger *ConsoleLogger) Logm(component string, fields map[string]interface{}, format string, items ...interface{})

func (*ConsoleLogger) SetComponents

func (logger *ConsoleLogger) SetComponents(components []string) error

type Context

type Context struct {
	// DB is the database connection used to load and write nodes
	DB *badger.DB
	// Logging interface
	Log Logger
	// Map between database extension hashes and the registered info
	Extensions map[uint64]ExtensionInfo
	// Map between databse policy hashes and the registered info
	Policies map[uint64]PolicyInfo
	// Map between serialized signal hashes and the registered info
	Signals map[uint64]SignalInfo
	// Map between database type hashes and the registered info
	Types map[uint64]*NodeInfo
	// Routing map to all the nodes local to this context
	NodesLock sync.RWMutex
	Nodes     map[NodeID]*Node
}

A Context stores all the data to run a graphvent process

func NewContext

func NewContext(db *badger.DB, log Logger) (*Context, error)

Create a new Context with the base library content added

func (*Context) AddNode added in v0.2.6

func (ctx *Context) AddNode(id NodeID, node *Node)

func (*Context) GetNode added in v0.2.0

func (ctx *Context) GetNode(id NodeID) (*Node, error)

Get a node from the context, or load from the database if not loaded

func (*Context) Node added in v0.2.6

func (ctx *Context) Node(id NodeID) (*Node, bool)

func (*Context) RegisterNodeType

func (ctx *Context) RegisterNodeType(node_type NodeType, extensions []ExtType) error

Register a NodeType to the context, with the list of extensions it requires

func (*Context) Send added in v0.2.0

func (ctx *Context) Send(messages Messages) error

Route a Signal to dest. Currently only local context routing is supported

type ECDHExt added in v0.2.0

type ECDHExt struct {
	ECDHStates ECDHMap
}

func NewECDHExt added in v0.2.6

func NewECDHExt() *ECDHExt

func (*ECDHExt) Deserialize added in v0.3.2

func (ext *ECDHExt) Deserialize(ctx *Context, data []byte) error

func (*ECDHExt) Field added in v0.2.6

func (ext *ECDHExt) Field(name string) interface{}

func (*ECDHExt) HandleECDHSignal added in v0.2.6

func (ext *ECDHExt) HandleECDHSignal(log Logger, node *Node, signal *ECDHSignal) Messages

func (*ECDHExt) Process added in v0.2.0

func (ext *ECDHExt) Process(ctx *Context, node *Node, source NodeID, signal Signal) Messages

func (*ECDHExt) Serialize added in v0.2.0

func (ext *ECDHExt) Serialize() ([]byte, error)

func (*ECDHExt) Type added in v0.2.0

func (ext *ECDHExt) Type() ExtType

type ECDHMap added in v0.2.6

type ECDHMap map[NodeID]ECDHState

func (ECDHMap) MarshalJSON added in v0.2.6

func (m ECDHMap) MarshalJSON() ([]byte, error)

type ECDHProxySignal added in v0.2.6

type ECDHProxySignal struct {
	BaseSignal
	Source NodeID
	Dest   NodeID
	IV     []byte
	Data   []byte
}

type ECDHSignal added in v0.2.6

type ECDHSignal struct {
	StringSignal
	Time      time.Time
	EDDSA     ed25519.PublicKey
	ECDH      *ecdh.PublicKey
	Signature []byte
}

func NewECDHRespSignal added in v0.2.6

func NewECDHRespSignal(node *Node, req *ECDHSignal) (ECDHSignal, []byte, error)

func (*ECDHSignal) MarshalJSON added in v0.2.6

func (signal *ECDHSignal) MarshalJSON() ([]byte, error)

func (*ECDHSignal) Serialize added in v0.2.6

func (signal *ECDHSignal) Serialize() ([]byte, error)

type ECDHSignalJSON added in v0.2.6

type ECDHSignalJSON struct {
	StringSignal
	Time      time.Time `json:"time"`
	EDDSA     []byte    `json:"ecdsa_pubkey"`
	ECDH      []byte    `json:"ecdh_pubkey"`
	Signature []byte    `json:"signature"`
}

type ECDHState added in v0.2.6

type ECDHState struct {
	ECKey        *ecdh.PrivateKey
	SharedSecret []byte
}

func (*ECDHState) MarshalJSON added in v0.2.6

func (state *ECDHState) MarshalJSON() ([]byte, error)

func (*ECDHState) UnmarshalJSON added in v0.2.6

func (state *ECDHState) UnmarshalJSON(data []byte) error

type ECDHStateJSON added in v0.2.6

type ECDHStateJSON struct {
	ECKey        []byte `json:"ec_key"`
	SharedSecret []byte `json:"shared_secret"`
}

type ErrorSignal added in v0.2.8

type ErrorSignal struct {
	BaseSignal
	Error string
}

func (*ErrorSignal) String added in v0.4.0

func (signal *ErrorSignal) String() string

type ExtType added in v0.2.0

type ExtType string

ExtType identifies an extension on a node

func GQLFields added in v0.2.6

func GQLFields(ctx *GQLExtContext, field_names []string) (graphql.Fields, []ExtType, error)

func (ExtType) Prefix added in v0.2.3

func (ext ExtType) Prefix() string

func (ExtType) String added in v0.2.3

func (ext ExtType) String() string

type Extension added in v0.2.0

type Extension interface {
	Serializable[ExtType]
	Field(string) interface{}
	Process(ctx *Context, node *Node, source NodeID, signal Signal) Messages
}

Extensions are data attached to nodes that process signals

func LoadExtension added in v0.3.2

func LoadExtension[T any, E interface {
	*T
	Extension
}](ctx *Context, data []byte) (Extension, error)

type ExtensionDB added in v0.2.0

type ExtensionDB struct {
	Header ExtensionDBHeader
	Data   []byte
}

func (ExtensionDB) Serialize added in v0.2.0

func (extension ExtensionDB) Serialize() []byte

type ExtensionDBHeader added in v0.2.0

type ExtensionDBHeader struct {
	TypeHash uint64
	Length   uint64
}

func (ExtensionDBHeader) Serialize added in v0.2.0

func (header ExtensionDBHeader) Serialize() []byte

type ExtensionInfo added in v0.2.0

type ExtensionInfo struct {
	// Function used to load extensions of this type from the database
	Load ExtensionLoadFunc
	Type ExtType
	// Extra context data shared between nodes of this class
	Data interface{}
}

Information about a registered extension

type ExtensionLoadFunc added in v0.2.0

type ExtensionLoadFunc func(*Context, []byte) (Extension, error)

Function to load an extension from bytes

type Field added in v0.2.6

type Field struct {
	Ext   ExtType
	Name  string
	Field *graphql.Field
}

type GQLExt added in v0.2.0

type GQLExt struct {
	TLSKey  []byte `json:"tls_key"`
	TLSCert []byte `json:"tls_cert"`
	Listen  string `json:"listen"`
	// contains filtered or unexported fields
}

func NewGQLExt added in v0.2.0

func NewGQLExt(ctx *Context, listen string, tls_cert []byte, tls_key []byte) (*GQLExt, error)

func (*GQLExt) Deserialize added in v0.3.2

func (ext *GQLExt) Deserialize(ctx *Context, data []byte) error

func (*GQLExt) Field added in v0.2.6

func (ext *GQLExt) Field(name string) interface{}

func (*GQLExt) FindResponseChannel added in v0.4.0

func (ext *GQLExt) FindResponseChannel(req_id uuid.UUID) chan Signal

func (*GQLExt) FreeResponseChannel added in v0.3.2

func (ext *GQLExt) FreeResponseChannel(req_id uuid.UUID) chan Signal

func (*GQLExt) GetResponseChannel added in v0.3.2

func (ext *GQLExt) GetResponseChannel(req_id uuid.UUID) chan Signal

func (*GQLExt) Process added in v0.2.0

func (ext *GQLExt) Process(ctx *Context, node *Node, source NodeID, signal Signal) Messages

func (*GQLExt) Serialize added in v0.2.0

func (ext *GQLExt) Serialize() ([]byte, error)

func (*GQLExt) StartGQLServer added in v0.2.6

func (ext *GQLExt) StartGQLServer(ctx *Context, node *Node) error

func (*GQLExt) StopGQLServer added in v0.2.6

func (ext *GQLExt) StopGQLServer() error

func (*GQLExt) Type added in v0.2.0

func (ext *GQLExt) Type() ExtType

type GQLExtContext added in v0.2.0

type GQLExtContext struct {
	// Generated GQL schema
	Schema graphql.Schema

	// Custom graphql types, mapped to NodeTypes
	NodeTypes  map[NodeType]*graphql.Object
	Interfaces map[string]*Interface
	Fields     map[string]Field

	// Schema parameters
	Types        []graphql.Type
	Query        *graphql.Object
	Mutation     *graphql.Object
	Subscription *graphql.Object
}

GQL Specific Context information

func NewGQLExtContext added in v0.2.0

func NewGQLExtContext() *GQLExtContext

func (*GQLExtContext) GetACLFields added in v0.2.6

func (ctx *GQLExtContext) GetACLFields(obj_name string, names []string) (map[ExtType][]string, error)

func (*GQLExtContext) RegisterInterface added in v0.2.6

func (ctx *GQLExtContext) RegisterInterface(name string, default_name string, interfaces []string, fields []string, self_fields map[string]SelfField, list_fields map[string]ListField) error

func (*GQLExtContext) RegisterNodeType added in v0.2.0

func (ctx *GQLExtContext) RegisterNodeType(node_type NodeType, name string, interface_names []string, field_names []string) error

type GQLPayload added in v0.2.0

type GQLPayload struct {
	OperationName string                 `json:"operationName,omitempty"`
	Query         string                 `json:"query,omitempty"`
	Variables     map[string]interface{} `json:"variables,omitempty"`
	Extensions    map[string]interface{} `json:"extensions,omitempty"`
	Data          string                 `json:"data,omitempty"`
}

type GQLUnauthorized added in v0.2.0

type GQLUnauthorized string

func (GQLUnauthorized) Error added in v0.2.0

func (e GQLUnauthorized) Error() string

func (GQLUnauthorized) Is added in v0.2.0

func (e GQLUnauthorized) Is(target error) bool

func (GQLUnauthorized) MarshalJSON added in v0.2.0

func (e GQLUnauthorized) MarshalJSON() ([]byte, error)

type GQLWSMsg

type GQLWSMsg struct {
	ID      string     `json:"id,omitempty"`
	Type    string     `json:"type"`
	Payload GQLPayload `json:"payload,omitempty"`
}

type GroupExt added in v0.2.0

type GroupExt struct {
	Members map[NodeID]string `json:"members"`
}

func NewGroupExt added in v0.2.0

func NewGroupExt(members map[NodeID]string) *GroupExt

func (*GroupExt) Deserialize added in v0.3.2

func (ext *GroupExt) Deserialize(ctx *Context, data []byte) error

func (*GroupExt) Field added in v0.2.6

func (ext *GroupExt) Field(name string) interface{}

func (*GroupExt) Process added in v0.2.0

func (ext *GroupExt) Process(ctx *Context, node *Node, source NodeID, signal Signal) Messages

func (*GroupExt) Serialize added in v0.2.0

func (ext *GroupExt) Serialize() ([]byte, error)

func (*GroupExt) Type added in v0.2.0

func (ext *GroupExt) Type() ExtType

type IDSignal added in v0.2.0

type IDSignal struct {
	BaseSignal
	NodeID `json:"id"`
}

func (*IDSignal) Serialize added in v0.2.6

func (signal *IDSignal) Serialize() ([]byte, error)

type IDStringSignal added in v0.2.8

type IDStringSignal struct {
	BaseSignal
	NodeID NodeID `json:"node_id"`
	Str    string `json:"string"`
}

func (*IDStringSignal) Serialize added in v0.2.8

func (signal *IDStringSignal) Serialize() ([]byte, error)

func (*IDStringSignal) String added in v0.2.8

func (signal *IDStringSignal) String() string

type Interface added in v0.2.6

type Interface struct {
	Interface  *graphql.Interface
	Default    *graphql.Object
	List       *graphql.List
	Extensions []ExtType
}

type ListField added in v0.2.6

type ListField struct {
	ACLName   string
	Extension ExtType
	ResolveFn func(graphql.ResolveParams, interface{}) ([]NodeID, error)
}

type ListenerExt added in v0.2.0

type ListenerExt struct {
	Buffer int
	Chan   chan Signal
}

A Listener extension provides a channel that can receive signals on a different thread

func NewListenerExt added in v0.2.0

func NewListenerExt(buffer int) *ListenerExt

Create a new listener extension with a given buffer size

func (*ListenerExt) Deserialize added in v0.3.2

func (ext *ListenerExt) Deserialize(ctx *Context, data []byte) error

Simple load function, unmarshal the buffer int from json

func (*ListenerExt) Field added in v0.2.6

func (ext *ListenerExt) Field(name string) interface{}

func (*ListenerExt) Process added in v0.2.0

func (ext *ListenerExt) Process(ctx *Context, node *Node, source NodeID, signal Signal) Messages

Send the signal to the channel, logging an overflow if it occurs

func (*ListenerExt) Serialize added in v0.2.0

func (ext *ListenerExt) Serialize() ([]byte, error)

func (*ListenerExt) Type added in v0.2.0

func (listener *ListenerExt) Type() ExtType

type LockableExt added in v0.2.0

type LockableExt struct {
	State        ReqState
	ReqID        uuid.UUID
	Owner        *NodeID
	PendingOwner *NodeID
	Requirements map[NodeID]ReqState
}

func NewLockableExt added in v0.2.0

func NewLockableExt(requirements []NodeID) *LockableExt

func (*LockableExt) Deserialize added in v0.3.2

func (ext *LockableExt) Deserialize(ctx *Context, data []byte) error

func (*LockableExt) Field added in v0.2.6

func (ext *LockableExt) Field(name string) interface{}

func (*LockableExt) HandleErrorSignal added in v0.4.0

func (ext *LockableExt) HandleErrorSignal(log Logger, node *Node, source NodeID, signal *ErrorSignal) Messages

func (*LockableExt) HandleLinkSignal added in v0.2.0

func (ext *LockableExt) HandleLinkSignal(log Logger, node *Node, source NodeID, signal *IDStringSignal) Messages

func (*LockableExt) HandleLockSignal added in v0.2.0

func (ext *LockableExt) HandleLockSignal(log Logger, node *Node, source NodeID, signal *StringSignal) Messages

Handle a LockSignal and update the extensions owner/requirement states

func (*LockableExt) Process added in v0.2.0

func (ext *LockableExt) Process(ctx *Context, node *Node, source NodeID, signal Signal) Messages

LockableExts process Up/Down signals by forwarding them to owner, dependency, and requirement nodes LockSignal and LinkSignal Direct signals are processed to update the requirement/dependency/lock state

func (*LockableExt) Serialize added in v0.2.0

func (ext *LockableExt) Serialize() ([]byte, error)

func (*LockableExt) Type added in v0.2.0

func (ext *LockableExt) Type() ExtType

type Logger

type Logger interface {
	SetComponents(components []string) error
	// Log a formatted string
	Logf(component string, format string, items ...interface{})
	// Log a map of attributes and a format string
	Logm(component string, fields map[string]interface{}, format string, items ...interface{})
	// Log a structure to a file by marshalling and unmarshalling the json
	Logj(component string, s interface{}, format string, items ...interface{})
}

A Logger is passed around to record events happening to components enabled by SetComponents

type MemberOfPolicy added in v0.4.0

type MemberOfPolicy struct {
	PerNodePolicy
}

func NewMemberOfPolicy added in v0.4.0

func NewMemberOfPolicy(group_rules map[NodeID]Tree) MemberOfPolicy

func (*MemberOfPolicy) Allows added in v0.4.0

func (policy *MemberOfPolicy) Allows(principal_id NodeID, action Tree, node *Node) (Messages, RuleResult)

Send a read signal to Group to check if principal_id is a member of it

func (*MemberOfPolicy) ContinueAllows added in v0.4.0

func (policy *MemberOfPolicy) ContinueAllows(current PendingACL, signal Signal) RuleResult

func (*MemberOfPolicy) Copy added in v0.4.0

func (policy *MemberOfPolicy) Copy() Policy

func (*MemberOfPolicy) Merge added in v0.4.0

func (policy *MemberOfPolicy) Merge(p Policy) Policy

func (*MemberOfPolicy) Type added in v0.4.0

func (policy *MemberOfPolicy) Type() PolicyType

type Message added in v0.4.0

type Message struct {
	Source    NodeID
	Dest      NodeID
	Principal ed25519.PublicKey
	Signal    Signal
	Signature []byte
}

func NewMessage added in v0.4.0

func NewMessage(dest NodeID, source NodeID, principal ed25519.PrivateKey, signal Signal) (*Message, error)

type Messages added in v0.4.0

type Messages []*Message

func (Messages) Add added in v0.4.0

func (msgs Messages) Add(source NodeID, principal ed25519.PrivateKey, signal Signal, dest NodeID) Messages

type Node

type Node struct {
	Key        ed25519.PrivateKey
	ID         NodeID
	Type       NodeType
	Extensions map[ExtType]Extension
	Policies   map[PolicyType]Policy

	PendingACLs    map[uuid.UUID]PendingACL
	PendingSignals map[uuid.UUID]PendingSignal

	// Channel for this node to receive messages from the Context
	MsgChan chan *Message
	// Size of MsgChan
	BufferSize uint32
	// Channel for this node to process delayed signals
	TimeoutChan <-chan time.Time

	Active atomic.Bool

	SignalQueue []QueuedSignal
	NextSignal  *QueuedSignal
}

Default message channel size for nodes Nodes represent a group of extensions that can be collectively addressed

func LoadNode

func LoadNode(ctx *Context, id NodeID) (*Node, error)

func NewNode added in v0.2.0

func NewNode(ctx *Context, key ed25519.PrivateKey, node_type NodeType, buffer_size uint32, policies map[PolicyType]Policy, extensions ...Extension) *Node

Create a new node in memory and start it's event loop TODO: Change panics to errors

func (*Node) Allows added in v0.4.0

func (node *Node) Allows(principal_id NodeID, action Tree) (map[PolicyType]Messages, RuleResult)

func (*Node) ClearSignalQueue added in v0.2.0

func (node *Node) ClearSignalQueue()

func (*Node) DequeueSignal added in v0.4.0

func (node *Node) DequeueSignal(id uuid.UUID) error

func (*Node) Process added in v0.2.0

func (node *Node) Process(ctx *Context, source NodeID, signal Signal) error

func (*Node) QueueSignal added in v0.2.0

func (node *Node) QueueSignal(time time.Time, signal Signal)

func (*Node) ReadFields added in v0.4.0

func (node *Node) ReadFields(reqs map[ExtType][]string) map[ExtType]map[string]interface{}

func (*Node) Serialize

func (node *Node) Serialize() ([]byte, error)

type NodeDB added in v0.2.0

type NodeDB struct {
	Header        NodeDBHeader
	Extensions    []ExtensionDB
	Policies      []PolicyDB
	QueuedSignals []QSignalDB
	KeyBytes      []byte
}

func NewNodeDB added in v0.2.0

func NewNodeDB(data []byte) (NodeDB, error)

TODO: add size safety checks

func (NodeDB) Serialize added in v0.2.0

func (node NodeDB) Serialize() []byte

type NodeDBHeader added in v0.2.0

type NodeDBHeader struct {
	Magic            uint32
	NumExtensions    uint32
	NumPolicies      uint32
	NumQueuedSignals uint32
	BufferSize       uint32
	KeyLength        uint32
	TypeHash         uint64
}

A DBHeader is parsed from the first NODE_DB_HEADER_LEN bytes of a serialized DB node

func (NodeDBHeader) Serialize added in v0.2.0

func (header NodeDBHeader) Serialize() []byte

type NodeID

type NodeID struct {
	uuid.UUID
}

A NodeID uniquely identifies a Node

func ExtractID added in v0.2.0

func ExtractID(p graphql.ResolveParams, name string) (NodeID, error)

func IDFromBytes added in v0.2.0

func IDFromBytes(bytes []byte) (NodeID, error)

func KeyID added in v0.2.6

func KeyID(pub ed25519.PublicKey) NodeID

func ParseID added in v0.2.0

func ParseID(str string) (NodeID, error)

Parse an ID from a string

func RandID

func RandID() NodeID

Generate a random NodeID

func (NodeID) Serialize

func (id NodeID) Serialize() []byte

type NodeInfo added in v0.2.0

type NodeInfo struct {
	Type NodeType
	// Required extensions to be a valid node of this class
	Extensions []ExtType
}

Information about a registered node type

type NodeResult added in v0.2.6

type NodeResult struct {
	ID     NodeID
	Result *ReadResultSignal
}

func ResolveNodes added in v0.2.6

func ResolveNodes(ctx *ResolveContext, p graphql.ResolveParams, ids []NodeID) ([]NodeResult, error)

type NodeType

type NodeType string

NodeType identifies the 'class' of a node

func (NodeType) Prefix added in v0.2.3

func (node NodeType) Prefix() string

func (NodeType) String added in v0.2.3

func (node NodeType) String() string

type PendingACL added in v0.4.0

type PendingACL struct {
	Counter   int
	TimeoutID uuid.UUID
	Action    Tree
	Principal NodeID
	Messages  Messages
	Responses []Signal
	Signal    Signal
	Source    NodeID
}

type PendingSignal added in v0.4.0

type PendingSignal struct {
	Policy PolicyType
	Found  bool
	ID     uuid.UUID
}

type PerNodePolicy added in v0.2.0

type PerNodePolicy struct {
	NodeRules map[NodeID]Tree `json:"node_actions"`
}

func NewPerNodePolicy added in v0.2.0

func NewPerNodePolicy(node_actions map[NodeID]Tree) PerNodePolicy

func (*PerNodePolicy) Allows added in v0.2.0

func (policy *PerNodePolicy) Allows(principal_id NodeID, action Tree, node *Node) (Messages, RuleResult)

func (*PerNodePolicy) ContinueAllows added in v0.4.0

func (policy *PerNodePolicy) ContinueAllows(current PendingACL, signal Signal) RuleResult

func (*PerNodePolicy) Copy added in v0.3.2

func (policy *PerNodePolicy) Copy() Policy

func (*PerNodePolicy) Deserialize added in v0.3.2

func (policy *PerNodePolicy) Deserialize(ctx *Context, data []byte) error

func (*PerNodePolicy) Merge added in v0.2.5

func (policy *PerNodePolicy) Merge(p Policy) Policy

func (*PerNodePolicy) Serialize added in v0.2.0

func (policy *PerNodePolicy) Serialize() ([]byte, error)

func (*PerNodePolicy) Type added in v0.2.0

func (policy *PerNodePolicy) Type() PolicyType

type Policy added in v0.2.0

type Policy interface {
	Serializable[PolicyType]
	Allows(principal_id NodeID, action Tree, node *Node) (Messages, RuleResult)
	ContinueAllows(current PendingACL, signal Signal) RuleResult
	// Merge with another policy of the same underlying type
	Merge(Policy) Policy
	// Make a copy of this policy
	Copy() Policy
}

func LoadPolicy added in v0.3.2

func LoadPolicy[T any, P interface {
	*T
	Policy
}](ctx *Context, data []byte) (Policy, error)

type PolicyDB added in v0.4.0

type PolicyDB struct {
	Header PolicyDBHeader
	Data   []byte
}

func (PolicyDB) Serialize added in v0.4.0

func (policy PolicyDB) Serialize() []byte

type PolicyDBHeader added in v0.4.0

type PolicyDBHeader struct {
	TypeHash uint64
	Length   uint64
}

func (PolicyDBHeader) Serialize added in v0.4.0

func (header PolicyDBHeader) Serialize() []byte

type PolicyInfo added in v0.2.0

type PolicyInfo struct {
	Load PolicyLoadFunc
	Type PolicyType
}

type PolicyLoadFunc added in v0.2.0

type PolicyLoadFunc func(*Context, []byte) (Policy, error)

type PolicyType added in v0.2.0

type PolicyType string

func (PolicyType) Prefix added in v0.2.3

func (policy PolicyType) Prefix() string

func (PolicyType) String added in v0.2.3

func (policy PolicyType) String() string

type QSignalDB added in v0.4.0

type QSignalDB struct {
	Header QSignalDBHeader
	Data   []byte
}

func (QSignalDB) Serialize added in v0.4.0

func (qsignal QSignalDB) Serialize() []byte

type QSignalDBHeader added in v0.4.0

type QSignalDBHeader struct {
	Time     time.Time
	TypeHash uint64
	Length   uint64
}

func (QSignalDBHeader) Serialize added in v0.4.0

func (header QSignalDBHeader) Serialize() []byte

type QueuedSignal added in v0.2.0

type QueuedSignal struct {
	Signal
	time.Time
}

A QueuedSignal is a Signal that has been Queued to trigger at a set time

func SoonestSignal added in v0.2.0

func SoonestSignal(signals []QueuedSignal) (*QueuedSignal, <-chan time.Time)

type ReadResultSignal added in v0.2.6

type ReadResultSignal struct {
	BaseSignal
	NodeID     NodeID
	NodeType   NodeType
	Extensions map[ExtType]map[string]interface{} `json:"extensions"`
}

func (*ReadResultSignal) Permission added in v0.3.2

func (signal *ReadResultSignal) Permission() Tree

type ReadSignal added in v0.2.6

type ReadSignal struct {
	BaseSignal
	Extensions map[ExtType][]string `json:"extensions"`
}

func NewReadSignal added in v0.2.6

func NewReadSignal(exts map[ExtType][]string) *ReadSignal

func (*ReadSignal) Permission added in v0.4.0

func (signal *ReadSignal) Permission() Tree

func (*ReadSignal) Serialize added in v0.2.6

func (signal *ReadSignal) Serialize() ([]byte, error)

type ReqState added in v0.2.1

type ReqState byte

type RequirementOfPolicy added in v0.2.0

type RequirementOfPolicy struct {
	PerNodePolicy
}

func NewRequirementOfPolicy added in v0.2.0

func NewRequirementOfPolicy(dep_rules map[NodeID]Tree) RequirementOfPolicy

func (*RequirementOfPolicy) ContinueAllows added in v0.4.0

func (policy *RequirementOfPolicy) ContinueAllows(current PendingACL, signal Signal) RuleResult

func (*RequirementOfPolicy) Type added in v0.2.0

func (policy *RequirementOfPolicy) Type() PolicyType

type ResolveContext added in v0.2.0

type ResolveContext struct {
	// Channels for the gql extension to route data to this context
	Chans map[uuid.UUID]chan Signal

	// Graph Context this resolver is running under
	Context *Context

	// GQL Extension context this resolver is running under
	GQLContext *GQLExtContext

	// Pointer to the node that's currently processing this request
	Server *Node

	// The state data for the node processing this request
	Ext *GQLExt

	// ID of the user that made this request
	User NodeID

	// Key for the user that made this request, to sign resolver requests
	// TODO: figure out some way to use a generated key so that the server can't impersonate the user afterwards
	Key ed25519.PrivateKey
}

Context passed to each resolve execution

func NewResolveContext added in v0.2.0

func NewResolveContext(ctx *Context, server *Node, gql_ext *GQLExt, r *http.Request) (*ResolveContext, error)

func PrepResolve added in v0.2.0

func PrepResolve(p graphql.ResolveParams) (*ResolveContext, error)

type RuleResult added in v0.4.0

type RuleResult int
const (
	Allow RuleResult = iota
	Deny
	Pending
)

type SelfField added in v0.2.6

type SelfField struct {
	ACLName   string
	Extension ExtType
	ResolveFn func(graphql.ResolveParams, interface{}) (*NodeID, error)
}

type Serializable added in v0.2.0

type Serializable[I comparable] interface {
	Serialize() ([]byte, error)
	Deserialize(*Context, []byte) error
	Type() I
}

A Serializable has a type that can be used to map to it, and a function to serialize` the current state

type Signal added in v0.2.0

type Signal interface {
	Serializable[SignalType]
	String() string
	Direction() SignalDirection
	ID() uuid.UUID
	ReqID() uuid.UUID
	Permission() Tree
}

func LoadSignal added in v0.3.2

func LoadSignal[T any, S interface {
	*T
	Signal
}](ctx *Context, data []byte) (Signal, error)

func NewACLTimeoutSignal added in v0.4.0

func NewACLTimeoutSignal(req_id uuid.UUID) Signal

func NewECDHProxySignal added in v0.2.6

func NewECDHProxySignal(source, dest NodeID, signal Signal, shared_secret []byte) (Signal, error)

func NewECDHReqSignal added in v0.2.6

func NewECDHReqSignal(node *Node) (Signal, *ecdh.PrivateKey, error)

func NewErrorSignal added in v0.2.8

func NewErrorSignal(req_id uuid.UUID, fmt_string string, args ...interface{}) Signal

func NewLinkSignal added in v0.2.0

func NewLinkSignal(state string, id NodeID) Signal

func NewLockSignal added in v0.2.0

func NewLockSignal(state string) Signal

func NewReadResultSignal added in v0.2.6

func NewReadResultSignal(req_id uuid.UUID, node_id NodeID, node_type NodeType, exts map[ExtType]map[string]interface{}) Signal

func NewStatusSignal added in v0.2.0

func NewStatusSignal(status string, source NodeID) Signal

func ParseECDHProxySignal added in v0.2.6

func ParseECDHProxySignal(ctx *Context, signal *ECDHProxySignal, shared_secret []byte) (Signal, error)

func ParseSignal added in v0.2.6

func ParseSignal(ctx *Context, data []byte) (Signal, error)

func WaitForResponse added in v0.4.0

func WaitForResponse(listener chan Signal, timeout time.Duration, req_id uuid.UUID) (Signal, error)

type SignalDirection

type SignalDirection int

type SignalHeader added in v0.2.6

type SignalHeader struct {
	Magic    uint32
	TypeHash uint64
	Length   uint64
}

type SignalInfo added in v0.2.6

type SignalInfo struct {
	Load SignalLoadFunc
	Type SignalType
}

type SignalLoadFunc added in v0.2.6

type SignalLoadFunc func(*Context, []byte) (Signal, error)

type SignalType added in v0.2.0

type SignalType string

func (SignalType) Prefix added in v0.2.6

func (signal_type SignalType) Prefix() string

func (SignalType) String added in v0.2.6

func (signal_type SignalType) String() string

type Singleton added in v0.2.0

type Singleton[K graphql.Type] struct {
	Type K
	List *graphql.List
}

func NewSingleton added in v0.2.0

func NewSingleton[K graphql.Type](init func() K, post_init func(K, *graphql.List)) *Singleton[K]

type StringSignal added in v0.2.8

type StringSignal struct {
	BaseSignal
	Str string `json:"state"`
}

func (*StringSignal) Permission added in v0.2.8

func (signal *StringSignal) Permission() Tree

func (*StringSignal) Serialize added in v0.2.8

func (signal *StringSignal) Serialize() ([]byte, error)

func (*StringSignal) String added in v0.4.0

func (signal *StringSignal) String() string

type Tree added in v0.4.0

type Tree map[string]Tree

func CopyTree added in v0.4.0

func CopyTree(tree Tree) Tree

func MergeTrees added in v0.4.0

func MergeTrees(first Tree, second Tree) Tree

func (Tree) Allows added in v0.4.0

func (rule Tree) Allows(action Tree) RuleResult

type Type added in v0.2.3

type Type struct {
	Type *graphql.Object
	List *graphql.List
}

func NewGQLNodeType added in v0.2.0

func NewGQLNodeType(node_type NodeType, interfaces []*graphql.Interface, init func(*Type)) *Type

type TypeName added in v0.2.6

type TypeName interface {
	String() string
	Prefix() string
}

A Type can be Hashed by Hash

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL