Added Singleton and Field to simplify GQL definitions

graph-rework-2
noah metz 2023-07-21 17:49:19 -06:00
parent 551370e541
commit d4fcd80ff8
7 changed files with 636 additions and 663 deletions

@ -120,6 +120,10 @@ type GQLContext struct {
ValidLockables ObjTypeMap
ValidThreads ObjTypeMap
BaseNodeType *graphql.Object
BaseLockableType *graphql.Object
BaseThreadType *graphql.Object
Query *graphql.Object
Mutation *graphql.Object
Subscription *graphql.Object
@ -154,6 +158,7 @@ func NewGQLContext() GQLContext {
Query: query,
Mutation: mutation,
Subscription: subscription,
BaseNodeType: GQLTypeGraphNode.Type,
}
return ctx
@ -168,48 +173,49 @@ func NewContext(db * badger.DB, log Logger) * Context {
Types: map[uint64]NodeDef{},
}
err := ctx.RegisterNodeType(NewNodeDef((*GraphNode)(nil), LoadGraphNode, GQLTypeGraphNode()))
err := ctx.RegisterNodeType(NewNodeDef((*GraphNode)(nil), LoadGraphNode, GQLTypeGraphNode.Type))
if err != nil {
panic(err)
}
err = ctx.RegisterNodeType(NewNodeDef((*SimpleLockable)(nil), LoadSimpleLockable, GQLTypeSimpleLockable()))
err = ctx.RegisterNodeType(NewNodeDef((*SimpleLockable)(nil), LoadSimpleLockable, GQLTypeSimpleLockable.Type))
if err != nil {
panic(err)
}
err = ctx.RegisterNodeType(NewNodeDef((*SimpleThread)(nil), LoadSimpleThread, GQLTypeSimpleThread()))
err = ctx.RegisterNodeType(NewNodeDef((*SimpleThread)(nil), LoadSimpleThread, GQLTypeSimpleThread.Type))
if err != nil {
panic(err)
}
err = ctx.RegisterNodeType(NewNodeDef((*GQLThread)(nil), LoadGQLThread, GQLTypeGQLThread()))
err = ctx.RegisterNodeType(NewNodeDef((*GQLThread)(nil), LoadGQLThread, GQLTypeGQLThread.Type))
if err != nil {
panic(err)
}
err = ctx.RegisterNodeType(NewNodeDef((*User)(nil), LoadUser, GQLTypeUser()))
err = ctx.RegisterNodeType(NewNodeDef((*User)(nil), LoadUser, GQLTypeUser.Type))
if err != nil {
panic(err)
}
err = ctx.RegisterNodeType(NewNodeDef((*PerNodePolicy)(nil), LoadPerNodePolicy, GQLTypeGraphNode()))
err = ctx.RegisterNodeType(NewNodeDef((*PerNodePolicy)(nil), LoadPerNodePolicy, GQLTypeGraphNode.Type))
if err != nil {
panic(err)
}
err = ctx.RegisterNodeType(NewNodeDef((*SimplePolicy)(nil), LoadSimplePolicy, GQLTypeGraphNode()))
err = ctx.RegisterNodeType(NewNodeDef((*SimplePolicy)(nil), LoadSimplePolicy, GQLTypeGraphNode.Type))
if err != nil {
panic(err)
}
err = ctx.RegisterNodeType(NewNodeDef((*PerTagPolicy)(nil), LoadPerTagPolicy, GQLTypeGraphNode()))
err = ctx.RegisterNodeType(NewNodeDef((*PerTagPolicy)(nil), LoadPerTagPolicy, GQLTypeGraphNode.Type))
if err != nil {
panic(err)
}
ctx.AddGQLType(GQLTypeSignal())
ctx.AddGQLType(GQLTypeSignal.Type)
ctx.GQL.Query.AddFieldConfig("Self", GQLQuerySelf())
ctx.GQL.Query.AddFieldConfig("Self", GQLQuerySelf)
ctx.GQL.Query.AddFieldConfig("User", GQLQueryUser)
ctx.GQL.Subscription.AddFieldConfig("Update", GQLSubscriptionUpdate())
ctx.GQL.Subscription.AddFieldConfig("Self", GQLSubscriptionSelf())
ctx.GQL.Subscription.AddFieldConfig("Update", GQLSubscriptionUpdate)
ctx.GQL.Subscription.AddFieldConfig("Self", GQLSubscriptionSelf)
ctx.GQL.Mutation.AddFieldConfig("sendUpdate", GQLMutationSendUpdate())
ctx.GQL.Mutation.AddFieldConfig("startChild", GQLMutationStartChild())
ctx.GQL.Mutation.AddFieldConfig("sendUpdate", GQLMutationSendUpdate)
ctx.GQL.Mutation.AddFieldConfig("startChild", GQLMutationStartChild)
err = ctx.RebuildSchema()
if err != nil {

@ -4,135 +4,130 @@ import (
"github.com/graphql-go/graphql"
)
var gql_mutation_send_update *graphql.Field = nil
func GQLMutationSendUpdate() *graphql.Field {
if gql_mutation_send_update == nil {
gql_mutation_send_update = &graphql.Field{
Type: GQLTypeSignal(),
Args: graphql.FieldConfigArgument{
"id": &graphql.ArgumentConfig{
Type: graphql.String,
},
"signal": &graphql.ArgumentConfig{
Type: GQLTypeSignalInput(),
},
var GQLMutationSendUpdate = NewField(func()*graphql.Field {
gql_mutation_send_update := &graphql.Field{
Type: GQLTypeSignal.Type,
Args: graphql.FieldConfigArgument{
"id": &graphql.ArgumentConfig{
Type: graphql.String,
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
ctx, server, user, err := PrepResolve(p)
if err != nil {
return nil, err
}
err = server.Allowed("signal", "self", user)
if err != nil {
return nil, err
}
signal_map, err := ExtractParam[map[string]interface{}](p, "signal")
if err != nil {
return nil, err
}
var signal GraphSignal = nil
if signal_map["Direction"] == "up" {
signal = NewSignal(server, signal_map["Type"].(string))
} else if signal_map["Direction"] == "down" {
signal = NewDownSignal(server, signal_map["Type"].(string))
} else if signal_map["Direction"] == "direct" {
signal = NewDirectSignal(server, signal_map["Type"].(string))
} else {
return nil, fmt.Errorf("Bad direction: %d", signal_map["Direction"])
}
id, err := ExtractID(p, "id")
if err != nil {
return nil, err
}
var node Node = nil
err = UseStates(ctx, []Node{server}, func(nodes NodeMap) (error){
node = FindChild(ctx, server, id, nodes)
if node == nil {
return fmt.Errorf("Failed to find ID: %s as child of server thread", id)
}
node.Signal(ctx, signal, nodes)
return nil
})
if err != nil {
return nil, err
}
return signal, nil
"signal": &graphql.ArgumentConfig{
Type: GQLTypeSignalInput.Type,
},
}
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
ctx, server, user, err := PrepResolve(p)
if err != nil {
return nil, err
}
err = server.Allowed("signal", "self", user)
if err != nil {
return nil, err
}
signal_map, err := ExtractParam[map[string]interface{}](p, "signal")
if err != nil {
return nil, err
}
var signal GraphSignal = nil
if signal_map["Direction"] == "up" {
signal = NewSignal(server, signal_map["Type"].(string))
} else if signal_map["Direction"] == "down" {
signal = NewDownSignal(server, signal_map["Type"].(string))
} else if signal_map["Direction"] == "direct" {
signal = NewDirectSignal(server, signal_map["Type"].(string))
} else {
return nil, fmt.Errorf("Bad direction: %d", signal_map["Direction"])
}
id, err := ExtractID(p, "id")
if err != nil {
return nil, err
}
var node Node = nil
err = UseStates(ctx, []Node{server}, func(nodes NodeMap) (error){
node = FindChild(ctx, server, id, nodes)
if node == nil {
return fmt.Errorf("Failed to find ID: %s as child of server thread", id)
}
node.Signal(ctx, signal, nodes)
return nil
})
if err != nil {
return nil, err
}
return signal, nil
},
}
return gql_mutation_send_update
}
var gql_mutation_start_child *graphql.Field = nil
func GQLMutationStartChild() *graphql.Field {
if gql_mutation_start_child == nil {
gql_mutation_start_child = &graphql.Field{
Type: GQLTypeSignal(),
Args: graphql.FieldConfigArgument{
"parent_id": &graphql.ArgumentConfig{
Type: graphql.String,
},
"child_id": &graphql.ArgumentConfig{
Type: graphql.String,
},
"action": &graphql.ArgumentConfig{
Type: graphql.String,
DefaultValue: "start",
},
})
var GQLMutationStartChild = NewField(func()*graphql.Field{
gql_mutation_start_child := &graphql.Field{
Type: GQLTypeSignal.Type,
Args: graphql.FieldConfigArgument{
"parent_id": &graphql.ArgumentConfig{
Type: graphql.String,
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
ctx, server, user, err := PrepResolve(p)
if err != nil {
return nil, err
}
err = server.Allowed("start_child", "self", user)
if err != nil {
return nil, err
}
parent_id, err := ExtractID(p, "parent_id")
if err != nil {
return nil, err
}
child_id, err := ExtractID(p, "child_id")
if err != nil {
return nil, err
}
action, err := ExtractParam[string](p, "action")
if err != nil {
return nil, err
"child_id": &graphql.ArgumentConfig{
Type: graphql.String,
},
"action": &graphql.ArgumentConfig{
Type: graphql.String,
DefaultValue: "start",
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
ctx, server, user, err := PrepResolve(p)
if err != nil {
return nil, err
}
err = server.Allowed("start_child", "self", user)
if err != nil {
return nil, err
}
parent_id, err := ExtractID(p, "parent_id")
if err != nil {
return nil, err
}
child_id, err := ExtractID(p, "child_id")
if err != nil {
return nil, err
}
action, err := ExtractParam[string](p, "action")
if err != nil {
return nil, err
}
var signal GraphSignal
err = UseStates(ctx, []Node{server}, func(nodes NodeMap) (error){
node := FindChild(ctx, server, parent_id, nodes)
if node == nil {
return fmt.Errorf("Failed to find ID: %s as child of server thread", parent_id)
}
var signal GraphSignal
err = UseStates(ctx, []Node{server}, func(nodes NodeMap) (error){
node := FindChild(ctx, server, parent_id, nodes)
if node == nil {
return fmt.Errorf("Failed to find ID: %s as child of server thread", parent_id)
}
return UseMoreStates(ctx, []Node{node}, nodes, func(NodeMap) error {
signal = NewStartChildSignal(server, child_id, action)
return node.Signal(ctx, signal, nodes)
})
return UseMoreStates(ctx, []Node{node}, nodes, func(NodeMap) error {
signal = NewStartChildSignal(server, child_id, action)
return node.Signal(ctx, signal, nodes)
})
if err != nil {
return nil, err
}
// TODO: wait for the result of the signal to send back instead of just the signal
return signal, nil
},
}
})
if err != nil {
return nil, err
}
// TODO: wait for the result of the signal to send back instead of just the signal
return signal, nil
},
}
return gql_mutation_start_child
}
})

@ -1,30 +1,38 @@
package graphvent
import (
"fmt"
"github.com/graphql-go/graphql"
)
var gql_query_self *graphql.Field = nil
func GQLQuerySelf() *graphql.Field {
if gql_query_self == nil {
gql_query_self = &graphql.Field{
Type: GQLTypeGQLThread(),
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
_, server, user, err := PrepResolve(p)
var GQLQuerySelf = &graphql.Field{
Type: GQLTypeGQLThread.Type,
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
_, server, user, err := PrepResolve(p)
if err != nil {
return nil, err
}
if err != nil {
return nil, err
}
err = server.Allowed("enumerate", "self", user)
if err != nil {
return nil, err
}
err = server.Allowed("enumerate", "self", user)
if err != nil {
return nil, fmt.Errorf("User %s is not allowed to perform self.enumerate on %s", user.ID(), server.ID())
}
return server, nil
},
}
var GQLQueryUser = &graphql.Field{
Type: GQLTypeUser.Type,
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
_, _, user, err := PrepResolve(p)
if err != nil {
return nil, err
}
return server, nil
},
err = user.Allowed("enumerate", "self", user)
if err != nil {
return nil, err
}
}
return gql_query_self
return user, nil
},
}

@ -50,33 +50,26 @@ func GQLSubscribeFn(p graphql.ResolveParams, send_nil bool, fn func(*Context, *G
return c, nil
}
var gql_subscription_self * graphql.Field = nil
func GQLSubscriptionSelf() * graphql.Field {
if gql_subscription_self == nil {
gql_subscription_self = &graphql.Field{
Type: GQLTypeGQLThread(),
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
return p.Source, nil
},
Subscribe: GQLSubscribeSelf,
}
var GQLSubscriptionSelf = NewField(func()*graphql.Field{
gql_subscription_self := &graphql.Field{
Type: GQLTypeGQLThread.Type,
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
return p.Source, nil
},
Subscribe: GQLSubscribeSelf,
}
return gql_subscription_self
}
})
var gql_subscription_update * graphql.Field = nil
func GQLSubscriptionUpdate() * graphql.Field {
if gql_subscription_update == nil {
gql_subscription_update = &graphql.Field{
Type: GQLTypeSignal(),
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
return p.Source, nil
},
Subscribe: GQLSubscribeSignal,
}
var GQLSubscriptionUpdate = NewField(func()*graphql.Field{
gql_subscription_update := &graphql.Field{
Type: GQLTypeSignal.Type,
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
return p.Source, nil
},
Subscribe: GQLSubscribeSignal,
}
return gql_subscription_update
}
})

@ -237,7 +237,7 @@ func TestGQLAuth(t * testing.T) {
url = fmt.Sprintf("https://localhost:%d/gql", port)
ser, err := json.MarshalIndent(&GQLPayload{
Query: "query { Self { Users { ID } } }",
Query: "query { Self { Users { ID, Name } } }",
}, "", " ")
fatalErr(t, err)

@ -5,532 +5,497 @@ import (
"reflect"
)
var gql_interface_graph_node *graphql.Interface = nil
func GQLInterfaceNode() *graphql.Interface {
if gql_interface_graph_node == nil {
gql_interface_graph_node = graphql.NewInterface(graphql.InterfaceConfig{
Name: "Node",
ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {
ctx, ok := p.Context.Value("graph_context").(*Context)
if ok == false {
return nil
}
valid_nodes := ctx.GQL.ValidNodes
node_type := ctx.GQL.NodeType
p_type := reflect.TypeOf(p.Value)
for key, value := range(valid_nodes) {
if p_type == key {
return value
}
}
if p_type.Implements(node_type) {
return GQLTypeGraphNode()
}
type Field *graphql.Field
return nil
},
Fields: graphql.Fields{},
})
gql_interface_graph_node.AddFieldConfig("ID", &graphql.Field{
Type: graphql.String,
})
}
return gql_interface_graph_node
func NewField(init func()*graphql.Field) Field {
return Field(init())
}
var gql_list_thread *graphql.List = nil
func GQLListThread() *graphql.List {
if gql_list_thread == nil {
gql_list_thread = graphql.NewList(GQLInterfaceThread())
}
return gql_list_thread
type Singleton[K graphql.Type] struct {
Type K
List *graphql.List
}
var gql_interface_thread *graphql.Interface = nil
func GQLInterfaceThread() *graphql.Interface {
if gql_interface_thread == nil {
gql_interface_thread = graphql.NewInterface(graphql.InterfaceConfig{
Name: "Thread",
ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {
ctx, ok := p.Context.Value("graph_context").(*Context)
if ok == false {
return nil
}
valid_threads := ctx.GQL.ValidThreads
thread_type := ctx.GQL.ThreadType
p_type := reflect.TypeOf(p.Value)
for key, value := range(valid_threads) {
if p_type == key {
return value
}
}
if p_type.Implements(thread_type) {
return GQLTypeSimpleThread()
}
ctx.Log.Logf("gql", "Found no type that matches %+v: %+v", p_type, p_type.Implements(thread_type))
return nil
},
Fields: graphql.Fields{},
})
gql_interface_thread.AddFieldConfig("ID", &graphql.Field{
Type: graphql.String,
})
gql_interface_thread.AddFieldConfig("Name", &graphql.Field{
Type: graphql.String,
})
gql_interface_thread.AddFieldConfig("State", &graphql.Field{
Type: graphql.String,
})
gql_interface_thread.AddFieldConfig("Children", &graphql.Field{
Type: GQLListThread(),
})
gql_interface_thread.AddFieldConfig("Parent", &graphql.Field{
Type: GQLInterfaceThread(),
})
gql_interface_thread.AddFieldConfig("Requirements", &graphql.Field{
Type: GQLListLockable(),
})
gql_interface_thread.AddFieldConfig("Dependencies", &graphql.Field{
Type: GQLListLockable(),
})
gql_interface_thread.AddFieldConfig("Owner", &graphql.Field{
Type: GQLInterfaceLockable(),
})
func NewSingleton[K graphql.Type](init func() K, post_init func(K, *graphql.List)) *Singleton[K] {
val := init()
list := graphql.NewList(val)
if post_init != nil {
post_init(val, list)
}
return gql_interface_thread
}
var gql_list_lockable *graphql.List = nil
func GQLListLockable() *graphql.List {
if gql_list_lockable == nil {
gql_list_lockable = graphql.NewList(GQLInterfaceLockable())
return &Singleton[K]{
Type: val,
List: list,
}
return gql_list_lockable
}
var gql_interface_lockable *graphql.Interface = nil
func GQLInterfaceLockable() *graphql.Interface {
if gql_interface_lockable == nil {
gql_interface_lockable = graphql.NewInterface(graphql.InterfaceConfig{
Name: "Lockable",
ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {
ctx, ok := p.Context.Value("graph_context").(*Context)
if ok == false {
return nil
}
var GQLInterfaceNode = NewSingleton(func() *graphql.Interface {
i := graphql.NewInterface(graphql.InterfaceConfig{
Name: "Node",
ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {
ctx, ok := p.Context.Value("graph_context").(*Context)
if ok == false {
return nil
}
valid_lockables := ctx.GQL.ValidLockables
lockable_type := ctx.GQL.LockableType
p_type := reflect.TypeOf(p.Value)
valid_nodes := ctx.GQL.ValidNodes
node_type := ctx.GQL.NodeType
p_type := reflect.TypeOf(p.Value)
for key, value := range(valid_lockables) {
if p_type == key {
return value
}
}
if p_type.Implements(lockable_type) {
return GQLTypeSimpleLockable()
for key, value := range(valid_nodes) {
if p_type == key {
return value
}
}
if p_type.Implements(node_type) {
return ctx.GQL.BaseNodeType
}
return nil
},
Fields: graphql.Fields{},
})
i.AddFieldConfig("ID", &graphql.Field{
Type: graphql.String,
})
return i
}, nil)
var GQLInterfaceThread = NewSingleton(func() *graphql.Interface {
gql_interface_thread := graphql.NewInterface(graphql.InterfaceConfig{
Name: "Thread",
ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {
ctx, ok := p.Context.Value("graph_context").(*Context)
if ok == false {
return nil
},
Fields: graphql.Fields{},
})
}
gql_interface_lockable.AddFieldConfig("ID", &graphql.Field{
Type: graphql.String,
})
valid_threads := ctx.GQL.ValidThreads
thread_type := ctx.GQL.ThreadType
p_type := reflect.TypeOf(p.Value)
gql_interface_lockable.AddFieldConfig("Name", &graphql.Field{
Type: graphql.String,
})
for key, value := range(valid_threads) {
if p_type == key {
return value
}
}
if gql_list_lockable == nil {
gql_list_lockable = graphql.NewList(gql_interface_lockable)
}
if p_type.Implements(thread_type) {
return ctx.GQL.BaseThreadType
}
gql_interface_lockable.AddFieldConfig("Requirements", &graphql.Field{
Type: gql_list_lockable,
})
ctx.Log.Logf("gql", "Found no type that matches %+v: %+v", p_type, p_type.Implements(thread_type))
return nil
},
Fields: graphql.Fields{},
})
gql_interface_lockable.AddFieldConfig("Dependencies", &graphql.Field{
Type: gql_list_lockable,
})
gql_interface_thread.AddFieldConfig("ID", &graphql.Field{
Type: graphql.String,
})
gql_interface_lockable.AddFieldConfig("Owner", &graphql.Field{
Type: gql_interface_lockable,
})
gql_interface_thread.AddFieldConfig("Name", &graphql.Field{
Type: graphql.String,
})
}
gql_interface_thread.AddFieldConfig("State", &graphql.Field{
Type: graphql.String,
})
return gql_interface_lockable
}
gql_interface_thread.AddFieldConfig("Requirements", &graphql.Field{
Type: GQLInterfaceLockable.List,
})
var gql_list_user *graphql.List = nil
func GQLListUser() *graphql.List {
if gql_list_user == nil {
gql_list_user = graphql.NewList(GQLTypeUser())
}
return gql_list_user
}
gql_interface_thread.AddFieldConfig("Dependencies", &graphql.Field{
Type: GQLInterfaceLockable.List,
})
var gql_type_user *graphql.Object = nil
func GQLTypeUser() * graphql.Object {
if gql_type_user == nil {
gql_type_user = graphql.NewObject(graphql.ObjectConfig{
Name: "User",
Interfaces: []*graphql.Interface{
GQLInterfaceNode(),
GQLInterfaceLockable(),
},
IsTypeOf: func(p graphql.IsTypeOfParams) bool {
ctx, ok := p.Context.Value("graph_context").(*Context)
if ok == false {
return false
}
gql_interface_thread.AddFieldConfig("Owner", &graphql.Field{
Type: GQLInterfaceLockable.Type,
})
lockable_type := ctx.GQL.LockableType
value_type := reflect.TypeOf(p.Value)
return gql_interface_thread
}, func(thread *graphql.Interface, thread_list *graphql.List) {
thread.AddFieldConfig("Children", &graphql.Field{
Type: thread_list,
})
thread.AddFieldConfig("Parent", &graphql.Field{
Type: thread,
})
})
var GQLInterfaceLockable = NewSingleton(func() *graphql.Interface {
gql_interface_lockable := graphql.NewInterface(graphql.InterfaceConfig{
Name: "Lockable",
ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {
ctx, ok := p.Context.Value("graph_context").(*Context)
if ok == false {
return nil
}
if value_type.Implements(lockable_type) {
return true
}
valid_lockables := ctx.GQL.ValidLockables
lockable_type := ctx.GQL.LockableType
p_type := reflect.TypeOf(p.Value)
for key, value := range(valid_lockables) {
if p_type == key {
return value
}
}
if p_type.Implements(lockable_type) {
return ctx.GQL.BaseThreadType
}
return nil
},
Fields: graphql.Fields{},
})
gql_interface_lockable.AddFieldConfig("ID", &graphql.Field{
Type: graphql.String,
})
gql_interface_lockable.AddFieldConfig("Name", &graphql.Field{
Type: graphql.String,
})
return gql_interface_lockable
}, func(lockable *graphql.Interface, lockable_list *graphql.List) {
lockable.AddFieldConfig("Requirements", &graphql.Field{
Type: lockable_list,
})
lockable.AddFieldConfig("Dependencies", &graphql.Field{
Type: lockable_list,
})
lockable.AddFieldConfig("Owner", &graphql.Field{
Type: lockable,
})
})
var GQLTypeUser = NewSingleton(func() *graphql.Object {
gql_type_user := graphql.NewObject(graphql.ObjectConfig{
Name: "User",
Interfaces: []*graphql.Interface{
GQLInterfaceNode.Type,
GQLInterfaceLockable.Type,
},
IsTypeOf: func(p graphql.IsTypeOfParams) bool {
ctx, ok := p.Context.Value("graph_context").(*Context)
if ok == false {
return false
},
Fields: graphql.Fields{},
})
gql_type_user.AddFieldConfig("ID", &graphql.Field{
Type: graphql.String,
Resolve: GQLNodeID,
})
gql_type_user.AddFieldConfig("Name", &graphql.Field{
Type: graphql.String,
Resolve: GQLLockableName,
})
gql_type_user.AddFieldConfig("Requirements", &graphql.Field{
Type: GQLListLockable(),
Resolve: GQLLockableRequirements,
})
gql_type_user.AddFieldConfig("Owner", &graphql.Field{
Type: GQLInterfaceLockable(),
Resolve: GQLLockableOwner,
})
gql_type_user.AddFieldConfig("Dependencies", &graphql.Field{
Type: GQLListLockable(),
Resolve: GQLLockableDependencies,
})
}
}
lockable_type := ctx.GQL.LockableType
value_type := reflect.TypeOf(p.Value)
if value_type.Implements(lockable_type) {
return true
}
return false
},
Fields: graphql.Fields{},
})
gql_type_user.AddFieldConfig("ID", &graphql.Field{
Type: graphql.String,
Resolve: GQLNodeID,
})
gql_type_user.AddFieldConfig("Name", &graphql.Field{
Type: graphql.String,
Resolve: GQLLockableName,
})
gql_type_user.AddFieldConfig("Requirements", &graphql.Field{
Type: GQLInterfaceLockable.List,
Resolve: GQLLockableRequirements,
})
gql_type_user.AddFieldConfig("Owner", &graphql.Field{
Type: GQLInterfaceLockable.Type,
Resolve: GQLLockableOwner,
})
gql_type_user.AddFieldConfig("Dependencies", &graphql.Field{
Type: GQLInterfaceLockable.List,
Resolve: GQLLockableDependencies,
})
return gql_type_user
}
var gql_type_gql_thread *graphql.Object = nil
func GQLTypeGQLThread() * graphql.Object {
if gql_type_gql_thread == nil {
gql_type_gql_thread = graphql.NewObject(graphql.ObjectConfig{
Name: "GQLThread",
Interfaces: []*graphql.Interface{
GQLInterfaceNode(),
GQLInterfaceThread(),
GQLInterfaceLockable(),
},
IsTypeOf: func(p graphql.IsTypeOfParams) bool {
_, ok := p.Value.(*GQLThread)
return ok
},
Fields: graphql.Fields{},
})
gql_type_gql_thread.AddFieldConfig("ID", &graphql.Field{
Type: graphql.String,
Resolve: GQLNodeID,
})
gql_type_gql_thread.AddFieldConfig("Name", &graphql.Field{
Type: graphql.String,
Resolve: GQLLockableName,
})
gql_type_gql_thread.AddFieldConfig("State", &graphql.Field{
Type: graphql.String,
Resolve: GQLThreadState,
})
gql_type_gql_thread.AddFieldConfig("Children", &graphql.Field{
Type: GQLListThread(),
Resolve: GQLThreadChildren,
})
gql_type_gql_thread.AddFieldConfig("Parent", &graphql.Field{
Type: GQLInterfaceThread(),
Resolve: GQLThreadParent,
})
gql_type_gql_thread.AddFieldConfig("Listen", &graphql.Field{
Type: graphql.String,
Resolve: GQLThreadListen,
})
gql_type_gql_thread.AddFieldConfig("Requirements", &graphql.Field{
Type: GQLListLockable(),
Resolve: GQLLockableRequirements,
})
gql_type_gql_thread.AddFieldConfig("Owner", &graphql.Field{
Type: GQLInterfaceLockable(),
Resolve: GQLLockableOwner,
})
gql_type_gql_thread.AddFieldConfig("Dependencies", &graphql.Field{
Type: GQLListLockable(),
Resolve: GQLLockableDependencies,
})
gql_type_gql_thread.AddFieldConfig("Users", &graphql.Field{
Type: GQLListUser(),
Resolve: GQLThreadUsers,
})
}
}, nil)
var GQLTypeGQLThread = NewSingleton(func() *graphql.Object {
gql_type_gql_thread := graphql.NewObject(graphql.ObjectConfig{
Name: "GQLThread",
Interfaces: []*graphql.Interface{
GQLInterfaceNode.Type,
GQLInterfaceThread.Type,
GQLInterfaceLockable.Type,
},
IsTypeOf: func(p graphql.IsTypeOfParams) bool {
_, ok := p.Value.(*GQLThread)
return ok
},
Fields: graphql.Fields{},
})
gql_type_gql_thread.AddFieldConfig("ID", &graphql.Field{
Type: graphql.String,
Resolve: GQLNodeID,
})
gql_type_gql_thread.AddFieldConfig("Name", &graphql.Field{
Type: graphql.String,
Resolve: GQLLockableName,
})
gql_type_gql_thread.AddFieldConfig("State", &graphql.Field{
Type: graphql.String,
Resolve: GQLThreadState,
})
gql_type_gql_thread.AddFieldConfig("Children", &graphql.Field{
Type: GQLInterfaceThread.List,
Resolve: GQLThreadChildren,
})
gql_type_gql_thread.AddFieldConfig("Parent", &graphql.Field{
Type: GQLInterfaceThread.Type,
Resolve: GQLThreadParent,
})
gql_type_gql_thread.AddFieldConfig("Listen", &graphql.Field{
Type: graphql.String,
Resolve: GQLThreadListen,
})
gql_type_gql_thread.AddFieldConfig("Requirements", &graphql.Field{
Type: GQLInterfaceLockable.List,
Resolve: GQLLockableRequirements,
})
gql_type_gql_thread.AddFieldConfig("Owner", &graphql.Field{
Type: GQLInterfaceLockable.Type,
Resolve: GQLLockableOwner,
})
gql_type_gql_thread.AddFieldConfig("Dependencies", &graphql.Field{
Type: GQLInterfaceLockable.List,
Resolve: GQLLockableDependencies,
})
gql_type_gql_thread.AddFieldConfig("Users", &graphql.Field{
Type: GQLTypeUser.List,
Resolve: GQLThreadUsers,
})
return gql_type_gql_thread
}
var gql_type_simple_thread *graphql.Object = nil
func GQLTypeSimpleThread() * graphql.Object {
if gql_type_simple_thread == nil {
gql_type_simple_thread = graphql.NewObject(graphql.ObjectConfig{
Name: "SimpleThread",
Interfaces: []*graphql.Interface{
GQLInterfaceNode(),
GQLInterfaceThread(),
GQLInterfaceLockable(),
},
IsTypeOf: func(p graphql.IsTypeOfParams) bool {
ctx, ok := p.Context.Value("graph_context").(*Context)
if ok == false {
return false
}
thread_type := ctx.GQL.ThreadType
value_type := reflect.TypeOf(p.Value)
if value_type.Implements(thread_type) {
return true
}
}, nil)
var GQLTypeSimpleThread = NewSingleton(func() *graphql.Object {
gql_type_simple_thread := graphql.NewObject(graphql.ObjectConfig{
Name: "SimpleThread",
Interfaces: []*graphql.Interface{
GQLInterfaceNode.Type,
GQLInterfaceThread.Type,
GQLInterfaceLockable.Type,
},
IsTypeOf: func(p graphql.IsTypeOfParams) bool {
ctx, ok := p.Context.Value("graph_context").(*Context)
if ok == false {
return false
},
Fields: graphql.Fields{},
})
gql_type_simple_thread.AddFieldConfig("ID", &graphql.Field{
Type: graphql.String,
Resolve: GQLNodeID,
})
gql_type_simple_thread.AddFieldConfig("Name", &graphql.Field{
Type: graphql.String,
Resolve: GQLLockableName,
})
gql_type_simple_thread.AddFieldConfig("State", &graphql.Field{
Type: graphql.String,
Resolve: GQLThreadState,
})
gql_type_simple_thread.AddFieldConfig("Children", &graphql.Field{
Type: GQLListThread(),
Resolve: GQLThreadChildren,
})
gql_type_simple_thread.AddFieldConfig("Parent", &graphql.Field{
Type: GQLInterfaceThread(),
Resolve: GQLThreadParent,
})
gql_type_simple_thread.AddFieldConfig("Requirements", &graphql.Field{
Type: GQLListLockable(),
Resolve: GQLLockableRequirements,
})
gql_type_simple_thread.AddFieldConfig("Owner", &graphql.Field{
Type: GQLInterfaceLockable(),
Resolve: GQLLockableOwner,
})
gql_type_simple_thread.AddFieldConfig("Dependencies", &graphql.Field{
Type: GQLListLockable(),
Resolve: GQLLockableDependencies,
})
}
return gql_type_simple_thread
}
}
thread_type := ctx.GQL.ThreadType
value_type := reflect.TypeOf(p.Value)
if value_type.Implements(thread_type) {
return true
}
return false
},
Fields: graphql.Fields{},
})
gql_type_simple_thread.AddFieldConfig("ID", &graphql.Field{
Type: graphql.String,
Resolve: GQLNodeID,
})
gql_type_simple_thread.AddFieldConfig("Name", &graphql.Field{
Type: graphql.String,
Resolve: GQLLockableName,
})
gql_type_simple_thread.AddFieldConfig("State", &graphql.Field{
Type: graphql.String,
Resolve: GQLThreadState,
})
gql_type_simple_thread.AddFieldConfig("Children", &graphql.Field{
Type: GQLInterfaceThread.List,
Resolve: GQLThreadChildren,
})
gql_type_simple_thread.AddFieldConfig("Parent", &graphql.Field{
Type: GQLInterfaceThread.Type,
Resolve: GQLThreadParent,
})
gql_type_simple_thread.AddFieldConfig("Requirements", &graphql.Field{
Type: GQLInterfaceLockable.List,
Resolve: GQLLockableRequirements,
})
gql_type_simple_thread.AddFieldConfig("Owner", &graphql.Field{
Type: GQLInterfaceLockable.Type,
Resolve: GQLLockableOwner,
})
gql_type_simple_thread.AddFieldConfig("Dependencies", &graphql.Field{
Type: GQLInterfaceLockable.List,
Resolve: GQLLockableDependencies,
})
var gql_type_simple_lockable *graphql.Object = nil
func GQLTypeSimpleLockable() * graphql.Object {
if gql_type_simple_lockable == nil {
gql_type_simple_lockable = graphql.NewObject(graphql.ObjectConfig{
Name: "SimpleLockable",
Interfaces: []*graphql.Interface{
GQLInterfaceNode(),
GQLInterfaceLockable(),
},
IsTypeOf: func(p graphql.IsTypeOfParams) bool {
ctx, ok := p.Context.Value("graph_context").(*Context)
if ok == false {
return false
}
return gql_type_simple_thread
}, nil)
var GQLTypeSimpleLockable = NewSingleton(func() *graphql.Object {
gql_type_simple_lockable := graphql.NewObject(graphql.ObjectConfig{
Name: "SimpleLockable",
Interfaces: []*graphql.Interface{
GQLInterfaceNode.Type,
GQLInterfaceLockable.Type,
},
IsTypeOf: func(p graphql.IsTypeOfParams) bool {
ctx, ok := p.Context.Value("graph_context").(*Context)
if ok == false {
return false
}
lockable_type := ctx.GQL.LockableType
value_type := reflect.TypeOf(p.Value)
lockable_type := ctx.GQL.LockableType
value_type := reflect.TypeOf(p.Value)
if value_type.Implements(lockable_type) {
return true
}
if value_type.Implements(lockable_type) {
return true
}
return false
},
Fields: graphql.Fields{},
})
gql_type_simple_lockable.AddFieldConfig("ID", &graphql.Field{
Type: graphql.String,
Resolve: GQLNodeID,
})
gql_type_simple_lockable.AddFieldConfig("Name", &graphql.Field{
Type: graphql.String,
Resolve: GQLLockableName,
})
gql_type_simple_lockable.AddFieldConfig("Requirements", &graphql.Field{
Type: GQLListLockable(),
Resolve: GQLLockableRequirements,
})
gql_type_simple_lockable.AddFieldConfig("Owner", &graphql.Field{
Type: GQLInterfaceLockable(),
Resolve: GQLLockableOwner,
})
gql_type_simple_lockable.AddFieldConfig("Dependencies", &graphql.Field{
Type: GQLListLockable(),
Resolve: GQLLockableDependencies,
})
}
return gql_type_simple_lockable
}
return false
},
Fields: graphql.Fields{},
})
var gql_type_simple_node *graphql.Object = nil
func GQLTypeGraphNode() * graphql.Object {
if gql_type_simple_node == nil {
gql_type_simple_node = graphql.NewObject(graphql.ObjectConfig{
Name: "GraphNode",
Interfaces: []*graphql.Interface{
GQLInterfaceNode(),
},
IsTypeOf: func(p graphql.IsTypeOfParams) bool {
ctx, ok := p.Context.Value("graph_context").(*Context)
if ok == false {
return false
}
gql_type_simple_lockable.AddFieldConfig("ID", &graphql.Field{
Type: graphql.String,
Resolve: GQLNodeID,
})
node_type := ctx.GQL.NodeType
value_type := reflect.TypeOf(p.Value)
gql_type_simple_lockable.AddFieldConfig("Name", &graphql.Field{
Type: graphql.String,
Resolve: GQLLockableName,
})
if value_type.Implements(node_type) {
return true
}
gql_type_simple_lockable.AddFieldConfig("Requirements", &graphql.Field{
Type: GQLInterfaceLockable.List,
Resolve: GQLLockableRequirements,
})
return false
},
Fields: graphql.Fields{},
})
gql_type_simple_node.AddFieldConfig("ID", &graphql.Field{
Type: graphql.String,
Resolve: GQLNodeID,
})
gql_type_simple_node.AddFieldConfig("Name", &graphql.Field{
Type: graphql.String,
Resolve: GQLLockableName,
})
}
gql_type_simple_lockable.AddFieldConfig("Owner", &graphql.Field{
Type: GQLInterfaceLockable.Type,
Resolve: GQLLockableOwner,
})
return gql_type_simple_node
}
gql_type_simple_lockable.AddFieldConfig("Dependencies", &graphql.Field{
Type: GQLInterfaceLockable.List,
Resolve: GQLLockableDependencies,
})
var gql_type_signal *graphql.Object = nil
func GQLTypeSignal() *graphql.Object {
if gql_type_signal == nil {
gql_type_signal = graphql.NewObject(graphql.ObjectConfig{
Name: "SignalOut",
IsTypeOf: func(p graphql.IsTypeOfParams) bool {
_, ok := p.Value.(GraphSignal)
return ok
},
Fields: graphql.Fields{},
})
gql_type_signal.AddFieldConfig("Type", &graphql.Field{
Type: graphql.String,
Resolve: GQLSignalType,
})
gql_type_signal.AddFieldConfig("Source", &graphql.Field{
Type: graphql.String,
Resolve: GQLSignalSource,
})
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_simple_lockable
}, nil)
var GQLTypeGraphNode = NewSingleton(func() *graphql.Object {
object := graphql.NewObject(graphql.ObjectConfig{
Name: "GraphNode",
Interfaces: []*graphql.Interface{
GQLInterfaceNode.Type,
},
IsTypeOf: func(p graphql.IsTypeOfParams) bool {
ctx, ok := p.Context.Value("graph_context").(*Context)
if ok == false {
return false
}
node_type := ctx.GQL.NodeType
value_type := reflect.TypeOf(p.Value)
if value_type.Implements(node_type) {
return true
}
return false
},
Fields: graphql.Fields{},
})
object.AddFieldConfig("ID", &graphql.Field{
Type: graphql.String,
Resolve: GQLNodeID,
})
object.AddFieldConfig("Name", &graphql.Field{
Type: graphql.String,
Resolve: GQLLockableName,
})
return object
}, nil)
var GQLTypeSignal = NewSingleton(func() *graphql.Object {
gql_type_signal := graphql.NewObject(graphql.ObjectConfig{
Name: "SignalOut",
IsTypeOf: func(p graphql.IsTypeOfParams) bool {
_, ok := p.Value.(GraphSignal)
return ok
},
Fields: graphql.Fields{},
})
gql_type_signal.AddFieldConfig("Type", &graphql.Field{
Type: graphql.String,
Resolve: GQLSignalType,
})
gql_type_signal.AddFieldConfig("Source", &graphql.Field{
Type: graphql.String,
Resolve: GQLSignalSource,
})
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)
var GQLTypeSignalInput = NewSingleton(func()*graphql.InputObject {
gql_type_signal_input := graphql.NewInputObject(graphql.InputObjectConfig{
Name: "SignalIn",
Fields: graphql.InputObjectConfigFieldMap{},
})
gql_type_signal_input.AddFieldConfig("Type", &graphql.InputObjectFieldConfig{
Type: graphql.String,
DefaultValue: "cancel",
})
gql_type_signal_input.AddFieldConfig("Direction", &graphql.InputObjectFieldConfig{
Type: graphql.String,
DefaultValue: "down",
})
var gql_type_signal_input *graphql.InputObject = nil
func GQLTypeSignalInput() *graphql.InputObject {
if gql_type_signal_input == nil {
gql_type_signal_input = graphql.NewInputObject(graphql.InputObjectConfig{
Name: "SignalIn",
Fields: graphql.InputObjectConfigFieldMap{},
})
gql_type_signal_input.AddFieldConfig("Type", &graphql.InputObjectFieldConfig{
Type: graphql.String,
DefaultValue: "cancel",
})
gql_type_signal_input.AddFieldConfig("Direction", &graphql.InputObjectFieldConfig{
Type: graphql.String,
DefaultValue: "down",
})
}
return gql_type_signal_input
}
}, nil)

@ -101,6 +101,12 @@ func (node * GraphNode) Serialize() ([]byte, error) {
}
func (node *GraphNode) Allowed(action string, resource string, principal Node) error {
if principal == nil {
return fmt.Errorf("nil is not allowed to perform any actions")
}
if node.ID() == principal.ID() {
return nil
}
for _, policy := range(node.policies) {
if policy.Allows(action, resource, principal) == true {
return nil