graphvent/gql_resolvers.go

339 lines
7.9 KiB
Go

2023-07-21 15:16:35 -06:00
package graphvent
import (
"fmt"
"reflect"
"github.com/graphql-go/graphql"
)
2023-07-26 00:18:11 -06:00
func PrepResolve(p graphql.ResolveParams) (*Node, *ResolveContext, error) {
2023-07-21 18:51:42 -06:00
resolve_context, ok := p.Context.Value("resolve").(*ResolveContext)
2023-07-21 15:16:35 -06:00
if ok == false {
2023-07-26 00:18:11 -06:00
return nil, nil, fmt.Errorf("Bad resolve in params context")
2023-07-21 15:16:35 -06:00
}
2023-07-26 00:18:11 -06:00
node, ok := p.Source.(*Node)
if ok == false {
return nil, nil, fmt.Errorf("Source is not a *Node in PrepResolve")
}
return node, resolve_context, nil
2023-07-21 15:16:35 -06:00
}
// TODO: Make composabe by checkinf if K is a slice, then recursing in the same way that ExtractList does
2023-07-21 15:16:35 -06:00
func ExtractParam[K interface{}](p graphql.ResolveParams, name string) (K, error) {
var zero K
arg_if, ok := p.Args[name]
if ok == false {
return zero, fmt.Errorf("No Arg of name %s", name)
}
arg, ok := arg_if.(K)
if ok == false {
return zero, fmt.Errorf("Failed to cast arg %s(%+v) to %+v", name, arg_if, reflect.TypeOf(zero))
}
return arg, nil
}
func ExtractList[K interface{}](p graphql.ResolveParams, name string) ([]K, error) {
var zero K
arg_list, err := ExtractParam[[]interface{}](p, name)
if err != nil {
return nil, err
}
ret := make([]K, len(arg_list))
for i, val := range(arg_list) {
val_conv, ok := arg_list[i].(K)
if ok == false {
return nil, fmt.Errorf("Failed to cast arg %s[%d](%+v) to %+v", name, i, val, reflect.TypeOf(zero))
}
ret[i] = val_conv
}
return ret, nil
}
2023-07-21 15:16:35 -06:00
func ExtractID(p graphql.ResolveParams, name string) (NodeID, error) {
id_str, err := ExtractParam[string](p, name)
if err != nil {
return ZeroID, err
}
id, err := ParseID(id_str)
if err != nil {
return ZeroID, err
}
return id, nil
}
// TODO: think about what permissions should be needed to read ID, and if there's ever a case where they haven't already been granted
2023-07-21 15:16:35 -06:00
func GQLNodeID(p graphql.ResolveParams) (interface{}, error) {
2023-07-26 00:18:11 -06:00
node, _, err := PrepResolve(p)
if err != nil {
return nil, err
2023-07-21 15:16:35 -06:00
}
2023-07-21 19:16:30 -06:00
2023-07-26 00:18:11 -06:00
return node.ID, nil
2023-07-21 15:16:35 -06:00
}
2023-07-26 00:18:11 -06:00
func GQLNodeTypeHash(p graphql.ResolveParams) (interface{}, error) {
node, _, err := PrepResolve(p)
2023-07-21 19:16:30 -06:00
if err != nil {
return nil, err
}
2023-07-26 00:18:11 -06:00
return string(node.Type), nil
}
func GQLThreadListen(p graphql.ResolveParams) (interface{}, error) {
node, ctx, err := PrepResolve(p)
if err != nil {
return nil, err
2023-07-21 15:16:35 -06:00
}
2023-07-26 00:18:11 -06:00
gql_ext, err := GetExt[*GQLExt](node)
if err != nil {
return nil, err
}
2023-07-21 15:16:35 -06:00
listen := ""
context := NewReadContext(ctx.Context)
2023-07-26 00:18:11 -06:00
err = UseStates(context, ctx.User, NewACLInfo(node, []string{"listen"}), func(context *StateContext) error {
listen = gql_ext.Listen
return nil
2023-07-21 15:16:35 -06:00
})
if err != nil {
return nil, err
}
return listen, nil
}
func GQLThreadParent(p graphql.ResolveParams) (interface{}, error) {
2023-07-26 00:18:11 -06:00
node, ctx, err := PrepResolve(p)
2023-07-21 19:16:30 -06:00
if err != nil {
return nil, err
}
2023-07-26 00:18:11 -06:00
thread_ext, err := GetExt[*ThreadExt](node)
if err != nil {
return nil, err
2023-07-21 15:16:35 -06:00
}
2023-07-26 00:18:11 -06:00
var parent *Node = nil
context := NewReadContext(ctx.Context)
2023-07-26 00:18:11 -06:00
err = UseStates(context, ctx.User, NewACLInfo(node, []string{"parent"}), func(context *StateContext) error {
parent = thread_ext.Parent
return nil
2023-07-21 15:16:35 -06:00
})
if err != nil {
return nil, err
}
return parent, nil
}
func GQLThreadState(p graphql.ResolveParams) (interface{}, error) {
2023-07-26 00:18:11 -06:00
node, ctx, err := PrepResolve(p)
2023-07-21 19:16:30 -06:00
if err != nil {
return nil, err
}
2023-07-26 00:18:11 -06:00
thread_ext, err := GetExt[*ThreadExt](node)
if err != nil {
return nil, err
2023-07-21 15:16:35 -06:00
}
var state string
context := NewReadContext(ctx.Context)
2023-07-26 00:18:11 -06:00
err = UseStates(context, ctx.User, NewACLInfo(node, []string{"state"}), func(context *StateContext) error {
state = thread_ext.State
return nil
2023-07-21 15:16:35 -06:00
})
if err != nil {
return nil, err
}
return state, nil
}
func GQLThreadChildren(p graphql.ResolveParams) (interface{}, error) {
2023-07-26 00:18:11 -06:00
node, ctx, err := PrepResolve(p)
2023-07-21 15:16:35 -06:00
if err != nil {
return nil, err
}
2023-07-26 00:18:11 -06:00
thread_ext, err := GetExt[*ThreadExt](node)
2023-07-21 19:16:30 -06:00
if err != nil {
return nil, err
2023-07-21 15:16:35 -06:00
}
2023-07-26 00:18:11 -06:00
var children []*Node = nil
context := NewReadContext(ctx.Context)
2023-07-26 00:18:11 -06:00
err = UseStates(context, ctx.User, NewACLInfo(node, []string{"children"}), func(context *StateContext) error {
children = thread_ext.ChildList()
return nil
2023-07-21 15:16:35 -06:00
})
if err != nil {
return nil, err
}
2023-07-26 00:18:11 -06:00
return children, nil
2023-07-21 15:16:35 -06:00
}
func GQLLockableRequirements(p graphql.ResolveParams) (interface{}, error) {
2023-07-26 00:18:11 -06:00
node, ctx, err := PrepResolve(p)
2023-07-21 19:16:30 -06:00
if err != nil {
return nil, err
}
2023-07-26 00:18:11 -06:00
lockable_ext, err := GetExt[*LockableExt](node)
if err != nil {
return nil, err
2023-07-21 15:16:35 -06:00
}
2023-07-26 00:18:11 -06:00
var requirements []*Node = nil
context := NewReadContext(ctx.Context)
2023-07-26 00:18:11 -06:00
err = UseStates(context, ctx.User, NewACLInfo(node, []string{"requirements"}), func(context *StateContext) error {
requirements = make([]*Node, len(lockable_ext.Requirements))
2023-07-24 16:04:56 -06:00
i := 0
2023-07-26 00:18:11 -06:00
for _, req := range(lockable_ext.Requirements) {
2023-07-24 16:04:56 -06:00
requirements[i] = req
i += 1
}
return nil
2023-07-21 15:16:35 -06:00
})
if err != nil {
return nil, err
}
return requirements, nil
}
func GQLLockableDependencies(p graphql.ResolveParams) (interface{}, error) {
2023-07-26 00:18:11 -06:00
node, ctx, err := PrepResolve(p)
2023-07-21 19:16:30 -06:00
if err != nil {
return nil, err
}
2023-07-26 00:18:11 -06:00
lockable_ext, err := GetExt[*LockableExt](node)
if err != nil {
return nil, err
2023-07-21 15:16:35 -06:00
}
2023-07-26 00:18:11 -06:00
var dependencies []*Node = nil
context := NewReadContext(ctx.Context)
2023-07-26 00:18:11 -06:00
err = UseStates(context, ctx.User, NewACLInfo(node, []string{"dependencies"}), func(context *StateContext) error {
dependencies = make([]*Node, len(lockable_ext.Dependencies))
2023-07-24 16:04:56 -06:00
i := 0
2023-07-26 00:18:11 -06:00
for _, dep := range(lockable_ext.Dependencies) {
2023-07-24 16:04:56 -06:00
dependencies[i] = dep
i += 1
}
return nil
2023-07-21 15:16:35 -06:00
})
if err != nil {
return nil, err
}
return dependencies, nil
}
func GQLLockableOwner(p graphql.ResolveParams) (interface{}, error) {
2023-07-26 00:18:11 -06:00
node, ctx, err := PrepResolve(p)
2023-07-21 19:16:30 -06:00
if err != nil {
return nil, err
}
2023-07-26 00:18:11 -06:00
lockable_ext, err := GetExt[*LockableExt](node)
if err != nil {
return nil, err
2023-07-21 15:16:35 -06:00
}
2023-07-26 00:18:11 -06:00
var owner *Node = nil
context := NewReadContext(ctx.Context)
2023-07-26 00:18:11 -06:00
err = UseStates(context, ctx.User, NewACLInfo(node, []string{"owner"}), func(context *StateContext) error {
owner = lockable_ext.Owner
return nil
2023-07-21 15:16:35 -06:00
})
if err != nil {
return nil, err
}
return owner, nil
}
2023-07-26 00:18:11 -06:00
func GQLGroupMembers(p graphql.ResolveParams) (interface{}, error) {
node, ctx, err := PrepResolve(p)
2023-07-21 19:16:30 -06:00
if err != nil {
return nil, err
}
2023-07-26 00:18:11 -06:00
group_ext, err := GetExt[*GroupExt](node)
if err != nil {
return nil, err
2023-07-21 15:16:35 -06:00
}
2023-07-26 00:18:11 -06:00
var members []*Node
context := NewReadContext(ctx.Context)
2023-07-26 00:18:11 -06:00
err = UseStates(context, ctx.User, NewACLInfo(node, []string{"users"}), func(context *StateContext) error {
members = make([]*Node, len(group_ext.Members))
2023-07-21 15:16:35 -06:00
i := 0
2023-07-26 00:18:11 -06:00
for _, member := range(group_ext.Members) {
members[i] = member
2023-07-21 15:16:35 -06:00
i += 1
}
return nil
2023-07-21 15:16:35 -06:00
})
if err != nil {
return nil, err
}
2023-07-26 00:18:11 -06:00
return members, nil
2023-07-21 15:16:35 -06:00
}
func GQLSignalFn(p graphql.ResolveParams, fn func(Signal, graphql.ResolveParams)(interface{}, error))(interface{}, error) {
if signal, ok := p.Source.(Signal); ok {
2023-07-21 15:16:35 -06:00
return fn(signal, p)
}
return nil, fmt.Errorf("Failed to cast source to event")
}
func GQLSignalType(p graphql.ResolveParams) (interface{}, error) {
return GQLSignalFn(p, func(signal Signal, p graphql.ResolveParams)(interface{}, error){
2023-07-21 15:16:35 -06:00
return signal.Type(), nil
})
}
func GQLSignalDirection(p graphql.ResolveParams) (interface{}, error) {
return GQLSignalFn(p, func(signal Signal, p graphql.ResolveParams)(interface{}, error){
2023-07-21 15:16:35 -06:00
direction := signal.Direction()
if direction == Up {
return "up", nil
} else if direction == Down {
return "down", nil
} else if direction == Direct {
return "direct", nil
}
return nil, fmt.Errorf("Invalid direction: %+v", direction)
})
}
func GQLSignalString(p graphql.ResolveParams) (interface{}, error) {
return GQLSignalFn(p, func(signal Signal, p graphql.ResolveParams)(interface{}, error){
ser, err := signal.Serialize()
return string(ser), err
2023-07-21 15:16:35 -06:00
})
}