b_login.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. package internal
  2. import (
  3. "context"
  4. "strings"
  5. "yx-dataset-server/app/bll"
  6. "yx-dataset-server/app/errors"
  7. "yx-dataset-server/app/model"
  8. "yx-dataset-server/app/schema"
  9. "yx-dataset-server/library/auth"
  10. "yx-dataset-server/library/utils"
  11. "github.com/LyricTian/captcha"
  12. "net/http"
  13. )
  14. // NewLogin 创建Login
  15. func NewLogin(
  16. Auth auth.Auther,
  17. user model.IUser,
  18. verifyCode bll.IVerifyCode,
  19. mTransModel model.ITrans,
  20. mLoginHis model.ILoginHistory,
  21. ) *Login {
  22. return &Login{
  23. auth: Auth,
  24. userModel: user,
  25. verifyCodeBll: verifyCode,
  26. transModel: mTransModel,
  27. loginHisModel: mLoginHis,
  28. }
  29. }
  30. // Login 创建Login对象
  31. type Login struct {
  32. auth auth.Auther
  33. userModel model.IUser
  34. verifyCodeBll bll.IVerifyCode
  35. transModel model.ITrans
  36. loginHisModel model.ILoginHistory
  37. }
  38. // GetCaptchaID 获取图形验证码信息
  39. func (a *Login) GetCaptchaID(ctx context.Context, length int) (*schema.LoginCaptcha, error) {
  40. captchaID := captcha.NewLen(length)
  41. item := &schema.LoginCaptcha{
  42. CaptchaID: captchaID,
  43. }
  44. return item, nil
  45. }
  46. // ResCaptcha 生成并响应图形验证码
  47. func (a *Login) ResCaptcha(ctx context.Context, w http.ResponseWriter, captchaID string, width, height int) error {
  48. err := captcha.WriteImage(w, captchaID, width, height)
  49. if err != nil {
  50. return err
  51. }
  52. w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
  53. w.Header().Set("Pragma", "no-cache")
  54. w.Header().Set("Expires", "0")
  55. w.Header().Set("Content-Type", "image/png")
  56. return nil
  57. }
  58. // GenerateToken 生成令牌
  59. func (a *Login) GenerateToken(ctx context.Context, userID string) (*schema.LoginTokenInfo, error) {
  60. tokenInfo, err := a.auth.GenerateToken(userID)
  61. if err != nil {
  62. return nil, errors.New400Response("生成令牌发生错误")
  63. }
  64. item := &schema.LoginTokenInfo{
  65. AccessToken: tokenInfo.GetAccessToken(),
  66. TokenType: tokenInfo.GetTokenType(),
  67. ExpiresAt: tokenInfo.GetExpiresAt(),
  68. }
  69. return item, nil
  70. }
  71. // DestroyToken 销毁令牌
  72. func (a *Login) DestroyToken(ctx context.Context, tokenString string) error {
  73. err := a.auth.DestroyToken(tokenString)
  74. if err != nil {
  75. return errors.WithStack(err)
  76. }
  77. return nil
  78. }
  79. // RefreshToken 刷新令牌
  80. func (a *Login) RefreshToken(ctx context.Context) (*schema.LoginTokenInfo, error) {
  81. userid := GetUserID(ctx)
  82. if userid == "" {
  83. return nil, errors.ErrInvalidToken
  84. }
  85. token, err := a.GenerateToken(ctx, userid)
  86. if err != nil {
  87. return nil, errors.New400Response("刷新令牌发生错误")
  88. }
  89. return token, nil
  90. }
  91. // Verify 登录验证
  92. func (a *Login) Verify(ctx context.Context, userName, password string) (*schema.User, error) {
  93. // 检查是否是超级用户
  94. root := GetRootUser()
  95. if userName == root.UserName && root.Password == password {
  96. return root, nil
  97. }
  98. result, err := a.userModel.Query(ctx, schema.UserQueryParam{
  99. UserName: userName,
  100. })
  101. if err != nil {
  102. return nil, err
  103. } else if len(result.Data) == 0 {
  104. return nil, errors.ErrInvalidUserName
  105. }
  106. item := result.Data[0]
  107. if item.Password != utils.SHA1HashString(strings.ToUpper(password)) {
  108. return nil, errors.ErrInvalidPassword
  109. } else if !item.Status {
  110. return nil, errors.ErrInvalidUser
  111. }
  112. return item, nil
  113. }
  114. // GetUserInfo 获取当前用户登录信息
  115. func (a *Login) GetUserInfo(ctx context.Context) (*schema.UserLoginInfo, error) {
  116. userID := GetUserID(ctx)
  117. if isRoot := CheckIsRootUser(ctx); isRoot {
  118. root := GetRootUser()
  119. loginInfo := &schema.UserLoginInfo{
  120. UserName: root.UserName,
  121. RealName: root.RealName,
  122. Photo: root.Photo,
  123. }
  124. return loginInfo, nil
  125. }
  126. user, err := a.userModel.Get(ctx, userID)
  127. if err != nil {
  128. return nil, err
  129. } else if user == nil {
  130. return nil, errors.ErrInvalidUser
  131. } else if user.Status {
  132. return nil, errors.ErrUserDisable
  133. }
  134. loginInfo := &schema.UserLoginInfo{
  135. UserName: user.UserName,
  136. RealName: user.RealName,
  137. }
  138. return loginInfo, nil
  139. }
  140. func (a *Login) getAndCheckUser(ctx context.Context, userID string, opts ...schema.UserOptions) (*schema.User, error) {
  141. user, err := a.userModel.Get(ctx, userID, opts...)
  142. if err != nil {
  143. return nil, err
  144. } else if user == nil {
  145. return nil, errors.ErrInvalidUser
  146. } else if user.Status {
  147. return nil, errors.ErrUserDisable
  148. }
  149. return user, nil
  150. }
  151. // UpdatePassword 更新当前用户登录密码
  152. func (a *Login) UpdatePassword(ctx context.Context, params schema.UpdatePasswordParam) error {
  153. userID := GetUserID(ctx)
  154. if CheckIsRootUser(ctx) {
  155. return errors.New400Response("超级管理员密码只能通过配置文件修改")
  156. }
  157. if params.OldPassword == "" {
  158. return errors.ErrUserNotEmptyPwd
  159. }
  160. user, err := a.getAndCheckUser(ctx, userID)
  161. if err != nil {
  162. return err
  163. } else if utils.SHA1HashString(strings.ToUpper(params.OldPassword)) != user.Password {
  164. return errors.ErrLoginInvalidOldPwd
  165. }
  166. params.NewPassword = utils.SHA1HashString(strings.ToUpper(params.NewPassword))
  167. return a.userModel.UpdatePassword(ctx, userID, params.NewPassword)
  168. }
  169. // Unsubscribe 用户注销
  170. func (a *Login) Unsubscribe(ctx context.Context, userId, tokenStr string) error {
  171. err := ExecTrans(ctx, a.transModel, func(ctx context.Context) error {
  172. err := a.userModel.Delete(ctx, userId)
  173. if err != nil {
  174. return err
  175. }
  176. return a.DestroyToken(ctx, tokenStr)
  177. })
  178. return err
  179. }
  180. // LoginBySms 通过短信验证码登录
  181. func (a *Login) LoginBySms(ctx context.Context, params schema.SmsLoginParam) error {
  182. checkResult, err := a.verifyCodeBll.Check(ctx, schema.VerifyCodeCheck{
  183. Tel: params.Phone,
  184. BusinessType: params.BusinessType,
  185. Code: params.Code,
  186. })
  187. if err != nil {
  188. return err
  189. }
  190. if !checkResult {
  191. return errors.ErrSmsCode
  192. }
  193. return nil
  194. }