2019-08-27 07:39:12 +09:00

94 lines
2.0 KiB
Go

package graphql
import (
"errors"
"fmt"
"reflect"
"strings"
"github.com/aerogo/aero"
"github.com/aerogo/graphql"
"github.com/animenotifier/notify.moe/arn"
)
var (
empty = struct{}{}
privateCollections = map[string]struct{}{
"PayPalPayment": empty,
"Purchase": empty,
"EmailToUser": empty,
"Session": empty,
"EditLogEntry": empty,
}
)
func Install(app *aero.Application) {
api := graphql.New(arn.DB)
// Block private collections
api.AddRootResolver(func(name string, arguments graphql.Map) (interface{}, error, bool) {
typeName := strings.TrimPrefix(name, "all")
typeName = strings.TrimPrefix(typeName, "like")
_, private := privateCollections[typeName]
if private {
return nil, fmt.Errorf("Type '%s' is private", typeName), true
}
return nil, nil, false
})
// Like objects
api.AddRootResolver(func(name string, arguments graphql.Map) (interface{}, error, bool) {
if !strings.HasPrefix(name, "like") {
return nil, nil, false
}
id, ok := arguments["ID"].(string)
if !ok {
return nil, fmt.Errorf("'%s' needs to specify an ID", name), true
}
typeName := strings.TrimPrefix(name, "like")
obj, err := arn.DB.Get(typeName, id)
if err != nil {
return nil, err, true
}
field := reflect.ValueOf(obj).Elem().FieldByName("IsDraft")
if field.IsValid() && field.Bool() {
return nil, errors.New("Drafts need to be published before they can be liked"), true
}
likeable, ok := obj.(arn.Likeable)
if !ok {
return nil, fmt.Errorf("'%s' does not implement the Likeable interface", name), true
}
// TODO: Authentication
// user := GetUserFromContext(ctx)
// if user == nil {
// return errors.New("Not logged in")
// }
// likeable.Like(user.ID)
// Call OnLike if the object implements it
// receiver, ok := likeable.(LikeEventReceiver)
// if ok {
// receiver.OnLike(user)
// }
likeable.Save()
return obj, nil, true
})
app.Post("/graphql", api.Handler())
}