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

@ -4,17 +4,15 @@ import (
"github.com/graphql-go/graphql" "github.com/graphql-go/graphql"
) )
var gql_mutation_send_update *graphql.Field = nil var GQLMutationSendUpdate = NewField(func()*graphql.Field {
func GQLMutationSendUpdate() *graphql.Field { gql_mutation_send_update := &graphql.Field{
if gql_mutation_send_update == nil { Type: GQLTypeSignal.Type,
gql_mutation_send_update = &graphql.Field{
Type: GQLTypeSignal(),
Args: graphql.FieldConfigArgument{ Args: graphql.FieldConfigArgument{
"id": &graphql.ArgumentConfig{ "id": &graphql.ArgumentConfig{
Type: graphql.String, Type: graphql.String,
}, },
"signal": &graphql.ArgumentConfig{ "signal": &graphql.ArgumentConfig{
Type: GQLTypeSignalInput(), Type: GQLTypeSignalInput.Type,
}, },
}, },
Resolve: func(p graphql.ResolveParams) (interface{}, error) { Resolve: func(p graphql.ResolveParams) (interface{}, error) {
@ -65,16 +63,13 @@ func GQLMutationSendUpdate() *graphql.Field {
return signal, nil return signal, nil
}, },
} }
}
return gql_mutation_send_update return gql_mutation_send_update
} })
var gql_mutation_start_child *graphql.Field = nil var GQLMutationStartChild = NewField(func()*graphql.Field{
func GQLMutationStartChild() *graphql.Field { gql_mutation_start_child := &graphql.Field{
if gql_mutation_start_child == nil { Type: GQLTypeSignal.Type,
gql_mutation_start_child = &graphql.Field{
Type: GQLTypeSignal(),
Args: graphql.FieldConfigArgument{ Args: graphql.FieldConfigArgument{
"parent_id": &graphql.ArgumentConfig{ "parent_id": &graphql.ArgumentConfig{
Type: graphql.String, Type: graphql.String,
@ -132,7 +127,7 @@ func GQLMutationStartChild() *graphql.Field {
return signal, nil return signal, nil
}, },
} }
}
return gql_mutation_start_child return gql_mutation_start_child
} })

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

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

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

@ -5,10 +5,31 @@ import (
"reflect" "reflect"
) )
var gql_interface_graph_node *graphql.Interface = nil type Field *graphql.Field
func GQLInterfaceNode() *graphql.Interface {
if gql_interface_graph_node == nil { func NewField(init func()*graphql.Field) Field {
gql_interface_graph_node = graphql.NewInterface(graphql.InterfaceConfig{ return Field(init())
}
type Singleton[K graphql.Type] struct {
Type K
List *graphql.List
}
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 &Singleton[K]{
Type: val,
List: list,
}
}
var GQLInterfaceNode = NewSingleton(func() *graphql.Interface {
i := graphql.NewInterface(graphql.InterfaceConfig{
Name: "Node", Name: "Node",
ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object { ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {
ctx, ok := p.Context.Value("graph_context").(*Context) ctx, ok := p.Context.Value("graph_context").(*Context)
@ -27,34 +48,21 @@ func GQLInterfaceNode() *graphql.Interface {
} }
if p_type.Implements(node_type) { if p_type.Implements(node_type) {
return GQLTypeGraphNode() return ctx.GQL.BaseNodeType
} }
return nil return nil
}, },
Fields: graphql.Fields{}, Fields: graphql.Fields{},
}) })
i.AddFieldConfig("ID", &graphql.Field{
gql_interface_graph_node.AddFieldConfig("ID", &graphql.Field{
Type: graphql.String, Type: graphql.String,
}) })
} return i
}, nil)
return gql_interface_graph_node var GQLInterfaceThread = NewSingleton(func() *graphql.Interface {
} gql_interface_thread := graphql.NewInterface(graphql.InterfaceConfig{
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
}
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", Name: "Thread",
ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object { ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {
ctx, ok := p.Context.Value("graph_context").(*Context) ctx, ok := p.Context.Value("graph_context").(*Context)
@ -73,7 +81,7 @@ func GQLInterfaceThread() *graphql.Interface {
} }
if p_type.Implements(thread_type) { if p_type.Implements(thread_type) {
return GQLTypeSimpleThread() return ctx.GQL.BaseThreadType
} }
ctx.Log.Logf("gql", "Found no type that matches %+v: %+v", p_type, p_type.Implements(thread_type)) ctx.Log.Logf("gql", "Found no type that matches %+v: %+v", p_type, p_type.Implements(thread_type))
@ -94,42 +102,32 @@ func GQLInterfaceThread() *graphql.Interface {
Type: graphql.String, 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{ gql_interface_thread.AddFieldConfig("Requirements", &graphql.Field{
Type: GQLListLockable(), Type: GQLInterfaceLockable.List,
}) })
gql_interface_thread.AddFieldConfig("Dependencies", &graphql.Field{ gql_interface_thread.AddFieldConfig("Dependencies", &graphql.Field{
Type: GQLListLockable(), Type: GQLInterfaceLockable.List,
}) })
gql_interface_thread.AddFieldConfig("Owner", &graphql.Field{ gql_interface_thread.AddFieldConfig("Owner", &graphql.Field{
Type: GQLInterfaceLockable(), Type: GQLInterfaceLockable.Type,
}) })
}
return gql_interface_thread return gql_interface_thread
} }, func(thread *graphql.Interface, thread_list *graphql.List) {
thread.AddFieldConfig("Children", &graphql.Field{
Type: thread_list,
})
var gql_list_lockable *graphql.List = nil thread.AddFieldConfig("Parent", &graphql.Field{
func GQLListLockable() *graphql.List { Type: thread,
if gql_list_lockable == nil { })
gql_list_lockable = graphql.NewList(GQLInterfaceLockable())
}
return gql_list_lockable
}
var gql_interface_lockable *graphql.Interface = nil })
func GQLInterfaceLockable() *graphql.Interface {
if gql_interface_lockable == nil { var GQLInterfaceLockable = NewSingleton(func() *graphql.Interface {
gql_interface_lockable = graphql.NewInterface(graphql.InterfaceConfig{ gql_interface_lockable := graphql.NewInterface(graphql.InterfaceConfig{
Name: "Lockable", Name: "Lockable",
ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object { ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object {
ctx, ok := p.Context.Value("graph_context").(*Context) ctx, ok := p.Context.Value("graph_context").(*Context)
@ -148,7 +146,7 @@ func GQLInterfaceLockable() *graphql.Interface {
} }
if p_type.Implements(lockable_type) { if p_type.Implements(lockable_type) {
return GQLTypeSimpleLockable() return ctx.GQL.BaseThreadType
} }
return nil return nil
}, },
@ -162,44 +160,27 @@ func GQLInterfaceLockable() *graphql.Interface {
gql_interface_lockable.AddFieldConfig("Name", &graphql.Field{ gql_interface_lockable.AddFieldConfig("Name", &graphql.Field{
Type: graphql.String, Type: graphql.String,
}) })
return gql_interface_lockable
if gql_list_lockable == nil { }, func(lockable *graphql.Interface, lockable_list *graphql.List) {
gql_list_lockable = graphql.NewList(gql_interface_lockable) lockable.AddFieldConfig("Requirements", &graphql.Field{
} Type: lockable_list,
gql_interface_lockable.AddFieldConfig("Requirements", &graphql.Field{
Type: gql_list_lockable,
}) })
gql_interface_lockable.AddFieldConfig("Dependencies", &graphql.Field{ lockable.AddFieldConfig("Dependencies", &graphql.Field{
Type: gql_list_lockable, Type: lockable_list,
}) })
gql_interface_lockable.AddFieldConfig("Owner", &graphql.Field{ lockable.AddFieldConfig("Owner", &graphql.Field{
Type: gql_interface_lockable, Type: lockable,
})
}) })
} var GQLTypeUser = NewSingleton(func() *graphql.Object {
gql_type_user := graphql.NewObject(graphql.ObjectConfig{
return gql_interface_lockable
}
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
}
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", Name: "User",
Interfaces: []*graphql.Interface{ Interfaces: []*graphql.Interface{
GQLInterfaceNode(), GQLInterfaceNode.Type,
GQLInterfaceLockable(), GQLInterfaceLockable.Type,
}, },
IsTypeOf: func(p graphql.IsTypeOfParams) bool { IsTypeOf: func(p graphql.IsTypeOfParams) bool {
ctx, ok := p.Context.Value("graph_context").(*Context) ctx, ok := p.Context.Value("graph_context").(*Context)
@ -230,32 +211,29 @@ func GQLTypeUser() * graphql.Object {
}) })
gql_type_user.AddFieldConfig("Requirements", &graphql.Field{ gql_type_user.AddFieldConfig("Requirements", &graphql.Field{
Type: GQLListLockable(), Type: GQLInterfaceLockable.List,
Resolve: GQLLockableRequirements, Resolve: GQLLockableRequirements,
}) })
gql_type_user.AddFieldConfig("Owner", &graphql.Field{ gql_type_user.AddFieldConfig("Owner", &graphql.Field{
Type: GQLInterfaceLockable(), Type: GQLInterfaceLockable.Type,
Resolve: GQLLockableOwner, Resolve: GQLLockableOwner,
}) })
gql_type_user.AddFieldConfig("Dependencies", &graphql.Field{ gql_type_user.AddFieldConfig("Dependencies", &graphql.Field{
Type: GQLListLockable(), Type: GQLInterfaceLockable.List,
Resolve: GQLLockableDependencies, Resolve: GQLLockableDependencies,
}) })
}
return gql_type_user return gql_type_user
} }, nil)
var gql_type_gql_thread *graphql.Object = nil var GQLTypeGQLThread = NewSingleton(func() *graphql.Object {
func GQLTypeGQLThread() * graphql.Object { gql_type_gql_thread := graphql.NewObject(graphql.ObjectConfig{
if gql_type_gql_thread == nil {
gql_type_gql_thread = graphql.NewObject(graphql.ObjectConfig{
Name: "GQLThread", Name: "GQLThread",
Interfaces: []*graphql.Interface{ Interfaces: []*graphql.Interface{
GQLInterfaceNode(), GQLInterfaceNode.Type,
GQLInterfaceThread(), GQLInterfaceThread.Type,
GQLInterfaceLockable(), GQLInterfaceLockable.Type,
}, },
IsTypeOf: func(p graphql.IsTypeOfParams) bool { IsTypeOf: func(p graphql.IsTypeOfParams) bool {
_, ok := p.Value.(*GQLThread) _, ok := p.Value.(*GQLThread)
@ -280,12 +258,12 @@ func GQLTypeGQLThread() * graphql.Object {
}) })
gql_type_gql_thread.AddFieldConfig("Children", &graphql.Field{ gql_type_gql_thread.AddFieldConfig("Children", &graphql.Field{
Type: GQLListThread(), Type: GQLInterfaceThread.List,
Resolve: GQLThreadChildren, Resolve: GQLThreadChildren,
}) })
gql_type_gql_thread.AddFieldConfig("Parent", &graphql.Field{ gql_type_gql_thread.AddFieldConfig("Parent", &graphql.Field{
Type: GQLInterfaceThread(), Type: GQLInterfaceThread.Type,
Resolve: GQLThreadParent, Resolve: GQLThreadParent,
}) })
@ -295,37 +273,34 @@ func GQLTypeGQLThread() * graphql.Object {
}) })
gql_type_gql_thread.AddFieldConfig("Requirements", &graphql.Field{ gql_type_gql_thread.AddFieldConfig("Requirements", &graphql.Field{
Type: GQLListLockable(), Type: GQLInterfaceLockable.List,
Resolve: GQLLockableRequirements, Resolve: GQLLockableRequirements,
}) })
gql_type_gql_thread.AddFieldConfig("Owner", &graphql.Field{ gql_type_gql_thread.AddFieldConfig("Owner", &graphql.Field{
Type: GQLInterfaceLockable(), Type: GQLInterfaceLockable.Type,
Resolve: GQLLockableOwner, Resolve: GQLLockableOwner,
}) })
gql_type_gql_thread.AddFieldConfig("Dependencies", &graphql.Field{ gql_type_gql_thread.AddFieldConfig("Dependencies", &graphql.Field{
Type: GQLListLockable(), Type: GQLInterfaceLockable.List,
Resolve: GQLLockableDependencies, Resolve: GQLLockableDependencies,
}) })
gql_type_gql_thread.AddFieldConfig("Users", &graphql.Field{ gql_type_gql_thread.AddFieldConfig("Users", &graphql.Field{
Type: GQLListUser(), Type: GQLTypeUser.List,
Resolve: GQLThreadUsers, Resolve: GQLThreadUsers,
}) })
}
return gql_type_gql_thread return gql_type_gql_thread
} }, nil)
var gql_type_simple_thread *graphql.Object = nil var GQLTypeSimpleThread = NewSingleton(func() *graphql.Object {
func GQLTypeSimpleThread() * graphql.Object { gql_type_simple_thread := graphql.NewObject(graphql.ObjectConfig{
if gql_type_simple_thread == nil {
gql_type_simple_thread = graphql.NewObject(graphql.ObjectConfig{
Name: "SimpleThread", Name: "SimpleThread",
Interfaces: []*graphql.Interface{ Interfaces: []*graphql.Interface{
GQLInterfaceNode(), GQLInterfaceNode.Type,
GQLInterfaceThread(), GQLInterfaceThread.Type,
GQLInterfaceLockable(), GQLInterfaceLockable.Type,
}, },
IsTypeOf: func(p graphql.IsTypeOfParams) bool { IsTypeOf: func(p graphql.IsTypeOfParams) bool {
ctx, ok := p.Context.Value("graph_context").(*Context) ctx, ok := p.Context.Value("graph_context").(*Context)
@ -361,41 +336,39 @@ func GQLTypeSimpleThread() * graphql.Object {
}) })
gql_type_simple_thread.AddFieldConfig("Children", &graphql.Field{ gql_type_simple_thread.AddFieldConfig("Children", &graphql.Field{
Type: GQLListThread(), Type: GQLInterfaceThread.List,
Resolve: GQLThreadChildren, Resolve: GQLThreadChildren,
}) })
gql_type_simple_thread.AddFieldConfig("Parent", &graphql.Field{ gql_type_simple_thread.AddFieldConfig("Parent", &graphql.Field{
Type: GQLInterfaceThread(), Type: GQLInterfaceThread.Type,
Resolve: GQLThreadParent, Resolve: GQLThreadParent,
}) })
gql_type_simple_thread.AddFieldConfig("Requirements", &graphql.Field{ gql_type_simple_thread.AddFieldConfig("Requirements", &graphql.Field{
Type: GQLListLockable(), Type: GQLInterfaceLockable.List,
Resolve: GQLLockableRequirements, Resolve: GQLLockableRequirements,
}) })
gql_type_simple_thread.AddFieldConfig("Owner", &graphql.Field{ gql_type_simple_thread.AddFieldConfig("Owner", &graphql.Field{
Type: GQLInterfaceLockable(), Type: GQLInterfaceLockable.Type,
Resolve: GQLLockableOwner, Resolve: GQLLockableOwner,
}) })
gql_type_simple_thread.AddFieldConfig("Dependencies", &graphql.Field{ gql_type_simple_thread.AddFieldConfig("Dependencies", &graphql.Field{
Type: GQLListLockable(), Type: GQLInterfaceLockable.List,
Resolve: GQLLockableDependencies, Resolve: GQLLockableDependencies,
}) })
}
return gql_type_simple_thread return gql_type_simple_thread
} }, nil)
var gql_type_simple_lockable *graphql.Object = nil var GQLTypeSimpleLockable = NewSingleton(func() *graphql.Object {
func GQLTypeSimpleLockable() * graphql.Object { gql_type_simple_lockable := graphql.NewObject(graphql.ObjectConfig{
if gql_type_simple_lockable == nil {
gql_type_simple_lockable = graphql.NewObject(graphql.ObjectConfig{
Name: "SimpleLockable", Name: "SimpleLockable",
Interfaces: []*graphql.Interface{ Interfaces: []*graphql.Interface{
GQLInterfaceNode(), GQLInterfaceNode.Type,
GQLInterfaceLockable(), GQLInterfaceLockable.Type,
}, },
IsTypeOf: func(p graphql.IsTypeOfParams) bool { IsTypeOf: func(p graphql.IsTypeOfParams) bool {
ctx, ok := p.Context.Value("graph_context").(*Context) ctx, ok := p.Context.Value("graph_context").(*Context)
@ -426,30 +399,28 @@ func GQLTypeSimpleLockable() * graphql.Object {
}) })
gql_type_simple_lockable.AddFieldConfig("Requirements", &graphql.Field{ gql_type_simple_lockable.AddFieldConfig("Requirements", &graphql.Field{
Type: GQLListLockable(), Type: GQLInterfaceLockable.List,
Resolve: GQLLockableRequirements, Resolve: GQLLockableRequirements,
}) })
gql_type_simple_lockable.AddFieldConfig("Owner", &graphql.Field{ gql_type_simple_lockable.AddFieldConfig("Owner", &graphql.Field{
Type: GQLInterfaceLockable(), Type: GQLInterfaceLockable.Type,
Resolve: GQLLockableOwner, Resolve: GQLLockableOwner,
}) })
gql_type_simple_lockable.AddFieldConfig("Dependencies", &graphql.Field{ gql_type_simple_lockable.AddFieldConfig("Dependencies", &graphql.Field{
Type: GQLListLockable(), Type: GQLInterfaceLockable.List,
Resolve: GQLLockableDependencies, Resolve: GQLLockableDependencies,
}) })
}
return gql_type_simple_lockable return gql_type_simple_lockable
} }, nil)
var gql_type_simple_node *graphql.Object = nil var GQLTypeGraphNode = NewSingleton(func() *graphql.Object {
func GQLTypeGraphNode() * graphql.Object { object := graphql.NewObject(graphql.ObjectConfig{
if gql_type_simple_node == nil {
gql_type_simple_node = graphql.NewObject(graphql.ObjectConfig{
Name: "GraphNode", Name: "GraphNode",
Interfaces: []*graphql.Interface{ Interfaces: []*graphql.Interface{
GQLInterfaceNode(), GQLInterfaceNode.Type,
}, },
IsTypeOf: func(p graphql.IsTypeOfParams) bool { IsTypeOf: func(p graphql.IsTypeOfParams) bool {
ctx, ok := p.Context.Value("graph_context").(*Context) ctx, ok := p.Context.Value("graph_context").(*Context)
@ -469,24 +440,21 @@ func GQLTypeGraphNode() * graphql.Object {
Fields: graphql.Fields{}, Fields: graphql.Fields{},
}) })
gql_type_simple_node.AddFieldConfig("ID", &graphql.Field{ object.AddFieldConfig("ID", &graphql.Field{
Type: graphql.String, Type: graphql.String,
Resolve: GQLNodeID, Resolve: GQLNodeID,
}) })
gql_type_simple_node.AddFieldConfig("Name", &graphql.Field{ object.AddFieldConfig("Name", &graphql.Field{
Type: graphql.String, Type: graphql.String,
Resolve: GQLLockableName, Resolve: GQLLockableName,
}) })
}
return gql_type_simple_node return object
} }, nil)
var gql_type_signal *graphql.Object = nil var GQLTypeSignal = NewSingleton(func() *graphql.Object {
func GQLTypeSignal() *graphql.Object { gql_type_signal := graphql.NewObject(graphql.ObjectConfig{
if gql_type_signal == nil {
gql_type_signal = graphql.NewObject(graphql.ObjectConfig{
Name: "SignalOut", Name: "SignalOut",
IsTypeOf: func(p graphql.IsTypeOfParams) bool { IsTypeOf: func(p graphql.IsTypeOfParams) bool {
_, ok := p.Value.(GraphSignal) _, ok := p.Value.(GraphSignal)
@ -511,14 +479,11 @@ func GQLTypeSignal() *graphql.Object {
Type: graphql.String, Type: graphql.String,
Resolve: GQLSignalString, Resolve: GQLSignalString,
}) })
}
return gql_type_signal return gql_type_signal
} }, nil)
var gql_type_signal_input *graphql.InputObject = nil var GQLTypeSignalInput = NewSingleton(func()*graphql.InputObject {
func GQLTypeSignalInput() *graphql.InputObject { gql_type_signal_input := graphql.NewInputObject(graphql.InputObjectConfig{
if gql_type_signal_input == nil {
gql_type_signal_input = graphql.NewInputObject(graphql.InputObjectConfig{
Name: "SignalIn", Name: "SignalIn",
Fields: graphql.InputObjectConfigFieldMap{}, Fields: graphql.InputObjectConfigFieldMap{},
}) })
@ -530,7 +495,7 @@ func GQLTypeSignalInput() *graphql.InputObject {
Type: graphql.String, Type: graphql.String,
DefaultValue: "down", DefaultValue: "down",
}) })
}
return gql_type_signal_input 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 { 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) { for _, policy := range(node.policies) {
if policy.Allows(action, resource, principal) == true { if policy.Allows(action, resource, principal) == true {
return nil return nil