graphvent

package module
v0.2.7 Latest Latest
Warning

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

Go to latest
Published: Jul 30, 2023 License: AGPL-3.0 Imports: 36 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ACLExtType      = ExtType("ACL")
	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 (
	// 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      = 28
	EXTENSION_DB_HEADER_LEN = 16
)
View Source
const (
	RequirementOfPolicyType = PolicyType("REQUIREMENT_OF")
	PerNodePolicyType       = PolicyType("PER_NODE")
	AllNodesPolicyType      = PolicyType("ALL_NODES")
)
View Source
const (
	StopSignalType       SignalType = "STOP"
	StatusSignalType                = "STATUS"
	LinkSignalType                  = "LINK"
	LockSignalType                  = "LOCK"
	ReadSignalType                  = "READ"
	ReadResultSignalType            = "READ_RESULT"
	LinkStartSignalType             = "LINK_START"
	ECDHSignalType                  = "ECDH"
	ECDHStateSignalType             = "ECDH_STATE"
	ECDHProxySignalType             = "ECDH_PROXY"
	GQLStateSignalType              = "GQL_STATE"

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

Variables

View Source
var (
	// Base NodeID, used as a special value
	ZeroUUID = uuid.UUID{}
	ZeroID   = NodeID(ZeroUUID)
)
View Source
var MutationStop = NewField(func() *graphql.Field {
	mutation_stop := &graphql.Field{
		Type: TypeSignal.Type,
		Args: graphql.FieldConfigArgument{
			"id": &graphql.ArgumentConfig{
				Type: graphql.String,
			},
		},
		Resolve: func(p graphql.ResolveParams) (interface{}, error) {
			return StopSignal, nil
		},
	}

	return mutation_stop
})
View Source
var (
	NodeNotFoundError = errors.New("Node not found in DB")
)
View Source
var TypeSignal = NewSingleton(func() *graphql.Object {
	gql_type_signal := graphql.NewObject(graphql.ObjectConfig{
		Name: "Signal",
		IsTypeOf: func(p graphql.IsTypeOfParams) bool {
			_, ok := p.Value.(Signal)
			return ok
		},
		Fields: graphql.Fields{},
	})

	gql_type_signal.AddFieldConfig("Type", &graphql.Field{
		Type:    graphql.String,
		Resolve: GQLSignalType,
	})
	gql_type_signal.AddFieldConfig("Direction", &graphql.Field{
		Type:    graphql.String,
		Resolve: GQLSignalDirection,
	})
	gql_type_signal.AddFieldConfig("String", &graphql.Field{
		Type:    graphql.String,
		Resolve: GQLSignalString,
	})
	return gql_type_signal
}, nil)

Functions

func AddNodeFields added in v0.2.0

func AddNodeFields(object *graphql.Object)

func AllNodesPolicyLoad added in v0.2.0

func AllNodesPolicyLoad(init_fn func(Actions) (Policy, error)) func(*Context, []byte) (Policy, error)

func Allowed added in v0.2.0

func Allowed(ctx *Context, principal_id NodeID, action Action, node *Node) error

func BuildSchema added in v0.2.0

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

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 GQLSignalDirection

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

func GQLSignalFn

func GQLSignalFn(p graphql.ResolveParams, fn func(Signal, graphql.ResolveParams) (interface{}, error)) (interface{}, error)

func GQLSignalString

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

func GQLSignalType

func GQLSignalType(p graphql.ResolveParams) (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 IDMap added in v0.2.4

func IDMap[S any, T map[NodeID]S](m T) map[string]S

func LinkRequirement added in v0.2.0

func LinkRequirement(ctx *Context, dependency NodeID, requirement NodeID) error

Setup a node to send the initial requirement link signal, then send the signal

func LoadIDMap added in v0.2.4

func LoadIDMap[S any, T map[string]S](m T) (map[NodeID]S, error)

func LockLockable added in v0.2.0

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

Send the signal to lock a node from itself

func MergeNodeActions added in v0.2.5

func MergeNodeActions(modified NodeActions, read NodeActions)

func NewField added in v0.2.0

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

func NodeInterfaceDefaultIsType added in v0.2.6

func NodeInterfaceDefaultIsType(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 PerNodePolicyLoad added in v0.2.0

func PerNodePolicyLoad(init_fn func(NodeActions) (Policy, error)) func(*Context, []byte) (Policy, error)

func ReadNodeFields added in v0.2.6

func ReadNodeFields(ctx *Context, self *Node, princ NodeID, reqs map[ExtType][]string) map[ExtType]map[string]interface{}

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 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, node *Node) error

Send the signal to unlock a node from itself

func ValidateStateContext added in v0.2.0

func ValidateStateContext(context *StateContext, Type string, Finished bool) error

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](ctx *Context, listener *ListenerExt, 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 ACLExt added in v0.2.0

type ACLExt struct {
	Policies map[PolicyType]Policy
}

Extension to allow a node to hold ACL policies

func NewACLExt added in v0.2.0

func NewACLExt(policies ...Policy) *ACLExt

func (*ACLExt) Allows added in v0.2.0

func (ext *ACLExt) Allows(ctx *Context, principal_id NodeID, action Action, node *Node) error

Check if the extension allows the principal to perform action on node

func (*ACLExt) Field added in v0.2.6

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

func (*ACLExt) Process added in v0.2.0

func (ext *ACLExt) Process(ctx *Context, princ_id NodeID, node *Node, signal Signal)

func (*ACLExt) Serialize added in v0.2.0

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

func (*ACLExt) Type added in v0.2.0

func (ext *ACLExt) Type() ExtType

type ACLExtContext added in v0.2.0

type ACLExtContext struct {
	Types map[PolicyType]PolicyInfo
}

func NewACLExtContext added in v0.2.0

func NewACLExtContext() *ACLExtContext

type ACLInfo added in v0.2.0

type ACLInfo struct {
	Node      *Node
	Resources []string
}

type ACLMap added in v0.2.0

type ACLMap map[NodeID]ACLInfo

func ACLList added in v0.2.0

func ACLList(list []*Node, resources []string) ACLMap

func ACLListM added in v0.2.0

func ACLListM(m map[NodeID]*Node, resources []string) ACLMap

func NewACLInfo added in v0.2.0

func NewACLInfo(node *Node, resources []string) ACLMap

func NewACLMap added in v0.2.0

func NewACLMap(requests ...ACLMap) ACLMap

type Action added in v0.2.5

type Action []string

func MakeAction added in v0.2.6

func MakeAction(parts ...interface{}) Action

func (Action) Allows added in v0.2.6

func (action Action) Allows(test Action) bool

type Actions added in v0.2.0

type Actions []Action

func MergeActions added in v0.2.5

func MergeActions(first Actions, second Actions) Actions

func (Actions) Allows added in v0.2.0

func (actions Actions) Allows(action Action) error

type AllNodesPolicy added in v0.2.0

type AllNodesPolicy struct {
	Actions Actions
}

func NewAllNodesPolicy added in v0.2.0

func NewAllNodesPolicy(actions Actions) AllNodesPolicy

func (AllNodesPolicy) Allows added in v0.2.0

func (policy AllNodesPolicy) Allows(principal_id NodeID, action Action, node *Node) 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 AllNodesPolicyJSON added in v0.2.0

type AllNodesPolicyJSON struct {
	Actions Actions `json:"actions"`
}

type BaseSignal

type BaseSignal struct {
	SignalDirection SignalDirection `json:"direction"`
	SignalType      SignalType      `json:"type"`
}

func NewBaseSignal

func NewBaseSignal(signal_type SignalType, direction SignalDirection) BaseSignal

func NewDirectSignal

func NewDirectSignal(signal_type SignalType) BaseSignal

func NewDownSignal

func NewDownSignal(signal_type SignalType) BaseSignal

func NewUpSignal added in v0.2.0

func NewUpSignal(signal_type SignalType) BaseSignal

func (BaseSignal) Direction

func (signal BaseSignal) Direction() SignalDirection

func (BaseSignal) Permission added in v0.2.5

func (signal BaseSignal) Permission() Action

func (BaseSignal) Serialize added in v0.2.0

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

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 serialized signal hashes and the registered info
	Signals map[uint64]SignalInfo
	// Map between database type hashes and the registered info
	Types map[uint64]*NodeInfo
	// Curve used for signature operations
	ECDSA elliptic.Curve
	// Curve used for ecdh operations
	ECDH ecdh.Curve
	// 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) RegisterExtension added in v0.2.0

func (ctx *Context) RegisterExtension(ext_type ExtType, load_fn ExtensionLoadFunc, data interface{}) error

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

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) RegisterSignal added in v0.2.6

func (ctx *Context) RegisterSignal(signal_type SignalType, load_fn SignalLoadFunc) error

func (*Context) Send added in v0.2.0

func (ctx *Context) Send(source NodeID, dest NodeID, signal Signal) error

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

func (*Context) Stop added in v0.2.1

func (ctx *Context) Stop()

Stop every running loop

type ECDHExt added in v0.2.0

type ECDHExt struct {
	ECDHStates ECDHMap
}

func NewECDHExt added in v0.2.6

func NewECDHExt() *ECDHExt

func (*ECDHExt) Field added in v0.2.6

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

func (*ECDHExt) HandleECDHProxySignal added in v0.2.6

func (ext *ECDHExt) HandleECDHProxySignal(ctx *Context, source NodeID, node *Node, signal ECDHProxySignal)

func (*ECDHExt) HandleECDHSignal added in v0.2.6

func (ext *ECDHExt) HandleECDHSignal(ctx *Context, source NodeID, node *Node, signal ECDHSignal)

func (*ECDHExt) HandleStateSignal added in v0.2.6

func (ext *ECDHExt) HandleStateSignal(ctx *Context, source NodeID, node *Node, signal StateSignal)

func (*ECDHExt) Process added in v0.2.0

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

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
}

