// 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 = ¬FoundHandler{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)) } }