Files
infix/src/webui/internal/server/server.go
T
2026-06-14 22:07:33 +02:00

169 lines
5.0 KiB
Go

// SPDX-License-Identifier: MIT
package server
import (
"html/template"
"io/fs"
"net/http"
"github.com/kernelkit/webui/internal/auth"
"github.com/kernelkit/webui/internal/handlers"
"github.com/kernelkit/webui/internal/restconf"
)
// New creates a fully wired http.Handler with all routes and middleware.
func New(
store *auth.SessionStore,
rc *restconf.Client,
templateFS fs.FS,
staticFS fs.FS,
) (http.Handler, error) {
// Parse templates per page so each can define its own "content" block
// without collisions.
loginTmpl, err := template.ParseFS(templateFS, "pages/login.html")
if err != nil {
return nil, err
}
dashTmpl, err := template.ParseFS(templateFS, "layouts/*.html", "pages/dashboard.html")
if err != nil {
return nil, err
}
fwTmpl, err := template.ParseFS(templateFS, "layouts/*.html", "pages/firewall.html")
if err != nil {
return nil, err
}
ksTmpl, err := template.ParseFS(templateFS, "layouts/*.html", "pages/keystore.html")
if err != nil {
return nil, err
}
ifTmpl, err := template.ParseFS(templateFS, "layouts/*.html", "pages/interfaces.html")
if err != nil {
return nil, err
}
ifDetailTmpl, err := template.ParseFS(templateFS, "layouts/*.html", "pages/iface-detail.html", "fragments/iface-counters.html")
if err != nil {
return nil, err
}
ifCountersTmpl, err := template.ParseFS(templateFS, "fragments/iface-counters.html")
if err != nil {
return nil, err
}
fwrTmpl, err := template.ParseFS(templateFS, "layouts/*.html", "pages/firmware.html")
if err != nil {
return nil, err
}
routingTmpl, err := template.ParseFS(templateFS, "layouts/*.html", "pages/routing.html")
if err != nil {
return nil, err
}
wifiTmpl, err := template.ParseFS(templateFS, "layouts/*.html", "pages/wifi.html")
if err != nil {
return nil, err
}
vpnTmpl, err := template.ParseFS(templateFS, "layouts/*.html", "pages/vpn.html")
if err != nil {
return nil, err
}
dhcpTmpl, err := template.ParseFS(templateFS, "layouts/*.html", "pages/dhcp.html")
if err != nil {
return nil, err
}
ntpTmpl, err := template.ParseFS(templateFS, "layouts/*.html", "pages/ntp.html")
if err != nil {
return nil, err
}
lldpTmpl, err := template.ParseFS(templateFS, "layouts/*.html", "pages/lldp.html")
if err != nil {
return nil, err
}
mdnsTmpl, err := template.ParseFS(templateFS, "layouts/*.html", "pages/mdns.html")
if err != nil {
return nil, err
}
containersTmpl, err := template.ParseFS(templateFS, "layouts/*.html", "pages/containers.html")
if err != nil {
return nil, err
}
login := &auth.LoginHandler{
Store: store,
RC: rc,
Template: loginTmpl,
}
dash := &handlers.DashboardHandler{
Template: dashTmpl,
RC: rc,
}
fw := &handlers.FirewallHandler{
Template: fwTmpl,
RC: rc,
}
ks := &handlers.KeystoreHandler{
Template: ksTmpl,
RC: rc,
}
iface := &handlers.InterfacesHandler{
Template: ifTmpl,
DetailTemplate: ifDetailTmpl,
CountersTemplate: ifCountersTmpl,
RC: rc,
}
sys := &handlers.SystemHandler{
RC: rc,
Template: fwrTmpl,
}
routing := &handlers.RoutingHandler{Template: routingTmpl, RC: rc}
wifi := &handlers.WiFiHandler{Template: wifiTmpl, RC: rc}
vpn := &handlers.VPNHandler{Template: vpnTmpl, RC: rc}
dhcp := &handlers.DHCPHandler{Template: dhcpTmpl, RC: rc}
ntp := &handlers.NTPHandler{Template: ntpTmpl, RC: rc}
lldp := &handlers.LLDPHandler{Template: lldpTmpl, RC: rc}
mdns := &handlers.MDNSHandler{Template: mdnsTmpl, RC: rc}
containers := &handlers.ContainersHandler{Template: containersTmpl, RC: rc}
mux := http.NewServeMux()
// Auth routes (public).
mux.HandleFunc("GET /login", login.ShowLogin)
mux.HandleFunc("POST /login", login.DoLogin)
mux.HandleFunc("POST /logout", login.DoLogout)
// Static assets (public).
staticServer := http.FileServerFS(staticFS)
mux.Handle("GET /assets/", http.StripPrefix("/assets/", staticServer))
// Authenticated routes.
mux.HandleFunc("GET /{$}", dash.Index)
mux.HandleFunc("GET /interfaces", iface.Overview)
mux.HandleFunc("GET /interfaces/{name}", iface.Detail)
mux.HandleFunc("GET /interfaces/{name}/counters", iface.Counters)
mux.HandleFunc("GET /firewall", fw.Overview)
mux.HandleFunc("GET /keystore", ks.Overview)
mux.HandleFunc("GET /firmware", sys.Firmware)
mux.HandleFunc("GET /firmware/progress", sys.FirmwareProgress)
mux.HandleFunc("POST /firmware/install", sys.FirmwareInstall)
mux.HandleFunc("POST /reboot", sys.Reboot)
mux.HandleFunc("GET /device-status", sys.DeviceStatus)
mux.HandleFunc("GET /config", sys.DownloadConfig)
mux.HandleFunc("GET /routing", routing.Overview)
mux.HandleFunc("GET /wifi", wifi.Overview)
mux.HandleFunc("GET /vpn", vpn.Overview)
mux.HandleFunc("GET /dhcp", dhcp.Overview)
mux.HandleFunc("GET /ntp", ntp.Overview)
mux.HandleFunc("GET /lldp", lldp.Overview)
mux.HandleFunc("GET /mdns", mdns.Overview)
mux.HandleFunc("GET /containers", containers.Overview)
handler := authMiddleware(store, mux)
handler = csrfMiddleware(handler)
handler = securityHeadersMiddleware(handler)
return handler, nil
}