func NewECDHProxySignal added in v0.2.6

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

type ECDHSignal added in v0.2.6

type ECDHSignal struct {
	StateSignal
	Time      time.Time
	ECDSA     *ecdsa.PublicKey
	ECDH      *ecdh.PublicKey
	Signature []byte
}

func NewECDHReqSignal added in v0.2.6

func NewECDHReqSignal(ctx *Context, node *Node) (ECDHSignal, *ecdh.PrivateKey, error)

func NewECDHRespSignal added in v0.2.6

func NewECDHRespSignal(ctx *Context, 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 {
	StateSignal
	Time      time.Time `json:"time"`
	ECDSA     []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 ExtMap added in v0.2.0

type ExtMap map[uint64]Extension

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(context *Context, source NodeID, node *Node, signal Signal)
}

Extensions are data attached to nodes that process signals

func LoadACLExt added in v0.2.0

func LoadACLExt(ctx *Context, data []byte) (Extension, error)

func LoadECDHExt added in v0.2.0

func LoadECDHExt(ctx *Context, data []byte) (Extension, error)

func LoadGQLExt added in v0.2.0

func LoadGQLExt(ctx *Context, data []byte) (Extension, error)

func LoadGroupExt added in v0.2.0

func LoadGroupExt(ctx *Context, data []byte) (Extension, error)

func LoadListenerExt added in v0.2.0

func LoadListenerExt(ctx *Context, data []byte) (Extension, error)

Simple load function, unmarshal the buffer int from json

func LoadLockableExt added in v0.2.0

func LoadLockableExt(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 {
	Listen string
	// 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) Field added in v0.2.6

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

func (*GQLExt) Process added in v0.2.0

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

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 GQLExtJSON added in v0.2.0

type GQLExtJSON struct {
	Listen  string `json:"listen"`
	TLSKey  []byte `json:"ssl_key"`
	TLSCert []byte `json:"ssl_cert"`
}

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
}

func NewGroupExt added in v0.2.0

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

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, princ_id NodeID, node *Node, signal Signal)

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 GroupExtJSON added in v0.2.4

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

type IDSignal added in v0.2.0

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

func NewIDSignal added in v0.2.0

func NewIDSignal(signal_type SignalType, direction SignalDirection, id NodeID) IDSignal

func (IDSignal) Serialize added in v0.2.6

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

func (IDSignal) String added in v0.2.0

func (signal IDSignal) String() string

type IDStateSignal added in v0.2.6

type IDStateSignal struct {
	BaseSignal
	ID    NodeID `json:"id"`
	State string `json:"state"`
}

func NewIDStateSignal added in v0.2.7

func NewIDStateSignal(signal_type SignalType, direction SignalDirection, state string, id NodeID) IDStateSignal

func NewLinkStartSignal added in v0.2.6

func NewLinkStartSignal(link_type string, target NodeID) IDStateSignal

func NewStatusSignal added in v0.2.0

func NewStatusSignal(status string, source NodeID) IDStateSignal

func (IDStateSignal) Serialize added in v0.2.6

func (signal IDStateSignal) Serialize() ([]byte, error)

func (IDStateSignal) String added in v0.2.6

func (signal IDStateSignal) String() string

type Interface added in v0.2.6

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

type LinkMap added in v0.2.7

type LinkMap map[NodeID]LinkState

A LockableExt allows a node to be linked to other nodes(via LinkSignal) and locked/unlocked(via LockSignal)

func (LinkMap) MarshalJSON added in v0.2.7

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

func (LinkMap) UnmarshalJSON added in v0.2.7

func (m LinkMap) UnmarshalJSON(data []byte) error

type LinkState added in v0.2.7

type LinkState struct {
	Link      string `json:"link"`
	Lock      string `json:"lock"`
	Initiator NodeID `json:"initiator"`
}

ReqState holds the multiple states of a requirement

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) 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, princ_id NodeID, node *Node, signal Signal)

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 {
	Owner        *NodeID `json:"owner"`
	PendingOwner *NodeID `json:"pending_owner"`
	Requirements LinkMap `json:"requirements"`
	Dependencies LinkMap `json:"dependencies"`
}

