mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2026-02-11 21:41:46 +01:00
Fix setup issue with chi router
This commit is contained in:
@@ -106,6 +106,27 @@ func (s *Server) init() error {
|
|||||||
|
|
||||||
authHandle := auth.GetAuthInstance()
|
authHandle := auth.GetAuthInstance()
|
||||||
|
|
||||||
|
// Middleware must be defined before routes in chi
|
||||||
|
s.router.Use(func(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
start := time.Now()
|
||||||
|
ww := middleware.NewWrapResponseWriter(rw, r.ProtoMajor)
|
||||||
|
next.ServeHTTP(ww, r)
|
||||||
|
cclog.Debugf("%s %s (%d, %.02fkb, %dms)",
|
||||||
|
r.Method, r.URL.RequestURI(),
|
||||||
|
ww.Status(), float32(ww.BytesWritten())/1024,
|
||||||
|
time.Since(start).Milliseconds())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
s.router.Use(middleware.Compress(5))
|
||||||
|
s.router.Use(middleware.Recoverer)
|
||||||
|
s.router.Use(cors.Handler(cors.Options{
|
||||||
|
AllowCredentials: true,
|
||||||
|
AllowedHeaders: []string{"X-Requested-With", "Content-Type", "Authorization", "Origin"},
|
||||||
|
AllowedMethods: []string{"GET", "POST", "HEAD", "OPTIONS"},
|
||||||
|
AllowedOrigins: []string{"*"},
|
||||||
|
}))
|
||||||
|
|
||||||
s.restAPIHandle = api.New()
|
s.restAPIHandle = api.New()
|
||||||
|
|
||||||
info := map[string]any{}
|
info := map[string]any{}
|
||||||
@@ -198,7 +219,9 @@ func (s *Server) init() error {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// API routes (JWT token auth)
|
// API routes (JWT token auth)
|
||||||
s.router.Route("/api", func(securedapi chi.Router) {
|
s.router.Route("/api", func(apiRouter chi.Router) {
|
||||||
|
// Main API routes with API auth
|
||||||
|
apiRouter.Group(func(securedapi chi.Router) {
|
||||||
if !config.Keys.DisableAuthentication {
|
if !config.Keys.DisableAuthentication {
|
||||||
securedapi.Use(func(next http.Handler) http.Handler {
|
securedapi.Use(func(next http.Handler) http.Handler {
|
||||||
return authHandle.AuthAPI(next, onFailureResponse)
|
return authHandle.AuthAPI(next, onFailureResponse)
|
||||||
@@ -207,6 +230,17 @@ func (s *Server) init() error {
|
|||||||
s.restAPIHandle.MountAPIRoutes(securedapi)
|
s.restAPIHandle.MountAPIRoutes(securedapi)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Metric store API routes with separate auth
|
||||||
|
apiRouter.Group(func(metricstoreapi chi.Router) {
|
||||||
|
if !config.Keys.DisableAuthentication {
|
||||||
|
metricstoreapi.Use(func(next http.Handler) http.Handler {
|
||||||
|
return authHandle.AuthMetricStoreAPI(next, onFailureResponse)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
s.restAPIHandle.MountMetricStoreAPIRoutes(metricstoreapi)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
// User API routes
|
// User API routes
|
||||||
s.router.Route("/userapi", func(userapi chi.Router) {
|
s.router.Route("/userapi", func(userapi chi.Router) {
|
||||||
if !config.Keys.DisableAuthentication {
|
if !config.Keys.DisableAuthentication {
|
||||||
@@ -217,8 +251,9 @@ func (s *Server) init() error {
|
|||||||
s.restAPIHandle.MountUserAPIRoutes(userapi)
|
s.restAPIHandle.MountUserAPIRoutes(userapi)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Config API routes
|
// Config API routes (uses Group with full paths to avoid shadowing
|
||||||
s.router.Route("/config", func(configapi chi.Router) {
|
// the /config page route that is registered in the secured group)
|
||||||
|
s.router.Group(func(configapi chi.Router) {
|
||||||
if !config.Keys.DisableAuthentication {
|
if !config.Keys.DisableAuthentication {
|
||||||
configapi.Use(func(next http.Handler) http.Handler {
|
configapi.Use(func(next http.Handler) http.Handler {
|
||||||
return authHandle.AuthConfigAPI(next, onFailureResponse)
|
return authHandle.AuthConfigAPI(next, onFailureResponse)
|
||||||
@@ -244,16 +279,6 @@ func (s *Server) init() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Metric store API routes (mounted under /api but with different auth)
|
|
||||||
s.router.Route("/api", func(metricstoreapi chi.Router) {
|
|
||||||
if !config.Keys.DisableAuthentication {
|
|
||||||
metricstoreapi.Use(func(next http.Handler) http.Handler {
|
|
||||||
return authHandle.AuthMetricStoreAPI(next, onFailureResponse)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
s.restAPIHandle.MountMetricStoreAPIRoutes(metricstoreapi)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Custom 404 handler for unmatched routes
|
// Custom 404 handler for unmatched routes
|
||||||
s.router.NotFound(func(rw http.ResponseWriter, r *http.Request) {
|
s.router.NotFound(func(rw http.ResponseWriter, r *http.Request) {
|
||||||
if strings.HasPrefix(r.URL.Path, "/api/") || strings.HasPrefix(r.URL.Path, "/userapi/") ||
|
if strings.HasPrefix(r.URL.Path, "/api/") || strings.HasPrefix(r.URL.Path, "/userapi/") ||
|
||||||
@@ -287,15 +312,6 @@ func (s *Server) init() error {
|
|||||||
s.router.Handle("/*", http.FileServer(http.Dir(config.Keys.StaticFiles)))
|
s.router.Handle("/*", http.FileServer(http.Dir(config.Keys.StaticFiles)))
|
||||||
}
|
}
|
||||||
|
|
||||||
s.router.Use(middleware.Compress(5))
|
|
||||||
s.router.Use(middleware.Recoverer)
|
|
||||||
s.router.Use(cors.Handler(cors.Options{
|
|
||||||
AllowCredentials: true,
|
|
||||||
AllowedHeaders: []string{"X-Requested-With", "Content-Type", "Authorization", "Origin"},
|
|
||||||
AllowedMethods: []string{"GET", "POST", "HEAD", "OPTIONS"},
|
|
||||||
AllowedOrigins: []string{"*"},
|
|
||||||
}))
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,19 +322,6 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) Start(ctx context.Context) error {
|
func (s *Server) Start(ctx context.Context) error {
|
||||||
// Add request logging middleware
|
|
||||||
s.router.Use(func(next http.Handler) http.Handler {
|
|
||||||
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
|
||||||
start := time.Now()
|
|
||||||
ww := middleware.NewWrapResponseWriter(rw, r.ProtoMajor)
|
|
||||||
next.ServeHTTP(ww, r)
|
|
||||||
cclog.Debugf("%s %s (%d, %.02fkb, %dms)",
|
|
||||||
r.Method, r.URL.RequestURI(),
|
|
||||||
ww.Status(), float32(ww.BytesWritten())/1024,
|
|
||||||
time.Since(start).Milliseconds())
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// Use configurable timeouts with defaults
|
// Use configurable timeouts with defaults
|
||||||
readTimeout := time.Duration(defaultReadTimeout) * time.Second
|
readTimeout := time.Duration(defaultReadTimeout) * time.Second
|
||||||
writeTimeout := time.Duration(defaultWriteTimeout) * time.Second
|
writeTimeout := time.Duration(defaultWriteTimeout) * time.Second
|
||||||
|
|||||||
@@ -140,16 +140,18 @@ func (api *RestAPI) MountMetricStoreAPIRoutes(r chi.Router) {
|
|||||||
|
|
||||||
// MountConfigAPIRoutes registers configuration and user management endpoints.
|
// MountConfigAPIRoutes registers configuration and user management endpoints.
|
||||||
// These routes use session-based authentication and require admin privileges.
|
// These routes use session-based authentication and require admin privileges.
|
||||||
|
// Routes use full paths (including /config prefix) to avoid conflicting with
|
||||||
|
// the /config page route when registered via Group instead of Route.
|
||||||
func (api *RestAPI) MountConfigAPIRoutes(r chi.Router) {
|
func (api *RestAPI) MountConfigAPIRoutes(r chi.Router) {
|
||||||
// Settings Frontend Uses SessionAuth
|
// Settings Frontend Uses SessionAuth
|
||||||
if api.Authentication != nil {
|
if api.Authentication != nil {
|
||||||
r.Get("/roles/", api.getRoles)
|
r.Get("/config/roles/", api.getRoles)
|
||||||
r.Post("/users/", api.createUser)
|
r.Post("/config/users/", api.createUser)
|
||||||
r.Put("/users/", api.createUser)
|
r.Put("/config/users/", api.createUser)
|
||||||
r.Get("/users/", api.getUsers)
|
r.Get("/config/users/", api.getUsers)
|
||||||
r.Delete("/users/", api.deleteUser)
|
r.Delete("/config/users/", api.deleteUser)
|
||||||
r.Post("/user/{id}", api.updateUser)
|
r.Post("/config/user/{id}", api.updateUser)
|
||||||
r.Post("/notice/", api.editNotice)
|
r.Post("/config/notice/", api.editNotice)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user