From e6d87d025f24ff1eaf357ac524f2726b7c88e146 Mon Sep 17 00:00:00 2001 From: ryyst Date: Sun, 21 Sep 2025 12:15:38 +0300 Subject: [PATCH] fix: secure admin endpoints with authentication middleware (issue #4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add config parameter to AuthService constructor - Implement proper config-based auth checks in middleware - Wrap all admin endpoints (users, groups, tokens) with authentication - Apply granular scopes: admin:users:*, admin:groups:*, admin:tokens:* - Maintain backward compatibility when config is nil 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- auth/auth.go | 4 +++- auth/middleware.go | 9 +++++---- server/routes.go | 48 ++++++++++++++++++++++++++++++++++------------ server/server.go | 2 +- 4 files changed, 45 insertions(+), 18 deletions(-) diff --git a/auth/auth.go b/auth/auth.go index db66440..00fa831 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -26,13 +26,15 @@ type AuthContext struct { type AuthService struct { db *badger.DB logger *logrus.Logger + config *types.Config } // NewAuthService creates a new authentication service -func NewAuthService(db *badger.DB, logger *logrus.Logger) *AuthService { +func NewAuthService(db *badger.DB, logger *logrus.Logger, config *types.Config) *AuthService { return &AuthService{ db: db, logger: logger, + config: config, } } diff --git a/auth/middleware.go b/auth/middleware.go index 163b6cf..07c244e 100644 --- a/auth/middleware.go +++ b/auth/middleware.go @@ -138,11 +138,12 @@ func (s *RateLimitService) RateLimitMiddleware(next http.HandlerFunc) http.Handl } } -// isAuthEnabled checks if authentication is enabled (would be passed from config) +// isAuthEnabled checks if authentication is enabled from config func (s *AuthService) isAuthEnabled() bool { - // This would normally be injected from config, but for now we'll assume enabled - // TODO: Inject config dependency - return true + if s.config != nil { + return s.config.AuthEnabled + } + return true // Default to enabled if no config } // Helper method to check rate limits (simplified version) diff --git a/server/routes.go b/server/routes.go index 4512783..9db7337 100644 --- a/server/routes.go +++ b/server/routes.go @@ -32,20 +32,44 @@ func (s *Server) setupRoutes() *mux.Router { // Authentication and user management endpoints (available when auth is enabled) if s.config.AuthEnabled { - // User Management endpoints - router.HandleFunc("/api/users", s.createUserHandler).Methods("POST") - router.HandleFunc("/api/users/{uuid}", s.getUserHandler).Methods("GET") - router.HandleFunc("/api/users/{uuid}", s.updateUserHandler).Methods("PUT") - router.HandleFunc("/api/users/{uuid}", s.deleteUserHandler).Methods("DELETE") + // User Management endpoints (with authentication middleware) + router.Handle("/api/users", s.authService.Middleware( + []string{"admin:users:create"}, nil, "", + )(s.createUserHandler)).Methods("POST") + + router.Handle("/api/users/{uuid}", s.authService.Middleware( + []string{"admin:users:read"}, nil, "", + )(s.getUserHandler)).Methods("GET") + + router.Handle("/api/users/{uuid}", s.authService.Middleware( + []string{"admin:users:update"}, nil, "", + )(s.updateUserHandler)).Methods("PUT") + + router.Handle("/api/users/{uuid}", s.authService.Middleware( + []string{"admin:users:delete"}, nil, "", + )(s.deleteUserHandler)).Methods("DELETE") - // Group Management endpoints - router.HandleFunc("/api/groups", s.createGroupHandler).Methods("POST") - router.HandleFunc("/api/groups/{uuid}", s.getGroupHandler).Methods("GET") - router.HandleFunc("/api/groups/{uuid}", s.updateGroupHandler).Methods("PUT") - router.HandleFunc("/api/groups/{uuid}", s.deleteGroupHandler).Methods("DELETE") + // Group Management endpoints (with authentication middleware) + router.Handle("/api/groups", s.authService.Middleware( + []string{"admin:groups:create"}, nil, "", + )(s.createGroupHandler)).Methods("POST") + + router.Handle("/api/groups/{uuid}", s.authService.Middleware( + []string{"admin:groups:read"}, nil, "", + )(s.getGroupHandler)).Methods("GET") + + router.Handle("/api/groups/{uuid}", s.authService.Middleware( + []string{"admin:groups:update"}, nil, "", + )(s.updateGroupHandler)).Methods("PUT") + + router.Handle("/api/groups/{uuid}", s.authService.Middleware( + []string{"admin:groups:delete"}, nil, "", + )(s.deleteGroupHandler)).Methods("DELETE") - // Token Management endpoints - router.HandleFunc("/api/tokens", s.createTokenHandler).Methods("POST") + // Token Management endpoints (with authentication middleware) + router.Handle("/api/tokens", s.authService.Middleware( + []string{"admin:tokens:create"}, nil, "", + )(s.createTokenHandler)).Methods("POST") } // Revision History endpoints (available when revision history is enabled) diff --git a/server/server.go b/server/server.go index 79476fb..22735a9 100644 --- a/server/server.go +++ b/server/server.go @@ -118,7 +118,7 @@ func NewServer(config *types.Config) (*Server, error) { server.revisionService = storage.NewRevisionService(storageService) // Initialize authentication service - server.authService = auth.NewAuthService(db, logger) + server.authService = auth.NewAuthService(db, logger, config) // Setup initial root account if needed (Issue #3) if config.AuthEnabled {