func NewLockableExt added in v0.2.0

func NewLockableExt() *LockableExt

func (*LockableExt) Field added in v0.2.6

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

func (*LockableExt) HandleLinkSignal added in v0.2.0

func (ext *LockableExt) HandleLinkSignal(ctx *Context, source NodeID, node *Node, signal StateSignal)

Handle LinkSignal, updating the extensions requirements and dependencies as necessary TODO: Add unlink

func (*LockableExt) HandleLinkStartSignal added in v0.2.6

func (ext *LockableExt) HandleLinkStartSignal(ctx *Context, source NodeID, node *Node, signal IDStateSignal)

func (*LockableExt) HandleLockSignal added in v0.2.0

func (ext *LockableExt) HandleLockSignal(ctx *Context, source NodeID, node *Node, signal StateSignal)

Handle a LockSignal and update the extensions owner/requirement states

func (*LockableExt) Process added in v0.2.0

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

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 Msg added in v0.2.0

type Msg struct {
	Source NodeID
	Signal Signal
}

type Node

type Node struct {
	Key        *ecdsa.PrivateKey
	ID         NodeID
	Type       NodeType
	Extensions map[ExtType]Extension

	// Channel for this node to receive messages from the Context
	MsgChan chan Msg
	// 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 *ecdsa.PrivateKey, node_type NodeType, buffer_size uint32, queued_signals []QueuedSignal, extensions ...Extension) *Node

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

func (*Node) ClearSignalQueue added in v0.2.0

func (node *Node) ClearSignalQueue()

func (*Node) Process added in v0.2.0

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

func (*Node) QueueSignal added in v0.2.0

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

func (*Node) Serialize

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

type NodeActions added in v0.2.0

type NodeActions map[NodeID]Actions

func (NodeActions) MarshalJSON added in v0.2.6

func (actions NodeActions) MarshalJSON() ([]byte, error)

func (NodeActions) UnmarshalJSON added in v0.2.6

func (actions NodeActions) UnmarshalJSON(data []byte) error

type NodeDB added in v0.2.0

type NodeDB struct {
	Header        NodeDBHeader
	QueuedSignals []QueuedSignal
	Extensions    []ExtensionDB
	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
	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 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 [16]byte) NodeID

Create an ID from a fixed length byte array Ignore the error since we're enforcing 16 byte length at compile time

func KeyID added in v0.2.6

func KeyID(pub *ecdsa.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) MarshalJSON added in v0.2.0

func (id *NodeID) MarshalJSON() ([]byte, error)

func (NodeID) Serialize

func (id NodeID) Serialize() []byte

func (NodeID) String added in v0.2.0

func (id NodeID) String() string

func (*NodeID) UnmarshalJSON added in v0.2.0

func (id *NodeID) UnmarshalJSON(bytes []byte) error

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 NodeMap

type NodeMap map[NodeID]*Node

func NodeList

func NodeList(nodes ...*Node) NodeMap

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 PerNodePolicy added in v0.2.0

type PerNodePolicy struct {
	NodeActions NodeActions `json:"node_actions"`
}

func NewPerNodePolicy added in v0.2.0

func NewPerNodePolicy(node_actions NodeActions) PerNodePolicy

func (PerNodePolicy) Allows added in v0.2.0

func (policy PerNodePolicy) Allows(principal_id NodeID, action Action, node *Node) 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 Action, node *Node) error
	// Merge with another policy of the same underlying type
	Merge(Policy) Policy
}

