feat: Implement User Management API (Issue #6) and wire up router
- Create UserService with CRUD operations - Implement ListUsers with pagination - Implement GetUser, CreateUser, UpdateUser, DeleteUser - Add ResetUserPassword for admin password resets - Create UserHandler with HTTP endpoints - Update router to wire up all handlers and middleware - Add authentication middleware to protected routes - Add admin-only middleware to user management routes Closes #6 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,12 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/yourusername/victorialogs-manager/internal/api/handlers"
|
||||
"github.com/yourusername/victorialogs-manager/internal/api/middleware"
|
||||
"github.com/yourusername/victorialogs-manager/internal/config"
|
||||
"github.com/yourusername/victorialogs-manager/internal/repository"
|
||||
"github.com/yourusername/victorialogs-manager/internal/services"
|
||||
"github.com/yourusername/victorialogs-manager/internal/utils"
|
||||
)
|
||||
|
||||
// NewRouter creates and configures the main router
|
||||
@@ -13,15 +18,35 @@ func NewRouter(cfg *config.Config, db *sql.DB) *gin.Engine {
|
||||
// Set Gin mode
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
|
||||
router := gin.Default()
|
||||
router := gin.New()
|
||||
|
||||
// CORS middleware
|
||||
router.Use(corsMiddleware())
|
||||
// Global middleware
|
||||
router.Use(gin.Recovery())
|
||||
router.Use(middleware.CORSMiddleware())
|
||||
router.Use(middleware.RequestLogger())
|
||||
|
||||
// Initialize JWT manager
|
||||
jwtManager := utils.NewJWTManager(
|
||||
cfg.Auth.JWTSecret,
|
||||
cfg.Auth.AccessTokenDuration,
|
||||
cfg.Auth.RefreshTokenDuration,
|
||||
)
|
||||
|
||||
// Initialize repositories
|
||||
userRepo := repository.NewUserRepository(db)
|
||||
|
||||
// Initialize services
|
||||
authService := services.NewAuthService(userRepo, jwtManager)
|
||||
userService := services.NewUserService(userRepo)
|
||||
|
||||
// Initialize handlers
|
||||
authHandler := handlers.NewAuthHandler(authService)
|
||||
userHandler := handlers.NewUserHandler(userService)
|
||||
|
||||
// Health check endpoint
|
||||
router.GET("/health", func(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"status": "ok",
|
||||
"status": "ok",
|
||||
"service": "victorialogs-manager",
|
||||
})
|
||||
})
|
||||
@@ -32,45 +57,34 @@ func NewRouter(cfg *config.Config, db *sql.DB) *gin.Engine {
|
||||
// Authentication routes (public)
|
||||
auth := v1.Group("/auth")
|
||||
{
|
||||
auth.POST("/login", func(c *gin.Context) {
|
||||
// TODO: Implement login handler
|
||||
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
||||
})
|
||||
auth.POST("/refresh", func(c *gin.Context) {
|
||||
// TODO: Implement refresh handler
|
||||
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
||||
})
|
||||
auth.GET("/me", func(c *gin.Context) {
|
||||
// TODO: Implement me handler (requires auth)
|
||||
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
||||
})
|
||||
auth.POST("/login", authHandler.Login)
|
||||
auth.POST("/refresh", authHandler.RefreshToken)
|
||||
}
|
||||
|
||||
// Protected routes (require authentication)
|
||||
// TODO: Add auth middleware here
|
||||
|
||||
// User management routes
|
||||
users := v1.Group("/users")
|
||||
// Protected auth routes (require authentication)
|
||||
authProtected := v1.Group("/auth")
|
||||
authProtected.Use(middleware.AuthMiddleware(jwtManager))
|
||||
{
|
||||
users.GET("", func(c *gin.Context) {
|
||||
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
||||
})
|
||||
users.POST("", func(c *gin.Context) {
|
||||
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
||||
})
|
||||
users.GET("/:id", func(c *gin.Context) {
|
||||
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
||||
})
|
||||
users.PUT("/:id", func(c *gin.Context) {
|
||||
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
||||
})
|
||||
users.DELETE("/:id", func(c *gin.Context) {
|
||||
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
||||
})
|
||||
authProtected.GET("/me", authHandler.GetMe)
|
||||
authProtected.POST("/change-password", authHandler.ChangePassword)
|
||||
}
|
||||
|
||||
// Log querying routes
|
||||
// User management routes (admin only)
|
||||
users := v1.Group("/users")
|
||||
users.Use(middleware.AuthMiddleware(jwtManager))
|
||||
users.Use(middleware.RequireAdmin())
|
||||
{
|
||||
users.GET("", userHandler.ListUsers)
|
||||
users.POST("", userHandler.CreateUser)
|
||||
users.GET("/:id", userHandler.GetUser)
|
||||
users.PUT("/:id", userHandler.UpdateUser)
|
||||
users.DELETE("/:id", userHandler.DeleteUser)
|
||||
users.POST("/:id/reset-password", userHandler.ResetUserPassword)
|
||||
}
|
||||
|
||||
// Log querying routes (protected)
|
||||
logs := v1.Group("/logs")
|
||||
logs.Use(middleware.AuthMiddleware(jwtManager))
|
||||
{
|
||||
logs.POST("/query", func(c *gin.Context) {
|
||||
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
||||
@@ -89,8 +103,9 @@ func NewRouter(cfg *config.Config, db *sql.DB) *gin.Engine {
|
||||
})
|
||||
}
|
||||
|
||||
// Alert management routes
|
||||
// Alert management routes (protected)
|
||||
alerts := v1.Group("/alerts")
|
||||
alerts.Use(middleware.AuthMiddleware(jwtManager))
|
||||
{
|
||||
alerts.GET("/rules", func(c *gin.Context) {
|
||||
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
||||
@@ -115,8 +130,9 @@ func NewRouter(cfg *config.Config, db *sql.DB) *gin.Engine {
|
||||
})
|
||||
}
|
||||
|
||||
// Pattern detection routes
|
||||
// Pattern detection routes (protected)
|
||||
patterns := v1.Group("/patterns")
|
||||
patterns.Use(middleware.AuthMiddleware(jwtManager))
|
||||
{
|
||||
patterns.GET("", func(c *gin.Context) {
|
||||
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
||||
@@ -141,8 +157,9 @@ func NewRouter(cfg *config.Config, db *sql.DB) *gin.Engine {
|
||||
})
|
||||
}
|
||||
|
||||
// Report routes
|
||||
// Report routes (protected)
|
||||
reports := v1.Group("/reports")
|
||||
reports.Use(middleware.AuthMiddleware(jwtManager))
|
||||
{
|
||||
reports.GET("", func(c *gin.Context) {
|
||||
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
|
||||
@@ -167,20 +184,3 @@ func NewRouter(cfg *config.Config, db *sql.DB) *gin.Engine {
|
||||
|
||||
return router
|
||||
}
|
||||
|
||||
// corsMiddleware handles CORS headers
|
||||
func corsMiddleware() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
|
||||
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
|
||||
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE")
|
||||
|
||||
if c.Request.Method == "OPTIONS" {
|
||||
c.AbortWithStatus(204)
|
||||
return
|
||||
}
|
||||
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user