Skip to content

Commit 250cf6d

Browse files
committed
重构:统一认证架构并修复下载权限问题
主要改进: 1. 创建统一的AuthService,整合所有认证逻辑 - 统一密码策略、验证、哈希处理 - 集中用户注册、登录、密码修改逻辑 - 统一JWT令牌管理和会话控制 2. 重构UserService和AdminService - 将认证操作委托给AuthService - 消除重复的密码处理代码 - 简化验证逻辑 3. 修复文件下载权限问题 - 修复匿名上传但设置认证要求的文件访问问题 - 保持用户上传需要认证文件的安全性 - 提供更好的兼容性处理 4. 更新用户管理统计数据 - 添加用户相关统计信息到GetStats方法 - 修复前端用户管理页面显示null的问题 5. 其他优化 - 更新中间件类型引用 - 修复编译错误和方法签名不匹配 - 添加缺失的管理员服务方法
1 parent ccd014b commit 250cf6d

File tree

21 files changed

+1758
-552
lines changed

21 files changed

+1758
-552
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ data/
2424
# 临时文件
2525
*.tmp
2626
*.temp
27+
*.bin
2728

2829
# IDE和编辑器文件
2930
.vscode/
File renamed without changes.

internal/handlers/admin.go

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,13 @@ func (h *AdminHandler) GetFiles(c *gin.Context) {
108108

109109
// DeleteFile 删除文件
110110
func (h *AdminHandler) DeleteFile(c *gin.Context) {
111-
idStr := c.Param("id")
112-
id64, err := strconv.ParseUint(idStr, 10, 32)
113-
if err != nil {
114-
common.BadRequestResponse(c, "文件ID错误")
111+
code := c.Param("code")
112+
if code == "" {
113+
common.BadRequestResponse(c, "文件代码不能为空")
115114
return
116115
}
117116

118-
err = h.service.DeleteFile(uint(id64))
117+
err := h.service.DeleteFileByCode(code)
119118
if err != nil {
120119
common.InternalServerErrorResponse(c, "删除失败: "+err.Error())
121120
return
@@ -126,14 +125,13 @@ func (h *AdminHandler) DeleteFile(c *gin.Context) {
126125

127126
// GetFile 获取单个文件信息
128127
func (h *AdminHandler) GetFile(c *gin.Context) {
129-
idStr := c.Param("id")
130-
id64, err := strconv.ParseUint(idStr, 10, 32)
131-
if err != nil {
132-
common.BadRequestResponse(c, "文件ID错误")
128+
code := c.Param("code")
129+
if code == "" {
130+
common.BadRequestResponse(c, "文件代码不能为空")
133131
return
134132
}
135133

136-
fileCode, err := h.service.GetFileByID(uint(id64))
134+
fileCode, err := h.service.GetFileByCode(code)
137135
if err != nil {
138136
common.NotFoundResponse(c, "文件不存在")
139137
return
@@ -183,11 +181,10 @@ func (h *AdminHandler) CleanExpiredFiles(c *gin.Context) {
183181

184182
// UpdateFile 更新文件信息
185183
func (h *AdminHandler) UpdateFile(c *gin.Context) {
186-
// 从URL参数获取ID
187-
idStr := c.Param("id")
188-
id64, err := strconv.ParseUint(idStr, 10, 32)
189-
if err != nil {
190-
common.BadRequestResponse(c, "文件ID错误")
184+
// 从URL参数获取code
185+
code := c.Param("code")
186+
if code == "" {
187+
common.BadRequestResponse(c, "文件代码不能为空")
191188
return
192189
}
193190

@@ -204,7 +201,7 @@ func (h *AdminHandler) UpdateFile(c *gin.Context) {
204201
}
205202

206203
// 获取现有文件信息
207-
fileCode, err := h.service.GetFileByID(uint(id64))
204+
_, err := h.service.GetFileByCode(code)
208205
if err != nil {
209206
common.NotFoundResponse(c, "文件不存在")
210207
return
@@ -216,8 +213,12 @@ func (h *AdminHandler) UpdateFile(c *gin.Context) {
216213
expiredAt = updateData.ExpiredAt
217214
}
218215

219-
// 保存更新 - 使用现有的UpdateFile方法
220-
err = h.service.UpdateFile(uint(id64), updateData.Code, fileCode.Prefix, fileCode.Suffix, expiredAt, updateData.ExpiredCount)
216+
// 保存更新 - 使用UpdateFileByCode方法
217+
var expTime time.Time
218+
if expiredAt != nil {
219+
expTime = *expiredAt
220+
}
221+
err = h.service.UpdateFileByCode(code, updateData.Code, "", expTime)
221222
if err != nil {
222223
common.InternalServerErrorResponse(c, "更新失败: "+err.Error())
223224
return
@@ -228,35 +229,39 @@ func (h *AdminHandler) UpdateFile(c *gin.Context) {
228229

229230
// DownloadFile 下载文件(管理员)
230231
func (h *AdminHandler) DownloadFile(c *gin.Context) {
231-
idStr := c.Query("id")
232-
id64, err := strconv.ParseUint(idStr, 10, 32)
233-
if err != nil {
234-
common.BadRequestResponse(c, "文件ID错误")
232+
code := c.Query("code")
233+
if code == "" {
234+
common.BadRequestResponse(c, "文件代码不能为空")
235235
return
236236
}
237237

238-
fileCode, err := h.service.GetFileByID(uint(id64))
238+
fileCode, err := h.service.GetFileByCode(code)
239239
if err != nil {
240240
common.NotFoundResponse(c, "文件不存在")
241241
return
242242
}
243243

244244
if fileCode.Text != "" {
245245
// 文本内容
246-
common.SuccessResponse(c, fileCode.Text)
246+
fileName := fileCode.Prefix + ".txt"
247+
c.Header("Content-Disposition", "attachment; filename=\""+fileName+"\"")
248+
c.Header("Content-Type", "text/plain")
249+
c.String(200, fileCode.Text)
247250
return
248251
}
249252

250-
// 文件下载
253+
// 文件下载 - 通过存储管理器
251254
filePath := fileCode.GetFilePath()
252255
if filePath == "" {
253256
common.NotFoundResponse(c, "文件路径为空")
254257
return
255258
}
256259

257-
fileName := fileCode.Prefix + fileCode.Suffix
258-
c.Header("Content-Disposition", "attachment; filename=\""+fileName+"\"")
259-
c.File(filePath)
260+
err = h.service.ServeFile(c, fileCode)
261+
if err != nil {
262+
common.InternalServerErrorResponse(c, "文件下载失败: "+err.Error())
263+
return
264+
}
260265
}
261266

262267
// ========== 用户管理相关方法 ==========
@@ -347,7 +352,7 @@ func (h *AdminHandler) getUsersFromDB(page, pageSize int, search string) ([]gin.
347352

348353
// getUserStats 获取用户统计信息
349354
func (h *AdminHandler) getUserStats() (gin.H, error) {
350-
stats, err := h.service.GetUserStats()
355+
stats, err := h.service.GetStats()
351356
if err != nil {
352357
return nil, err
353358
}
@@ -406,7 +411,7 @@ func (h *AdminHandler) CreateUser(c *gin.Context) {
406411
var userData struct {
407412
Username string `json:"username" binding:"required"`
408413
Email string `json:"email" binding:"required,email"`
409-
Password string `json:"password" binding:"required,min=6"`
414+
Password string `json:"password" binding:"required"`
410415
Nickname string `json:"nickname"`
411416
IsAdmin bool `json:"is_admin"`
412417
IsActive bool `json:"is_active"`
@@ -559,7 +564,10 @@ func (h *AdminHandler) GetUserFiles(c *gin.Context) {
559564
}
560565

561566
// 获取用户的文件列表
562-
files, err := h.service.GetUserFiles(userID)
567+
page := 1 // 默认第一页
568+
limit := 20 // 默认每页20条
569+
570+
files, total, err := h.service.GetUserFiles(userID, page, limit)
563571
if err != nil {
564572
common.InternalServerErrorResponse(c, "获取用户文件失败: "+err.Error())
565573
return
@@ -597,6 +605,6 @@ func (h *AdminHandler) GetUserFiles(c *gin.Context) {
597605
common.SuccessResponse(c, gin.H{
598606
"files": fileList,
599607
"username": user.Username,
600-
"total": len(fileList),
608+
"total": total,
601609
})
602610
}

internal/handlers/user.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -202,11 +202,6 @@ func (h *UserHandler) ChangePassword(c *gin.Context) {
202202
return
203203
}
204204

205-
if len(req.NewPassword) < 6 {
206-
common.BadRequestResponse(c, "新密码长度至少6个字符")
207-
return
208-
}
209-
210205
if err := h.userService.ChangePassword(userID.(uint), req.OldPassword, req.NewPassword); err != nil {
211206
common.BadRequestResponse(c, err.Error())
212207
return

internal/middleware/middleware.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ func UserAuth(cfg *config.Config, userService interface {
241241
}
242242

243243
// 类型断言获取claims
244-
if claims, ok := claimsInterface.(*services.UserClaims); ok {
244+
if claims, ok := claimsInterface.(*services.AuthClaims); ok {
245245
// 将用户信息设置到上下文
246246
c.Set("user_id", claims.UserID)
247247
c.Set("username", claims.Username)
@@ -300,7 +300,7 @@ func OptionalUserAuth(cfg *config.Config, userService interface {
300300
}
301301

302302
// 类型断言获取claims
303-
if claims, ok := claimsInterface.(*services.UserClaims); ok {
303+
if claims, ok := claimsInterface.(*services.AuthClaims); ok {
304304
// 将用户信息设置到上下文
305305
c.Set("user_id", claims.UserID)
306306
c.Set("username", claims.Username)

internal/routes/routes.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,9 @@ func SetupRoutes(
132132
authGroup.GET("/dashboard", adminHandler.Dashboard)
133133
authGroup.GET("/stats", adminHandler.GetStats)
134134
authGroup.GET("/files", adminHandler.GetFiles)
135-
authGroup.GET("/files/:id", adminHandler.GetFile)
136-
authGroup.DELETE("/files/:id", adminHandler.DeleteFile)
137-
authGroup.PUT("/files/:id", adminHandler.UpdateFile)
135+
authGroup.GET("/files/:code", adminHandler.GetFile)
136+
authGroup.DELETE("/files/:code", adminHandler.DeleteFile)
137+
authGroup.PUT("/files/:code", adminHandler.UpdateFile)
138138
authGroup.GET("/files/download", adminHandler.DownloadFile)
139139
authGroup.GET("/config", adminHandler.GetConfig)
140140
authGroup.PUT("/config", adminHandler.UpdateConfig)

0 commit comments

Comments
 (0)