- 创建Repository接口定义(UserRepository、ProfileRepository、TextureRepository等) - 创建Repository接口实现 - 创建依赖注入容器(container.Container) - 改造Handler层使用依赖注入(AuthHandler、UserHandler、TextureHandler) - 创建新的路由注册方式(RegisterRoutesWithDI) - 提供main.go示例文件展示如何使用依赖注入 同时包含之前的安全修复: - CORS配置安全加固 - 头像URL验证安全修复 - JWT algorithm confusion漏洞修复 - Recovery中间件增强 - 敏感错误信息泄露修复 - 类型断言安全修复
192 lines
5.2 KiB
Go
192 lines
5.2 KiB
Go
package handler
|
||
|
||
import (
|
||
"carrotskin/internal/container"
|
||
"carrotskin/internal/middleware"
|
||
"carrotskin/internal/model"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
)
|
||
|
||
// Handlers 集中管理所有Handler
|
||
type Handlers struct {
|
||
Auth *AuthHandler
|
||
User *UserHandler
|
||
Texture *TextureHandler
|
||
// Profile *ProfileHandler // 后续添加
|
||
// Captcha *CaptchaHandler // 后续添加
|
||
// Yggdrasil *YggdrasilHandler // 后续添加
|
||
}
|
||
|
||
// NewHandlers 创建所有Handler实例
|
||
func NewHandlers(c *container.Container) *Handlers {
|
||
return &Handlers{
|
||
Auth: NewAuthHandler(c),
|
||
User: NewUserHandler(c),
|
||
Texture: NewTextureHandler(c),
|
||
}
|
||
}
|
||
|
||
// RegisterRoutesWithDI 使用依赖注入注册所有路由
|
||
func RegisterRoutesWithDI(router *gin.Engine, c *container.Container) {
|
||
// 设置Swagger文档
|
||
SetupSwagger(router)
|
||
|
||
// 创建Handler实例
|
||
h := NewHandlers(c)
|
||
|
||
// API路由组
|
||
v1 := router.Group("/api/v1")
|
||
{
|
||
// 认证路由(无需JWT)
|
||
registerAuthRoutes(v1, h.Auth)
|
||
|
||
// 用户路由(需要JWT认证)
|
||
registerUserRoutes(v1, h.User)
|
||
|
||
// 材质路由
|
||
registerTextureRoutes(v1, h.Texture)
|
||
|
||
// 档案路由(暂时保持原有方式)
|
||
registerProfileRoutes(v1)
|
||
|
||
// 验证码路由(暂时保持原有方式)
|
||
registerCaptchaRoutes(v1)
|
||
|
||
// Yggdrasil API路由组(暂时保持原有方式)
|
||
registerYggdrasilRoutes(v1)
|
||
|
||
// 系统路由
|
||
registerSystemRoutes(v1)
|
||
}
|
||
}
|
||
|
||
// registerAuthRoutes 注册认证路由
|
||
func registerAuthRoutes(v1 *gin.RouterGroup, h *AuthHandler) {
|
||
authGroup := v1.Group("/auth")
|
||
{
|
||
authGroup.POST("/register", h.Register)
|
||
authGroup.POST("/login", h.Login)
|
||
authGroup.POST("/send-code", h.SendVerificationCode)
|
||
authGroup.POST("/reset-password", h.ResetPassword)
|
||
}
|
||
}
|
||
|
||
// registerUserRoutes 注册用户路由
|
||
func registerUserRoutes(v1 *gin.RouterGroup, h *UserHandler) {
|
||
userGroup := v1.Group("/user")
|
||
userGroup.Use(middleware.AuthMiddleware())
|
||
{
|
||
userGroup.GET("/profile", h.GetProfile)
|
||
userGroup.PUT("/profile", h.UpdateProfile)
|
||
|
||
// 头像相关
|
||
userGroup.POST("/avatar/upload-url", h.GenerateAvatarUploadURL)
|
||
userGroup.PUT("/avatar", h.UpdateAvatar)
|
||
|
||
// 更换邮箱
|
||
userGroup.POST("/change-email", h.ChangeEmail)
|
||
|
||
// Yggdrasil密码相关
|
||
userGroup.POST("/yggdrasil-password/reset", h.ResetYggdrasilPassword)
|
||
}
|
||
}
|
||
|
||
// registerTextureRoutes 注册材质路由
|
||
func registerTextureRoutes(v1 *gin.RouterGroup, h *TextureHandler) {
|
||
textureGroup := v1.Group("/texture")
|
||
{
|
||
// 公开路由(无需认证)
|
||
textureGroup.GET("", h.Search)
|
||
textureGroup.GET("/:id", h.Get)
|
||
|
||
// 需要认证的路由
|
||
textureAuth := textureGroup.Group("")
|
||
textureAuth.Use(middleware.AuthMiddleware())
|
||
{
|
||
textureAuth.POST("/upload-url", h.GenerateUploadURL)
|
||
textureAuth.POST("", h.Create)
|
||
textureAuth.PUT("/:id", h.Update)
|
||
textureAuth.DELETE("/:id", h.Delete)
|
||
textureAuth.POST("/:id/favorite", h.ToggleFavorite)
|
||
textureAuth.GET("/my", h.GetUserTextures)
|
||
textureAuth.GET("/favorites", h.GetUserFavorites)
|
||
}
|
||
}
|
||
}
|
||
|
||
// registerProfileRoutes 注册档案路由(保持原有方式,后续改造)
|
||
func registerProfileRoutes(v1 *gin.RouterGroup) {
|
||
profileGroup := v1.Group("/profile")
|
||
{
|
||
// 公开路由(无需认证)
|
||
profileGroup.GET("/:uuid", GetProfile)
|
||
|
||
// 需要认证的路由
|
||
profileAuth := profileGroup.Group("")
|
||
profileAuth.Use(middleware.AuthMiddleware())
|
||
{
|
||
profileAuth.POST("/", CreateProfile)
|
||
profileAuth.GET("/", GetProfiles)
|
||
profileAuth.PUT("/:uuid", UpdateProfile)
|
||
profileAuth.DELETE("/:uuid", DeleteProfile)
|
||
profileAuth.POST("/:uuid/activate", SetActiveProfile)
|
||
}
|
||
}
|
||
}
|
||
|
||
// registerCaptchaRoutes 注册验证码路由(保持原有方式)
|
||
func registerCaptchaRoutes(v1 *gin.RouterGroup) {
|
||
captchaGroup := v1.Group("/captcha")
|
||
{
|
||
captchaGroup.GET("/generate", Generate)
|
||
captchaGroup.POST("/verify", Verify)
|
||
}
|
||
}
|
||
|
||
// registerYggdrasilRoutes 注册Yggdrasil API路由(保持原有方式)
|
||
func registerYggdrasilRoutes(v1 *gin.RouterGroup) {
|
||
ygg := v1.Group("/yggdrasil")
|
||
{
|
||
ygg.GET("", GetMetaData)
|
||
ygg.POST("/minecraftservices/player/certificates", GetPlayerCertificates)
|
||
authserver := ygg.Group("/authserver")
|
||
{
|
||
authserver.POST("/authenticate", Authenticate)
|
||
authserver.POST("/validate", ValidToken)
|
||
authserver.POST("/refresh", RefreshToken)
|
||
authserver.POST("/invalidate", InvalidToken)
|
||
authserver.POST("/signout", SignOut)
|
||
}
|
||
sessionServer := ygg.Group("/sessionserver")
|
||
{
|
||
sessionServer.GET("/session/minecraft/profile/:uuid", GetProfileByUUID)
|
||
sessionServer.POST("/session/minecraft/join", JoinServer)
|
||
sessionServer.GET("/session/minecraft/hasJoined", HasJoinedServer)
|
||
}
|
||
api := ygg.Group("/api")
|
||
profiles := api.Group("/profiles")
|
||
{
|
||
profiles.POST("/minecraft", GetProfilesByName)
|
||
}
|
||
}
|
||
}
|
||
|
||
// registerSystemRoutes 注册系统路由
|
||
func registerSystemRoutes(v1 *gin.RouterGroup) {
|
||
system := v1.Group("/system")
|
||
{
|
||
system.GET("/config", func(c *gin.Context) {
|
||
// TODO: 实现从数据库读取系统配置
|
||
c.JSON(200, model.NewSuccessResponse(gin.H{
|
||
"site_name": "CarrotSkin",
|
||
"site_description": "A Minecraft Skin Station",
|
||
"registration_enabled": true,
|
||
"max_textures_per_user": 100,
|
||
"max_profiles_per_user": 5,
|
||
}))
|
||
})
|
||
}
|
||
}
|
||
|