Some checks failed
CI / Build & Test (push) Failing after 1m31s
- Add user management endpoints (list/create/get/update/delete) with pagination and search - Add dashboard stats endpoint with tenant/user/online counts and growth metrics - Add tenant resolver middleware for multi-tenant request scoping - Add i18n kernel with zh/en message files and AcceptLanguage middleware - Add WebSocket hub/handler for real-time communication - Add job scheduler kernel with cron support - Add plugin sandbox for isolated execution - Add storage kernel (local filesystem) - Add event bus kernel for pub/sub - Add cache kernel abstraction - Add database migration runner and version upgrade checker - Add rate limiting middleware with Redis backend - Add SQL migrations for rbac, audit_logs, settings, notifications, examples - Extend user repository with list/delete/count operations - Register all module routes with tenant resolver
87 lines
2.1 KiB
Go
87 lines
2.1 KiB
Go
package interfaces
|
|
|
|
import (
|
|
"mengstack/internal/app/middleware"
|
|
"mengstack/internal/config"
|
|
"mengstack/internal/kernel/tenant"
|
|
"mengstack/internal/modules/auth/application"
|
|
"mengstack/internal/modules/auth/infrastructure"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"go.uber.org/fx"
|
|
)
|
|
|
|
type AuthMiddleware struct {
|
|
fx.In
|
|
|
|
Service *application.Service
|
|
}
|
|
|
|
func NewAuthMiddleware(in AuthMiddleware) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
authHeader := c.GetHeader("Authorization")
|
|
if authHeader == "" {
|
|
c.AbortWithStatusJSON(401, gin.H{"code": -1, "message": "missing authorization"})
|
|
return
|
|
}
|
|
|
|
token := authHeader
|
|
if len(authHeader) > 7 && authHeader[:7] == "Bearer " {
|
|
token = authHeader[7:]
|
|
}
|
|
|
|
claims, err := application.ParseToken(token, in.Service.JWTSecret())
|
|
if err != nil {
|
|
c.AbortWithStatusJSON(401, gin.H{"code": -1, "message": "invalid token"})
|
|
return
|
|
}
|
|
|
|
c.Set("user_id", claims.UserID)
|
|
c.Set("tenant_id", claims.TenantID)
|
|
c.Next()
|
|
}
|
|
}
|
|
|
|
func SetupRoutes(r *gin.Engine, h *Handler, authMW gin.HandlerFunc, tenantResolver tenant.Resolver) {
|
|
auth := r.Group("/api/v1/auth")
|
|
auth.Use(middleware.OptionalTenant(tenantResolver))
|
|
{
|
|
auth.POST("/register", h.Register)
|
|
auth.POST("/login", h.Login)
|
|
auth.POST("/refresh", h.RefreshToken)
|
|
}
|
|
|
|
protected := r.Group("/api/v1")
|
|
protected.Use(authMW, middleware.MultiTenant(tenantResolver))
|
|
{
|
|
protected.GET("/ping", h.Ping)
|
|
protected.GET("/profile", h.GetProfile)
|
|
protected.POST("/password", h.ChangePassword)
|
|
|
|
protected.GET("/users", h.ListUsers)
|
|
protected.POST("/users", h.CreateUser)
|
|
protected.GET("/users/:id", h.GetUser)
|
|
protected.PUT("/users/:id", h.UpdateUser)
|
|
protected.DELETE("/users/:id", h.DeleteUser)
|
|
}
|
|
}
|
|
|
|
func NewJWTConfig(cfg *config.Config) application.JWTConfig {
|
|
return application.JWTConfig{
|
|
Secret: cfg.JWT.Secret,
|
|
AccessExpiryMinutes: cfg.JWT.AccessExpiryMinutes,
|
|
RefreshExpiryDays: cfg.JWT.RefreshExpiryDays,
|
|
Issuer: cfg.JWT.Issuer,
|
|
}
|
|
}
|
|
|
|
var Module = fx.Module("auth",
|
|
fx.Provide(
|
|
NewJWTConfig,
|
|
infrastructure.NewUserRepository,
|
|
application.NewService,
|
|
NewHandler,
|
|
NewAuthMiddleware,
|
|
),
|
|
)
|