Update besar
This commit is contained in:
+114
-83
@@ -9,40 +9,67 @@ import (
|
||||
"api-service/internal/middleware"
|
||||
services "api-service/internal/services/auth"
|
||||
"api-service/pkg/logger"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
swaggerFiles "github.com/swaggo/files"
|
||||
ginSwagger "github.com/swaggo/gin-swagger"
|
||||
)
|
||||
|
||||
func RegisterRoutes(cfg *config.Config) *gin.Engine {
|
||||
// Atur mode Gin berdasarkan konfigurasi
|
||||
gin.SetMode(cfg.Server.Mode)
|
||||
router := gin.New()
|
||||
|
||||
// Initialize auth middleware configuration
|
||||
// =============================================================================
|
||||
// GLOBAL MIDDLEWARE STACK (Middleware yang diperlukan SEMUA route)
|
||||
// =============================================================================
|
||||
middleware.InitializeAuth(cfg)
|
||||
|
||||
// Add global middleware
|
||||
router.Use(middleware.CORSConfig())
|
||||
router.Use(middleware.ErrorHandler())
|
||||
router.Use(logger.RequestLoggerMiddleware(logger.Default()))
|
||||
router.Use(gin.Recovery())
|
||||
// 1. CORS (Paling awal)
|
||||
router.Use(middleware.SecureCORSConfig(cfg.Security))
|
||||
// 2. Rate Limiting
|
||||
router.Use(middleware.RateLimitByIPRedis(cfg.Security))
|
||||
// 3. Logging & Recovery
|
||||
router.Use(logger.RequestLoggerMiddleware(logger.Default()))
|
||||
// 4. Error Handling (Terakhir, untuk menangkap error dari middleware di atasnya)
|
||||
router.Use(middleware.ErrorHandler())
|
||||
|
||||
// =============================================================================
|
||||
// INISIALISASI SERVIS & HANDLER
|
||||
// =============================================================================
|
||||
|
||||
// Initialize services with error handling
|
||||
authService := services.NewAuthService(cfg)
|
||||
if authService == nil {
|
||||
logger.Fatal("Failed to initialize auth service")
|
||||
}
|
||||
|
||||
// Initialize database service
|
||||
dbService := database.New(cfg)
|
||||
|
||||
// =============================================================================
|
||||
// HEALTH CHECK & SYSTEM ROUTES
|
||||
// SWAGGER DOCUMENTATION (Publik - TANPA SecurityHeaders)
|
||||
// =============================================================================
|
||||
// Route ini didefinisikan SEBELUM grup API agar tidak terkena middleware keamanan.
|
||||
router.GET("/swagger/*any", ginSwagger.WrapHandler(
|
||||
swaggerFiles.Handler,
|
||||
ginSwagger.DefaultModelsExpandDepth(-1),
|
||||
ginSwagger.DeepLinking(true),
|
||||
))
|
||||
|
||||
// =============================================================================
|
||||
// API GROUPS (Dengan Keamanan Ketat)
|
||||
// =============================================================================
|
||||
// Terapkan middleware keamanan dan validasi input HANYA ke grup API.
|
||||
// Ini adalah perubahan utama.
|
||||
apiGroup := router.Group("/api")
|
||||
apiGroup.Use(middleware.SecurityHeaders()) // <--- PINDAHKAN KE SINI
|
||||
apiGroup.Use(middleware.InputValidation(cfg.Security)) // <--- PINDAHKAN KE SINI
|
||||
|
||||
// --- HEALTH CHECK & SYSTEM ROUTES ---
|
||||
healthCheckHandler := healthcheckHandlers.NewHealthCheckHandler(dbService)
|
||||
sistem := router.Group("/api/sistem")
|
||||
sistem := apiGroup.Group("/sistem")
|
||||
{
|
||||
sistem.GET("/health", healthCheckHandler.CheckHealth)
|
||||
sistem.GET("/databases", func(c *gin.Context) {
|
||||
@@ -62,89 +89,93 @@ func RegisterRoutes(cfg *config.Config) *gin.Engine {
|
||||
})
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// SWAGGER DOCUMENTATION
|
||||
// =============================================================================
|
||||
|
||||
router.GET("/swagger/*any", ginSwagger.WrapHandler(
|
||||
swaggerFiles.Handler,
|
||||
ginSwagger.DefaultModelsExpandDepth(-1),
|
||||
ginSwagger.DeepLinking(true),
|
||||
))
|
||||
|
||||
// =============================================================================
|
||||
// API v1 GROUP
|
||||
// =============================================================================
|
||||
|
||||
v1 := router.Group("/api/v1")
|
||||
|
||||
// =============================================================================
|
||||
// PUBLIC ROUTES (No Authentication Required)
|
||||
// =============================================================================
|
||||
|
||||
// Authentication routes
|
||||
authHandler := authHandlers.NewAuthHandler(authService)
|
||||
tokenHandler := authHandlers.NewTokenHandler(authService)
|
||||
|
||||
// Basic auth routes
|
||||
v1.POST("/auth/login", authHandler.Login)
|
||||
v1.POST("/auth/register", authHandler.Register)
|
||||
v1.POST("/auth/refresh", authHandler.RefreshToken)
|
||||
|
||||
// Token generation routes
|
||||
v1.POST("/token/generate", tokenHandler.GenerateToken)
|
||||
v1.POST("/token/generate-direct", tokenHandler.GenerateTokenDirect)
|
||||
|
||||
// =============================================================================
|
||||
// PUBLISHED ROUTES
|
||||
|
||||
// Retribusi endpoints with
|
||||
retribusiHandler := retribusiHandlers.NewRetribusiHandler()
|
||||
retribusiGroup := v1.Group("/retribusi")
|
||||
// --- API v1 GROUP ---
|
||||
v1 := apiGroup.Group("/v1")
|
||||
{
|
||||
retribusiGroup.GET("", retribusiHandler.GetRetribusi)
|
||||
retribusiGroup.GET("/dynamic", retribusiHandler.GetRetribusiDynamic)
|
||||
retribusiGroup.GET("/search", retribusiHandler.SearchRetribusiAdvanced)
|
||||
retribusiGroup.GET("/id/:id", retribusiHandler.GetRetribusiByID)
|
||||
retribusiGroup.POST("", func(c *gin.Context) {
|
||||
retribusiHandler.CreateRetribusi(c)
|
||||
})
|
||||
// =============================================================================
|
||||
// PUBLIC ROUTES (No Authentication Required)
|
||||
// =============================================================================
|
||||
authHandler := authHandlers.NewAuthHandler(authService)
|
||||
tokenHandler := authHandlers.NewTokenHandler(authService)
|
||||
|
||||
retribusiGroup.PUT("/id/:id", func(c *gin.Context) {
|
||||
retribusiHandler.UpdateRetribusi(c)
|
||||
})
|
||||
v1.POST("/auth/login", authHandler.Login)
|
||||
v1.POST("/auth/register", authHandler.Register)
|
||||
v1.POST("/auth/refresh", authHandler.RefreshToken)
|
||||
|
||||
retribusiGroup.DELETE("/id/:id", func(c *gin.Context) {
|
||||
retribusiHandler.DeleteRetribusi(c)
|
||||
})
|
||||
v1.POST("/token/generate", tokenHandler.GenerateToken)
|
||||
v1.POST("/token/generate-direct", tokenHandler.GenerateTokenDirect)
|
||||
|
||||
retribusiHandler := retribusiHandlers.NewRetribusiHandler()
|
||||
retribusiGroup := v1.Group("/retribusi")
|
||||
{
|
||||
retribusiGroup.GET("", retribusiHandler.GetRetribusi)
|
||||
retribusiGroup.GET("/dynamic", retribusiHandler.GetRetribusiDynamic)
|
||||
retribusiGroup.GET("/id/:id", retribusiHandler.GetRetribusiByID)
|
||||
retribusiGroup.POST("", func(c *gin.Context) {
|
||||
retribusiHandler.CreateRetribusi(c)
|
||||
})
|
||||
retribusiGroup.PUT("/id/:id", func(c *gin.Context) {
|
||||
retribusiHandler.UpdateRetribusi(c)
|
||||
})
|
||||
retribusiGroup.DELETE("/id/:id", func(c *gin.Context) {
|
||||
retribusiHandler.DeleteRetribusi(c)
|
||||
})
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// PROTECTED ROUTES (Authentication Required)
|
||||
// =============================================================================
|
||||
protected := v1.Group("/")
|
||||
protected.Use(middleware.UnifiedAuthMiddleware(cfg, authService))
|
||||
|
||||
// farmasiObatHandler := farmasiObatHandlers.NewObatHandler()
|
||||
// protectedFarmasiGroup := protected.Group("/farmasi/obat")
|
||||
// {
|
||||
// protectedFarmasiGroup.GET("", farmasiObatHandler.GetObat)
|
||||
// protectedFarmasiGroup.GET("/kode/:kode", farmasiObatHandler.GetObatByID)
|
||||
// }
|
||||
|
||||
// protectedAuthGroup := protected.Group("/auth")
|
||||
// {
|
||||
// protectedAuthGroup.GET("/me", authHandler.Me)
|
||||
// }
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// PROTECTED ROUTES (Authentication Required)
|
||||
// DEBUG ROUTES (Publik - Tanpa keamanan ketat)
|
||||
// =============================================================================
|
||||
router.GET("/debug/token", func(c *gin.Context) {
|
||||
authHeader := c.GetHeader("Authorization")
|
||||
if authHeader == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Header Authorization hilang"})
|
||||
return
|
||||
}
|
||||
|
||||
protected := v1.Group("/")
|
||||
protected.Use(middleware.ConfigurableAuthMiddleware(cfg))
|
||||
parts := strings.SplitN(authHeader, " ", 2)
|
||||
if len(parts) != 2 || strings.ToLower(parts[0]) != "bearer" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Format header harus Bearer {token}"})
|
||||
return
|
||||
}
|
||||
|
||||
// Protected retribusi endpoints (Authentication Required)
|
||||
// protectedRetribusiGroup := protected.Group("/retribusi")
|
||||
// {
|
||||
// protectedRetribusiGroup.GET("", retribusiHandler.GetRetribusi)
|
||||
// protectedRetribusiGroup.GET("/dynamic", retribusiHandler.GetRetribusiDynamic)
|
||||
// protectedRetribusiGroup.GET("/search", retribusiHandler.SearchRetribusiAdvanced)
|
||||
// protectedRetribusiGroup.GET("/id/:id", retribusiHandler.GetRetribusiByID)
|
||||
// protectedRetribusiGroup.POST("", func(c *gin.Context) {
|
||||
// retribusiHandler.CreateRetribusi(c)
|
||||
// })
|
||||
tokenString := parts[1]
|
||||
|
||||
// protectedRetribusiGroup.PUT("/id/:id", func(c *gin.Context) {
|
||||
// retribusiHandler.UpdateRetribusi(c)
|
||||
// })
|
||||
token, _, err := new(jwt.Parser).ParseUnverified(tokenString, jwt.MapClaims{})
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Gagal parsing token: " + err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// protectedRetribusiGroup.DELETE("/id/:id", func(c *gin.Context) {
|
||||
// retribusiHandler.DeleteRetribusi(c)
|
||||
// })
|
||||
// }
|
||||
claims, ok := token.Claims.(jwt.MapClaims)
|
||||
if !ok {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Format claim tidak valid"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"header": token.Header,
|
||||
"claims": claims,
|
||||
})
|
||||
})
|
||||
|
||||
return router
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user