加固后台管理安全
This commit is contained in:
@@ -2,7 +2,6 @@ package router
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"hfb_sys/backend/internal/config"
|
||||
@@ -63,7 +62,7 @@ func New(cfg config.Config, deps Dependencies, logger *zap.Logger) *gin.Engine {
|
||||
engine.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||
}
|
||||
if cfg.RateLimit.Enabled {
|
||||
engine.Use(middleware.RateLimitPerMinute(cfg.RateLimit.RequestsPerMinute))
|
||||
engine.Use(middleware.RateLimitPerMinute(cfg.RateLimit.RequestsPerMinute, deps.Redis))
|
||||
}
|
||||
|
||||
jwtManager := auth.NewJWTManager(cfg.JWTSecret)
|
||||
@@ -166,8 +165,8 @@ func New(cfg config.Config, deps Dependencies, logger *zap.Logger) *gin.Engine {
|
||||
var paymentConfigService *paymentconfig.Service
|
||||
var paymentConfigHandler *paymentconfig.Handler
|
||||
if deps.DB != nil {
|
||||
// 从环境变量获取加密密钥,如果没有则使用 MockEncryptor
|
||||
encryptionKey := os.Getenv("PAYMENT_CONFIG_ENCRYPTION_KEY")
|
||||
// 生产环境必须配置有效加密密钥;开发/测试缺失时才降级 MockEncryptor。
|
||||
encryptionKey := cfg.PaymentConfigEncryptionKey
|
||||
var encryptor paymentconfig.Encryptor
|
||||
if encryptionKey != "" {
|
||||
if aesEncryptor, err := paymentconfig.NewAESEncryptor(encryptionKey); err == nil {
|
||||
@@ -175,6 +174,9 @@ func New(cfg config.Config, deps Dependencies, logger *zap.Logger) *gin.Engine {
|
||||
}
|
||||
}
|
||||
if encryptor == nil {
|
||||
if cfg.AppEnv == "production" {
|
||||
logger.Fatal("PAYMENT_CONFIG_ENCRYPTION_KEY not set or invalid")
|
||||
}
|
||||
encryptor = &paymentconfig.MockEncryptor{}
|
||||
logger.Warn("PAYMENT_CONFIG_ENCRYPTION_KEY not set or invalid, using MockEncryptor")
|
||||
}
|
||||
@@ -225,7 +227,7 @@ func New(cfg config.Config, deps Dependencies, logger *zap.Logger) *gin.Engine {
|
||||
systemConfigHandler := systemconfig.NewHandler(systemConfigService)
|
||||
var adminRoleRepo *adminrole.Repository
|
||||
if deps.DB != nil {
|
||||
adminRoleRepo = adminrole.NewRepository(deps.DB)
|
||||
adminRoleRepo = adminrole.NewRepository(deps.DB, deps.Redis)
|
||||
}
|
||||
adminRoleService := adminrole.NewService(adminRoleRepo)
|
||||
adminRoleHandler := adminrole.NewHandler(adminRoleService)
|
||||
@@ -246,7 +248,10 @@ func New(cfg config.Config, deps Dependencies, logger *zap.Logger) *gin.Engine {
|
||||
fileService := filemodule.NewService(fileStorage)
|
||||
fileHandler := filemodule.NewHandler(fileService, fileStorage)
|
||||
listingService := listing.NewService(listingRepo, systemConfigRepo)
|
||||
listingHandler := listing.NewHandler(listingService, fileStorage)
|
||||
listingHandler := listing.NewHandler(listingService, fileStorage, listing.HandlerOptions{
|
||||
ExternalUploadSecret: cfg.ExternalUploadSecret,
|
||||
ExternalUploadAllowedIPs: cfg.ExternalUploadAllowedIPs,
|
||||
})
|
||||
var announcementRepo *announcement.Repository
|
||||
if deps.DB != nil {
|
||||
announcementRepo = announcement.NewRepository(deps.DB)
|
||||
@@ -254,7 +259,20 @@ func New(cfg config.Config, deps Dependencies, logger *zap.Logger) *gin.Engine {
|
||||
announcementService := announcement.NewService(announcementRepo)
|
||||
announcementHandler := announcement.NewHandler(announcementService)
|
||||
requireAuth := middleware.Auth(jwtManager)
|
||||
requireAdmin := middleware.AdminAuth(jwtManager)
|
||||
var validateAdminToken middleware.AdminTokenValidatorFunc
|
||||
if adminAuthRepo != nil {
|
||||
validateAdminToken = func(ctx context.Context, adminID uint64, tokenVersion int64) (middleware.AdminTokenContext, error) {
|
||||
admin, err := adminAuthRepo.FindActiveForToken(ctx, adminID, tokenVersion)
|
||||
if err != nil {
|
||||
return middleware.AdminTokenContext{}, err
|
||||
}
|
||||
return middleware.AdminTokenContext{
|
||||
Username: admin.Username,
|
||||
PasswordMustChange: admin.PasswordMustChange,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
requireAdmin := middleware.AdminAuth(jwtManager, validateAdminToken)
|
||||
requireRealname := middleware.RequireRealname(userRepo)
|
||||
requirePerm := func(code string) gin.HandlerFunc {
|
||||
return middleware.RequirePermission(code, deps.Redis)
|
||||
@@ -410,7 +428,7 @@ func New(cfg config.Config, deps Dependencies, logger *zap.Logger) *gin.Engine {
|
||||
adminAuthRoutes.POST("/refresh", adminAuthHandler.Refresh)
|
||||
}
|
||||
|
||||
adminRoutes := api.Group("/admin", requireAdmin)
|
||||
adminRoutes := api.Group("/admin", requireAdmin, middleware.RequireAdminPasswordChanged())
|
||||
{
|
||||
adminRoutes.GET("/me", adminAuthHandler.Me)
|
||||
adminRoutes.PUT("/me/support-status", adminAuthHandler.UpdateSupportStatus)
|
||||
@@ -455,7 +473,9 @@ func New(cfg config.Config, deps Dependencies, logger *zap.Logger) *gin.Engine {
|
||||
adminRoutes.GET("/payment-configs", requirePerm("payment_config:list"), paymentConfigHandler.List)
|
||||
adminRoutes.GET("/payment-configs/export", requirePerm("payment_config:view_secret"), paymentConfigHandler.ExportBackup)
|
||||
adminRoutes.POST("/payment-configs/import", requirePerm("payment_config:view_secret"), paymentConfigHandler.ImportBackup)
|
||||
adminRoutes.GET("/payment-configs/:id", requirePerm("payment_config:list"), paymentConfigHandler.Get)
|
||||
adminRoutes.GET("/payment-configs/:id", requirePerm("payment_config:list"), middleware.RequirePermissionIf("payment_config:view_secret", deps.Redis, func(c *gin.Context) bool {
|
||||
return c.Query("include_secret") == "true"
|
||||
}), paymentConfigHandler.Get)
|
||||
adminRoutes.POST("/payment-configs", requirePerm("payment_config:create"), paymentConfigHandler.Create)
|
||||
adminRoutes.PUT("/payment-configs/:id", requirePerm("payment_config:update"), paymentConfigHandler.Update)
|
||||
adminRoutes.DELETE("/payment-configs/:id", requirePerm("payment_config:delete"), paymentConfigHandler.Delete)
|
||||
@@ -498,7 +518,8 @@ func New(cfg config.Config, deps Dependencies, logger *zap.Logger) *gin.Engine {
|
||||
adminRoutes.PUT("/admin-users/:id", requirePerm("admin_user:manage"), adminMgrHandler.Update)
|
||||
adminRoutes.DELETE("/admin-users/:id", requirePerm("admin_user:manage"), adminMgrHandler.Delete)
|
||||
adminRoutes.PUT("/admin-users/:id/roles", requirePerm("admin_user:manage"), adminMgrHandler.AssignRoles)
|
||||
adminRoutes.PUT("/admin-users/:id/password", adminMgrHandler.ChangePassword)
|
||||
adminRoutes.PUT("/admin-users/me/password", adminMgrHandler.ChangeOwnPassword)
|
||||
adminRoutes.PUT("/admin-users/:id/password", requirePerm("admin_user:manage"), adminMgrHandler.ResetPassword)
|
||||
|
||||
// 公告管理
|
||||
adminRoutes.GET("/announcements", requirePerm("announcement:view"), announcementHandler.AdminList)
|
||||
|
||||
Reference in New Issue
Block a user