type PolicyInfo added in v0.2.0

type PolicyInfo struct {
	Load PolicyLoadFunc
}

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 QueuedSignal added in v0.2.0

type QueuedSignal struct {
	uuid.UUID
	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
	uuid.UUID
	NodeType
	Extensions map[ExtType]map[string]interface{} `json:"extensions"`
}

func NewReadResultSignal added in v0.2.6

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

func WaitForReadResult added in v0.2.6

func WaitForReadResult(listener chan *ReadResultSignal, timeout time.Duration, id uuid.UUID) (*ReadResultSignal, error)

type ReadSignal added in v0.2.6

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

func NewReadSignal added in v0.2.6

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

func (ReadSignal) Serialize added in v0.2.6

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

type RequirementOfPolicy added in v0.2.0

type RequirementOfPolicy struct {
	AllNodesPolicy
}

func NewRequirementOfPolicy added in v0.2.0

func NewRequirementOfPolicy(actions Actions) RequirementOfPolicy

func (RequirementOfPolicy) Allows added in v0.2.0

func (policy RequirementOfPolicy) Allows(principal_id NodeID, action Action, node *Node) error

func (RequirementOfPolicy) Merge added in v0.2.5

func (policy RequirementOfPolicy) Merge(p Policy) Policy

func (RequirementOfPolicy) Type added in v0.2.0

