//go:generate go run github.com/99designs/gqlgen generate package graph import ( "context" "log/slog" "net/http" "github.com/99designs/gqlgen/graphql" "github.com/99designs/gqlgen/graphql/handler" "github.com/99designs/gqlgen/graphql/handler/extension" "github.com/99designs/gqlgen/graphql/playground" "github.com/vektah/gqlparser/v2/gqlerror" "gitserver.in/patialtech/rano/graph/generated" "gitserver.in/patialtech/rano/util/logger" ) // This file will not be regenerated automatically. // // It serves as dependency injection for your app, add any dependencies you require here. type Resolver struct{} var srv *handler.Server func init() { srv = handler.NewDefaultServer(schema()) // limit query complexity srv.Use(extension.FixedComplexityLimit(90)) // recover srv.SetRecoverFunc(func(ctx context.Context, err interface{}) error { oc := graphql.GetOperationContext(ctx) // TODO: sanitize oc.RawQuery logger.Error(err.(error), slog.String("gqlQuery", oc.RawQuery)) return gqlerror.Errorf("Internal server error!") }) } // schema creates a graphql executable schema. func schema() graphql.ExecutableSchema { c := generated.Config{ Resolvers: &Resolver{}, } // c.Directives.Authorize = func(ctx context.Context, obj interface{}, next graphql.Resolver, groups []*permission.Group) (res interface{}, err error) { // // get session user // user := account.CtxUser(ctx) // if user == nil { // // session user isn't found // return nil, errors.New("401 Unauthorized") // } // // has roles count more than 0 // if len(groups) == 0 { // we just want to authorize, no need to check has a role // return next(ctx) // } // // user is in desired role // for _, g := range groups { // if g == nil { // continue // } // // Role Check // switch *g { // case permission.GroupRFXAdmin, // permission.GroupDealerAdmin, // permission.GroupInstallerAdmin, // permission.GroupIntegratorAdmin: // if enum.RoleAdmin != user.Role { // continue // } // case permission.GroupRFXUser, // permission.GroupDealerUser, // permission.GroupInstallerUser, // permission.GroupIntegratorUser: // if enum.RoleSiteUser != user.Role { // continue // } // default: // continue // } // // ORG must be present // if user.Partner == nil { // continue // } // // ORG Type Check // switch *g { // case permission.GroupRFXAdmin, permission.GroupRFXUser: // if enum.PartnerRFX == user.Partner.Type { // return next(ctx) // } // case permission.GroupDealerAdmin, permission.GroupDealerUser: // if enum.PartnerDealer == user.Partner.Type { // return next(ctx) // } // case permission.GroupInstallerAdmin, permission.GroupInstallerUser: // if enum.PartnerInstaller == user.Partner.Type { // return next(ctx) // } // case permission.GroupIntegratorAdmin, permission.GroupIntegratorUser: // if enum.PartnerIntegrator == user.Partner.Type { // return next(ctx) // } // } // } // // failed, user is not authorized to go next // return nil, msg.NewError(msg.NotAuthorized) // } // c.Directives.FieldFor = func( // ctx context.Context, obj interface{}, next graphql.Resolver, roles []*enum.Role, defaultVal interface{}, // ) (res interface{}, err error) { // // get session user // user := account.CtxUser(ctx) // if user == nil { // return empty if user info not found // return "", nil // } // // check user has a role allowed for current operation // for _, role := range roles { // if role != nil && user.Role == *role { // // on match just call next // return next(ctx) // } // } // return defaultVal, nil // } return generated.NewExecutableSchema(c) } // GraphiQL route handler func GraphiQL(queryEndpoint string) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { h := playground.Handler("GraphQL", queryEndpoint) h.ServeHTTP(w, r) } } // Query graph func Query(w http.ResponseWriter, r *http.Request) { // srv.ServeHTTP(w, r.WithContext(userCtx(r))) srv.ServeHTTP(w, r) }