142 lines
4.8 KiB
Go
142 lines
4.8 KiB
Go
package web
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/gorilla/mux"
|
|
"github.com/rs/zerolog/log"
|
|
"github.com/spf13/viper"
|
|
|
|
"git.coopgo.io/coopgo-apps/parcoursmob/core/application"
|
|
"git.coopgo.io/coopgo-apps/parcoursmob/renderer"
|
|
webapi "git.coopgo.io/coopgo-apps/parcoursmob/servers/web/api"
|
|
webapplication "git.coopgo.io/coopgo-apps/parcoursmob/servers/web/application"
|
|
webauth "git.coopgo.io/coopgo-apps/parcoursmob/servers/web/auth"
|
|
webexports "git.coopgo.io/coopgo-apps/parcoursmob/servers/web/exports"
|
|
webexternal "git.coopgo.io/coopgo-apps/parcoursmob/servers/web/external"
|
|
webprotectedapi "git.coopgo.io/coopgo-apps/parcoursmob/servers/web/protected_api"
|
|
"git.coopgo.io/coopgo-apps/parcoursmob/services"
|
|
"git.coopgo.io/coopgo-apps/parcoursmob/core/utils/identification"
|
|
cacheStorage "git.coopgo.io/coopgo-apps/parcoursmob/core/utils/storage"
|
|
"git.coopgo.io/coopgo-platform/groups-management/storage"
|
|
"github.com/coreos/go-oidc/v3/oidc"
|
|
)
|
|
|
|
type WebServer struct {
|
|
cfg *viper.Viper
|
|
services *services.ServicesHandler
|
|
renderer *renderer.Renderer
|
|
applicationHandler *application.ApplicationHandler
|
|
exportsHandler *webexports.Handler
|
|
authHandler *webauth.Handler
|
|
idp *identification.IdentificationProvider
|
|
|
|
// Web handler subpackages
|
|
appHandler *webapplication.Handler
|
|
extHandler *webexternal.Handler
|
|
protectedAPIHandler *webprotectedapi.Handler
|
|
webAPIHandler *webapi.Handler
|
|
}
|
|
|
|
func Run(cfg *viper.Viper, services *services.ServicesHandler, renderer *renderer.Renderer, applicationHandler *application.ApplicationHandler, idp *identification.IdentificationProvider, cacheHandler cacheStorage.CacheHandler, filestorage cacheStorage.FileStorage) {
|
|
var (
|
|
address = cfg.GetString("server.web.listen")
|
|
service_name = cfg.GetString("service_name")
|
|
templates_public_dir = cfg.GetString("templates.public_dir")
|
|
dev_env = cfg.GetBool("dev_env")
|
|
)
|
|
|
|
webServer := &WebServer{
|
|
cfg: cfg,
|
|
services: services,
|
|
renderer: renderer,
|
|
applicationHandler: applicationHandler,
|
|
idp: idp,
|
|
|
|
// Initialize web handler subpackages
|
|
appHandler: webapplication.NewHandler(cfg, renderer, applicationHandler, idp, services),
|
|
authHandler: webauth.NewHandler(cfg, applicationHandler, idp, renderer),
|
|
exportsHandler: webexports.NewHandler(cfg, applicationHandler, idp, renderer),
|
|
extHandler: webexternal.NewHandler(cfg, applicationHandler, filestorage),
|
|
protectedAPIHandler: webprotectedapi.NewHandler(cfg, applicationHandler),
|
|
webAPIHandler: webapi.NewHandler(cfg, idp, applicationHandler, cacheHandler),
|
|
}
|
|
|
|
r := mux.NewRouter()
|
|
|
|
// Static files
|
|
r.PathPrefix("/public/").Handler(http.StripPrefix("/public/", http.FileServer(http.Dir(templates_public_dir))))
|
|
|
|
// Root redirect
|
|
r.HandleFunc("/", redirectApp)
|
|
|
|
// Development middleware
|
|
if dev_env {
|
|
r.Use(trackPage)
|
|
}
|
|
|
|
// Setup all route groups
|
|
webServer.setupAuthRoutes(r)
|
|
webServer.setupCalendarsRoutes(r)
|
|
webServer.setupExternalRoutes(r)
|
|
webServer.setupAPIRoutes(r)
|
|
webServer.setupProtectedAPIRoutes(r)
|
|
webServer.setupApplicationRoutes(r)
|
|
webServer.setupExportsRoutes(r)
|
|
|
|
srv := &http.Server{
|
|
Handler: r,
|
|
Addr: address,
|
|
WriteTimeout: 30 * time.Second,
|
|
ReadTimeout: 15 * time.Second,
|
|
}
|
|
|
|
log.Info().Str("service_name", service_name).Str("address", address).Msg("Running HTTP server")
|
|
|
|
err := srv.ListenAndServe()
|
|
log.Error().Err(err).Msg("Web server error")
|
|
}
|
|
|
|
func redirectApp(w http.ResponseWriter, r *http.Request) {
|
|
http.Redirect(w, r, "/app/", http.StatusFound)
|
|
}
|
|
|
|
func trackPage(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
log.Trace().Str("requested_uri", r.RequestURI).Msg("New request")
|
|
next.ServeHTTP(w, r.WithContext(r.Context()))
|
|
})
|
|
}
|
|
|
|
// Helper functions for extracting user and group information from request context
|
|
func currentGroup(r *http.Request) (current_group storage.Group, err error) {
|
|
g := r.Context().Value(identification.GroupKey)
|
|
if g == nil {
|
|
return storage.Group{}, errors.New("current group not found")
|
|
}
|
|
current_group = g.(storage.Group)
|
|
|
|
return current_group, nil
|
|
}
|
|
|
|
func currentUser(r *http.Request) (current_user_token *oidc.IDToken, current_user_claims map[string]any, err error) {
|
|
// Get current user ID
|
|
u := r.Context().Value(identification.IdtokenKey)
|
|
if u == nil {
|
|
return nil, nil, errors.New("current user not found")
|
|
}
|
|
current_user_token = u.(*oidc.IDToken)
|
|
|
|
// Get current user claims
|
|
c := r.Context().Value(identification.ClaimsKey)
|
|
if c == nil {
|
|
return current_user_token, nil, errors.New("current user claims not found")
|
|
}
|
|
current_user_claims = c.(map[string]any)
|
|
|
|
return current_user_token, current_user_claims, nil
|
|
}
|
|
|