func (policy RequirementOfPolicy) Type() PolicyType

type ResolveContext added in v0.2.0

type ResolveContext struct {
	// ID generated for the context so the gql extension can route data to it
	ID uuid.UUID

	// Channel for the gql extension to route data to this context
	Chan chan *ReadResultSignal

	// 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
	// TODO: figure out auth
	User NodeID
}

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 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 {
	Type() I
	Serialize() ([]byte, error)
}

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]
	Direction() SignalDirection
	Permission() Action
}

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)

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 StateContext added in v0.2.0

type StateContext struct {
	// Type of the state context
	Type string
	// The wrapped graph context
	Graph *Context
	// Granted permissions in the context
	Permissions map[NodeID]ACLMap
	// Locked extensions in the context
	Locked map[NodeID]*Node

	// Context state for validation
	Started  bool
	Finished bool
}

Context of running state usage(read/write)

func NewReadContext added in v0.2.0

func NewReadContext(ctx *Context) *StateContext

func NewWriteContext added in v0.2.0

func NewWriteContext(ctx *Context) *StateContext

type StateFn added in v0.2.0

type StateFn func(*StateContext) error

type StateSignal added in v0.2.0

type StateSignal struct {
	BaseSignal
	State string `json:"state"`
}

func NewLinkSignal added in v0.2.0

func NewLinkSignal(state string) StateSignal

func NewLockSignal added in v0.2.0

func NewLockSignal(state string) StateSignal

func (StateSignal) Permission added in v0.2.6

func (signal StateSignal) Permission() Action

func (StateSignal) Serialize added in v0.2.0

func (signal StateSignal) Serialize() ([]byte, error)

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