From e12954a0c949c8633237a5b1fcf14cd452b6f9b1 Mon Sep 17 00:00:00 2001 From: Kingcq <404291187@qq.com> Date: Sun, 28 Jun 2026 17:54:32 +0800 Subject: [PATCH] fix: bug --- dao/article.go | 4 +++- dao/document.go | 4 +++- dao/server.go | 1 + dao/user.go | 62 +++++++++++++++++++++++++++++++++++++++++++++++-- service/auth.go | 43 +++++++++++++++++++++++++++++----- service/user.go | 7 +++--- 6 files changed, 108 insertions(+), 13 deletions(-) diff --git a/dao/article.go b/dao/article.go index 5b0530d..6acf2a3 100644 --- a/dao/article.go +++ b/dao/article.go @@ -90,7 +90,9 @@ func GetArticleList(target string, page int, pageSize int, pin bool) ([]model.Ar func DeleteArticle(id string) error { db := database.GetArticleDatabase() - result := db.Where("id = ?", id).Delete(&model.Article{}) + result := db.Unscoped(). + Where("id = ?", id). + Delete(&model.Article{}) if result.Error != nil { return result.Error } diff --git a/dao/document.go b/dao/document.go index d0273b3..ed82ed2 100644 --- a/dao/document.go +++ b/dao/document.go @@ -109,7 +109,9 @@ func DeleteDocumentNode(id string) error { } if err := db.Transaction(func(tx *gorm.DB) error { - result := tx.Where("id IN ?", ids).Delete(&model.DocumentNode{}) + result := tx.Unscoped(). + Where("id IN ?", ids). + Delete(&model.DocumentNode{}) if result.Error != nil { return result.Error } diff --git a/dao/server.go b/dao/server.go index e9524d3..9cf4600 100644 --- a/dao/server.go +++ b/dao/server.go @@ -44,6 +44,7 @@ func UpdateServer(server model.Server) error { func DeleteServer(id string) error { result := database.GetServerDatabase(). + Unscoped(). Where("id = ?", id). Delete(&model.Server{}) diff --git a/dao/user.go b/dao/user.go index 617cb74..33c841f 100644 --- a/dao/user.go +++ b/dao/user.go @@ -3,11 +3,13 @@ package dao import ( "encoding/json" "errors" + "fmt" "log" "necore/config" "necore/database" "necore/model" "slices" + "strings" "time" "github.com/golang-jwt/jwt/v5" @@ -78,20 +80,63 @@ func GetUserByUsername(u string) (*model.User, error) { } func AddUserByUsername(username string, password string) error { + username = strings.TrimSpace(username) + + if username == "" { + return fmt.Errorf("username cannot be empty") + } + + if password == "" { + return fmt.Errorf("password cannot be empty") + } + hash, err := hashPassword(password) if err != nil { return err } + db := database.GetUserDatabase() + + var existingUser model.User + + err = db.Unscoped(). + Where("username = ?", username). + First(&existingUser).Error + + if err == nil { + if !existingUser.DeletedAt.Valid { + return fmt.Errorf("user already exists") + } + + // 这里不要新建用户,而是复活旧用户。 + // 关键点:token_version 必须递增,避免旧 JWT 在同名用户重建后重新有效。 + return db.Unscoped(). + Model(&existingUser). + Updates(map[string]any{ + "password": hash, + "group": `[]`, + "tags": `[]`, + "avatar": "", + "token_version": gorm.Expr("token_version + ?", 1), + "deleted_at": nil, + "updated_at": time.Now(), + }).Error + } + + if !errors.Is(err, gorm.ErrRecordNotFound) { + return err + } + user := model.User{ Username: username, Password: hash, Group: `[]`, Tags: `[]`, + Avatar: "", TokenVersion: 1, } - return database.GetUserDatabase().Create(&user).Error + return db.Create(&user).Error } func GetAllUsers() ([]model.User, error) { @@ -103,7 +148,20 @@ func GetAllUsers() ([]model.User, error) { func DeleteUserByUsername(username string) error { db := database.GetUserDatabase() - return db.Where(&model.User{Username: username}).Delete(&model.User{}).Error + + result := db. + Where("username = ?", username). + Delete(&model.User{}) + + if result.Error != nil { + return result.Error + } + + if result.RowsAffected == 0 { + return fmt.Errorf("user '%s' not found", username) + } + + return nil } func CheckUserPassword(input string, password string) bool { diff --git a/service/auth.go b/service/auth.go index 5f63701..83391d4 100644 --- a/service/auth.go +++ b/service/auth.go @@ -2,8 +2,11 @@ package service import ( "encoding/json" + "errors" + "fmt" "necore/dao" "necore/model" + "strings" "github.com/gofiber/fiber/v2" ) @@ -80,24 +83,52 @@ func Login(c *fiber.Ctx) error { // Register by admin func AddUser(c *fiber.Ctx) error { - // Check if user is admin currentUser := c.Locals("currentUser").(model.User) + if !dao.ContainsGroup(currentUser.Group, "admin") { - return c.Status(fiber.StatusForbidden).JSON(fiber.Map{"error": "Forbidden"}) + return c.Status(fiber.StatusForbidden).JSON(fiber.Map{ + "error": "Forbidden", + }) } - // Parse body type NewUser struct { Username string `json:"username"` Password string `json:"password"` } + user := new(NewUser) + if err := c.BodyParser(user); err != nil { - return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Review your input", "err": err}) + return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ + "error": "Review your input", + "err": err.Error(), + }) } - if err := dao.AddUserByUsername(user.Username, user.Password); err != nil { - return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()}) + username := strings.TrimSpace(user.Username) + + if username == "" { + return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ + "error": "Username cannot be empty", + }) + } + + if user.Password == "" { + return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ + "error": "Password cannot be empty", + }) + } + + if err := dao.AddUserByUsername(username, user.Password); err != nil { + if errors.Is(err, fmt.Errorf("user already exists")) { + return c.Status(fiber.StatusConflict).JSON(fiber.Map{ + "error": "Username already exists", + }) + } + + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": err.Error(), + }) } return c.JSON(fiber.Map{}) diff --git a/service/user.go b/service/user.go index 959492f..3b57166 100644 --- a/service/user.go +++ b/service/user.go @@ -4,13 +4,14 @@ import ( "encoding/json" "necore/dao" "necore/model" + "net/url" "slices" "github.com/gofiber/fiber/v2" ) func GetUserInfo(c *fiber.Ctx) error { - userId := c.Params("id") + userId, _ := url.PathUnescape(c.Params("id")) userModel, err := dao.GetUserByUsername(userId) if err != nil || userModel == nil { @@ -91,7 +92,7 @@ func DeleteUser(c *fiber.Ctx) error { return c.Status(fiber.StatusForbidden).JSON(fiber.Map{"error": "Forbidden"}) } - username := c.Params("id") + username, _ := url.PathUnescape(c.Params("id")) err := dao.UpdateUserPermissions(username) if err != nil { return c.Status(500).JSON(fiber.Map{"error": "Internal server error"}) @@ -189,7 +190,7 @@ func UpdateUserInfo(c *fiber.Ctx) error { } func GetUserAvatar(c *fiber.Ctx) error { - userId := c.Params("id") + userId, _ := url.PathUnescape(c.Params("id")) avatar, err := dao.GetUserAvatar(userId) if err != nil {