stufflog graphql server
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

172 lines
4.2 KiB

package main
import (
"context"
"git.aiterp.net/stufflog/server/database"
"git.aiterp.net/stufflog/server/graph"
"git.aiterp.net/stufflog/server/internal/generate"
"git.aiterp.net/stufflog/server/internal/xlerrors"
"git.aiterp.net/stufflog/server/models"
"git.aiterp.net/stufflog/server/services"
"github.com/99designs/gqlgen/graphql/playground"
"github.com/gin-gonic/gin"
"github.com/pkg/errors"
"github.com/pressly/goose"
"github.com/urfave/cli/v2"
"log"
"os"
"os/signal"
"sort"
"syscall"
"time"
)
func main() {
app := &cli.App{
Name: "stufflog",
Usage: "Issue tracker for your home and hobbies",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "db-driver",
Value: "mysql",
Usage: "Database driver",
EnvVars: []string{"DATABASE_DRIVER"},
},
&cli.StringFlag{
Name: "db-connect",
Value: "stufflog_user:stuff1234@(localhost:3306)/stufflog",
Usage: "Database connection string or path",
EnvVars: []string{"DATABASE_CONNECT"},
},
&cli.StringFlag{
Name: "listen",
Value: ":8000",
Usage: "Address to bind the server to.",
EnvVars: []string{"SERVER_LISTEN"},
},
},
Commands: []*cli.Command{
{
Name: "reset-admin",
Usage: "Reset the admin user (or create it)",
Action: func(c *cli.Context) error {
db, err := database.Open(c.String("db-driver"), c.String("db-connect"))
if err != nil {
return errors.Wrap(err, "Failed to connect to database")
}
timeout, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
newPass := generate.Generate(20, "")
admin, err := db.Users().Find(timeout, "Admin")
if xlerrors.IsNotFound(err) {
admin = &models.User{
ID: "Admin",
Name: "Administrator",
Active: true,
Admin: true,
}
err = admin.SetPassword(newPass)
if err != nil {
return errors.Wrap(err, "Failed to set password")
}
_, err = db.Users().Insert(timeout, *admin)
if err != nil {
return errors.Wrap(err, "Failed to inset user")
}
} else if err != nil {
return err
} else {
err = admin.SetPassword(newPass)
if err != nil {
return errors.Wrap(err, "Failed to set password")
}
err = db.Users().Save(timeout, *admin)
if err != nil {
return errors.Wrap(err, "Failed to save user")
}
}
log.Println("Username:", admin.ID)
log.Println("Password:", newPass)
return nil
},
},
{
Name: "migrate",
Usage: "Migrate the configured database",
Action: func(c *cli.Context) error {
db, err := database.Open(c.String("db-driver"), c.String("db-connect"))
if err != nil {
return errors.Wrap(err, "Failed to connect to database")
}
err = db.Migrate()
if err == goose.ErrNoNextVersion {
log.Println("No more migrations to run")
} else if err != nil {
return errors.Wrap(err, "Failed to run migration")
}
log.Println("Migration succeeded")
return nil
},
},
{
Name: "server",
Usage: "Run the server",
Action: func(c *cli.Context) error {
db, err := database.Open(c.String("db-driver"), c.String("db-connect"))
if err != nil {
return errors.Wrap(err, "Failed to connect to database")
}
bundle := services.NewBundle(db)
server := gin.New()
server.GET("/graphql", graph.Gin(bundle, db))
server.POST("/graphql", graph.Gin(bundle, db))
server.GET("/playground", gin.WrapH(playground.Handler("StuffLog GraphQL Playground", "/graphql")))
exitSignal := make(chan os.Signal)
signal.Notify(exitSignal, os.Interrupt, os.Kill, syscall.SIGTERM)
errCh := make(chan error)
go func() {
err := server.Run(c.String("listen"))
if err != nil {
errCh <- err
}
}()
select {
case signal := <-exitSignal:
{
log.Println("Received signal", signal)
return nil
}
case err := <-errCh:
{
return err
}
}
},
},
},
}
sort.Sort(cli.FlagsByName(app.Flags))
sort.Sort(cli.CommandsByName(app.Commands))
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
}