goacc/pkg/server/server.go

110 lines
2.2 KiB
Go

// Copyright (C) 2022 Marius Schellenberger
package server
import (
"bytes"
"context"
"embed"
"errors"
"net/http"
"time"
"git.giftfish.de/ston1th/goacc/pkg/core"
"git.giftfish.de/ston1th/goacc/pkg/db"
"git.giftfish.de/ston1th/jwt/v3"
"github.com/go-logr/logr"
"github.com/gorilla/mux"
client "github.com/ory/hydra-client-go"
)
const (
cookieName = "goacc_session"
)
type Server struct {
log logr.Logger
Config *core.Config
srv *http.Server
API *client.APIClient
DB *db.DB
JWT *jwt.JWT
BasicAuth *BasicAuth
ts *TemplateStore
}
func NewServer(log logr.Logger, cfg *core.Config) (srv *Server, err error) {
srv = &Server{
log: log,
Config: cfg,
}
srv.srv = &http.Server{
Addr: cfg.Listen,
Handler: srv.buildRoutes(),
}
conf := client.NewConfiguration()
conf.Servers = []client.ServerConfiguration{
{
URL: cfg.HydraAdminURL,
},
}
srv.API = client.NewAPIClient(conf)
err = srv.loadTemplates()
return
}
func (s *Server) Start(dblog logr.Logger) (err error) {
s.DB, err = db.New(dblog, s.Config)
if err != nil {
return errors.New("db: " + err.Error())
}
//err = godrop.UnveilBlock()
//if err != nil {
// return
//}
if s.Config.Secret != "" {
s.JWT, err = jwt.New(jwt.DefaultExpiry, s.DB, bytes.NewBufferString(s.Config.Secret))
} else {
s.JWT, err = jwt.New(jwt.DefaultExpiry, s.DB, nil)
}
if err != nil {
return errors.New("server: " + err.Error())
}
s.BasicAuth, err = NewBasicAuth(NewDBLoginValidator(s.DB))
if err != nil {
return errors.New("server: " + err.Error())
}
go func() {
time.Sleep(time.Second * 2)
s.srv.ListenAndServe()
}()
return
}
func (s *Server) Shutdown(ctx context.Context) {
s.DB.Close()
s.JWT.Stop()
s.srv.Shutdown(ctx)
}
//go:embed static/*
var static embed.FS
func (s *Server) buildRoutes() http.Handler {
m := mux.NewRouter()
m.NotFoundHandler = &notFoundHandler{s}
m.Handle("/static/{file}", http.StripPrefix("/", http.FileServer(http.FS(static))))
for _, v := range routes {
m.HandleFunc(v.Path, s.contextWrapper(v.Handler)).Methods(v.Methods...)
}
return m
}
func (s *Server) contextWrapper(h ctxHandler) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
h(newContext(w, r, s))
}
}