fix: 修复帖子相关逻辑的严重安全与错误处理问题

- 修复 Service 层所有 FindByID 错误均返回 ErrUserNotFound 的严重 bug,新增 findPost/findPostWithAuthor 正确区分 gorm.ErrRecordNotFound 和数据库错误
- 新增帖子相关错误哨兵:ErrPostNotFound/ErrPostCannotEdit/ErrPostCannotSubmit/ErrPostCannotApprove/ErrPostCannotReject/ErrPostCannotUnlock
- 修复 ShowAPI 缺少权限控制,非 approved 帖子可被任意用户通过 API 获取
- 修复 EditPage 缺少权限检查,非作者可访问编辑页面
- 修复 Update/Delete API 中 uid 断言未做 ok 检查
- Controller 层区分业务错误和内部错误,避免透传 Service 层错误信息给客户端
- 将 postStore 接口从 post_service.go 移至 repository.go,与其他仓储接口保持一致
- 移除 new.html 中孤立的 </template> 标签
This commit is contained in:
2026-05-28 14:44:22 +08:00
parent 36b18c0ffe
commit e45d66fb77
6 changed files with 141 additions and 47 deletions

View File

@ -1,6 +1,7 @@
package admin
import (
"errors"
"net/http"
"strconv"
@ -72,7 +73,11 @@ func (ctrl *AdminPostController) Approve(c *gin.Context) {
}
if err := ctrl.postService.Approve(uint(id)); err != nil {
common.Error(c, http.StatusBadRequest, err.Error())
if errors.Is(err, common.ErrPostCannotApprove) || errors.Is(err, common.ErrPostNotFound) {
common.Error(c, http.StatusBadRequest, err.Error())
} else {
common.Error(c, http.StatusInternalServerError, "审核失败")
}
return
}
@ -94,7 +99,11 @@ func (ctrl *AdminPostController) Reject(c *gin.Context) {
}
if err := ctrl.postService.Reject(uint(id), req.Reason); err != nil {
common.Error(c, http.StatusBadRequest, err.Error())
if errors.Is(err, common.ErrPostCannotReject) || errors.Is(err, common.ErrPostNotFound) {
common.Error(c, http.StatusBadRequest, err.Error())
} else {
common.Error(c, http.StatusInternalServerError, "退回失败")
}
return
}
@ -110,7 +119,11 @@ func (ctrl *AdminPostController) Lock(c *gin.Context) {
}
if err := ctrl.postService.Lock(uint(id)); err != nil {
common.Error(c, http.StatusBadRequest, err.Error())
if errors.Is(err, common.ErrPostNotFound) {
common.Error(c, http.StatusBadRequest, err.Error())
} else {
common.Error(c, http.StatusInternalServerError, "锁定失败")
}
return
}
@ -126,7 +139,11 @@ func (ctrl *AdminPostController) Unlock(c *gin.Context) {
}
if err := ctrl.postService.Unlock(uint(id)); err != nil {
common.Error(c, http.StatusBadRequest, err.Error())
if errors.Is(err, common.ErrPostCannotUnlock) || errors.Is(err, common.ErrPostNotFound) {
common.Error(c, http.StatusBadRequest, err.Error())
} else {
common.Error(c, http.StatusInternalServerError, "解锁失败")
}
return
}
@ -142,7 +159,7 @@ func (ctrl *AdminPostController) Restore(c *gin.Context) {
}
if err := ctrl.postService.Restore(uint(id)); err != nil {
common.Error(c, http.StatusBadRequest, err.Error())
common.Error(c, http.StatusInternalServerError, "恢复失败")
return
}