users.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package model
  2. import (
  3. "crypto/hmac"
  4. "crypto/sha256"
  5. "errors"
  6. "fmt"
  7. "woord-core-service/global"
  8. "gorm.io/gorm"
  9. )
  10. var (
  11. ErrUserNotFound = fmt.Errorf("用户不存在")
  12. ErrUserNameAlreadyExists = fmt.Errorf("用户名已存在")
  13. ErrWrongUserNameOrPassword = fmt.Errorf("用户名或密码错误")
  14. )
  15. // 用户
  16. type User struct {
  17. *gorm.Model
  18. // 用户名
  19. Name string `gorm:"unique;index"`
  20. // 用户密码,保存为 HS256 散列值
  21. Password string
  22. // 用户所有词库
  23. Dicts []Dict
  24. }
  25. type UserResult struct {
  26. ID uint `json:"id"`
  27. Name string `json:"name"`
  28. }
  29. // 计算密码的 HS256 散列值
  30. func hashPassword(password string) string {
  31. mac := hmac.New(sha256.New, global.SecretKey)
  32. mac.Write([]byte(password))
  33. return fmt.Sprintf("%x", mac.Sum(nil))
  34. }
  35. // 获取用户
  36. func GetUser(id uint) (*UserResult, error) {
  37. result := &UserResult{}
  38. if err := global.DB.Model(&User{}).Take(result, "id = ?", id).Error; err != nil {
  39. if errors.Is(err, gorm.ErrRecordNotFound) {
  40. return nil, ErrUserNotFound
  41. }
  42. return nil, err
  43. }
  44. return result, nil
  45. }
  46. // 创建用户
  47. func CreateUser(name, password string) (*UserResult, error) {
  48. if err := global.DB.Model(&User{}).Take(&struct{ ID uint }{}, "name = ?", name).Error; !errors.Is(err, gorm.ErrRecordNotFound) {
  49. if err != nil {
  50. return nil, err
  51. }
  52. return nil, ErrUserNameAlreadyExists
  53. }
  54. password = hashPassword(password)
  55. user := &User{
  56. Name: name,
  57. Password: password,
  58. }
  59. if err := global.DB.Select("name", "password").Create(user).Error; err != nil {
  60. return nil, err
  61. }
  62. return &UserResult{
  63. ID: user.ID,
  64. Name: user.Name,
  65. }, nil
  66. }
  67. // 认证用户
  68. func AuthenticateUser(name, password string) (*UserResult, error) {
  69. password = hashPassword(password)
  70. result := &UserResult{}
  71. if err := global.DB.Model(&User{}).Take(result, "name = ? AND password = ?", name, password).Error; err != nil {
  72. if errors.Is(err, gorm.ErrRecordNotFound) {
  73. return nil, ErrWrongUserNameOrPassword
  74. }
  75. return nil, err
  76. }
  77. return result, nil
  78. }