admin_user.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. package service
  2. import (
  3. "context"
  4. "entrance-grpc/iam"
  5. "errors"
  6. "gadmin/config"
  7. "gadmin/internal/admin/consts"
  8. "gadmin/internal/admin/forms"
  9. "gadmin/internal/gorm/model"
  10. "gadmin/utility/serializer"
  11. "time"
  12. "golang.org/x/crypto/bcrypt"
  13. )
  14. // User 管理员服务
  15. var User = NewsUser()
  16. type LoginStats struct {
  17. FailNum int
  18. BanTs int64
  19. }
  20. type sUser struct {
  21. BanIps map[string]*LoginStats
  22. }
  23. func NewsUser() *sUser {
  24. user := new(sUser)
  25. user.BanIps = make(map[string]*LoginStats)
  26. return user
  27. }
  28. // 一次登录,清空错误次数
  29. func (s *sUser) AddSucessNum(ip string) {
  30. delete(s.BanIps, ip)
  31. }
  32. // 增加错误登录次数,超过10次,不再进行密码验证
  33. func (s *sUser) AddFailNum(ip string) {
  34. stats, ok := s.BanIps[ip]
  35. if !ok {
  36. stats = new(LoginStats)
  37. s.BanIps[ip] = stats
  38. }
  39. if stats.BanTs > 0 {
  40. return
  41. }
  42. if stats.FailNum > 10 {
  43. curTs := time.Now().Unix()
  44. stats.BanTs = curTs
  45. // 清理错误登录
  46. for k, v := range s.BanIps {
  47. if v.BanTs+24*60*60 < curTs {
  48. delete(s.BanIps, k)
  49. }
  50. }
  51. return
  52. }
  53. stats.FailNum += 1
  54. }
  55. // 检查是否允许登录
  56. func (s *sUser) CheckLoginAllow(ip string) bool {
  57. stats, ok := s.BanIps[ip]
  58. if !ok {
  59. return true
  60. }
  61. cur := time.Now().Unix()
  62. if stats.BanTs+1*60*60 > cur {
  63. return false
  64. }
  65. stats.BanTs = 0
  66. stats.FailNum = 0
  67. return true
  68. }
  69. // GetUser 用ID获取用户
  70. func (s *sUser) GetUser(ID interface{}) (u *model.AdminUser, err error) {
  71. res, err := config.GetIamClient().GetAdminUserByID(context.Background(), &iam.GetAdminUserByIDReq{
  72. UID: ID.(int64),
  73. })
  74. u = new(model.AdminUser)
  75. if err == nil && res.Data != nil {
  76. u.ID = res.Data.ID
  77. u.RoleID = int32(res.Data.RoleID)
  78. u.Status = int32(res.Data.Status)
  79. u.UserName = res.Data.UserName
  80. u.Nickname = res.Data.NickName
  81. u.Avatar = res.Data.Avatar
  82. } else {
  83. err = errors.New("获取用户信息失败")
  84. }
  85. return
  86. //result := config.DB.First(&u, ID)
  87. //return u, result.Error
  88. }
  89. // SetPassword 设置密码
  90. func (s *sUser) SetPassword(password string) (string, error) {
  91. bytes, err := bcrypt.GenerateFromPassword([]byte(password), consts.PassWordCost)
  92. if err != nil {
  93. return "", err
  94. }
  95. return string(bytes), nil
  96. }
  97. // CheckPassword 校验密码
  98. func (s *sUser) CheckPasswordRight(passwordDigest, password string) bool {
  99. err := bcrypt.CompareHashAndPassword([]byte(passwordDigest), []byte(password))
  100. return err == nil
  101. }
  102. //func (s *sUser) Login(req forms.UserLoginReq, ip string) serializer.Response {
  103. // var (
  104. // u model.AdminUser
  105. // )
  106. // if ok := s.CheckLoginAllow(ip); !ok {
  107. // return serializer.ParamErr("账号已被禁止登录", nil)
  108. // }
  109. //
  110. // if err := config.AdminDB.Where("user_name = ?", req.UserName).First(&u).Error; err != nil {
  111. // s.AddFailNum(ip)
  112. // logrus.Warnf("sUser %v Login req error %v.", req.UserName, ip)
  113. // return serializer.ParamErr("账号错误或不存在,请检查", nil)
  114. // }
  115. // //p, _ := s.SetPassword(req.Password)
  116. // //fmt.Println("pass:", p)
  117. //
  118. // if u.Status != 1 {
  119. // return serializer.ParamErr("账号已被禁用", nil)
  120. // }
  121. //
  122. // if s.CheckPasswordRight(u.PasswordDigest, req.Password) == false {
  123. // s.AddFailNum(ip)
  124. // logrus.Warnf("sUser %v Login req error. ip: %v.", req.UserName, ip)
  125. // return serializer.ParamErr("密码不正确,如忘记了密码请联系管理员!", nil)
  126. // }
  127. // s.AddSucessNum(ip)
  128. //
  129. // //if os.Getenv("GIN_MODE") == "release" && u.UserName == "mojun" {
  130. // // return serializer.ParamErr("该账号只允许在测试服登录!", nil)
  131. // //}
  132. //
  133. // t := token.GenerateTokenUsingUUID()
  134. //
  135. // // 记录登录token
  136. // key := config.GetUserTokenKey(u.ID)
  137. // config.TokenRedis.HSet(key, t, time.Now().Unix())
  138. // config.TokenRedis.Expire(key, config.TokenExpireTime)
  139. //
  140. // tokenKey := config.GetTokenKey(t)
  141. // user := &token.UserClaims{
  142. // ID: u.ID,
  143. // UserName: u.UserName,
  144. // RoleId: int64(u.RoleID),
  145. // Avatar: u.Avatar,
  146. // Nickname: u.Nickname,
  147. // AccessToken: t,
  148. // }
  149. // userStr, err := jsoniter.MarshalToString(user)
  150. // if err != nil {
  151. // return serializer.Err(1, "", err)
  152. // }
  153. // config.TokenRedis.Set(tokenKey, userStr, config.TokenExpireTime)
  154. //
  155. // return serializer.Suc(forms.UserLoginRes{
  156. // ID: u.ID,
  157. // UserName: u.UserName,
  158. // Nickname: u.Nickname,
  159. // Status: u.Status,
  160. // Avatar: u.Avatar,
  161. // Token: base64.URLEncoding.EncodeToString([]byte(t)),
  162. // })
  163. //
  164. // //t, err := token.GenerateToken(&token.UserClaims{
  165. // // ID: u.ID,
  166. // // UserName: u.UserName,
  167. // // RoleId: int64(u.RoleID),
  168. // // Avatar: u.Avatar,
  169. // // Nickname: u.Nickname,
  170. // //})
  171. // //if err != nil {
  172. // // return serializer.ParamErr(err.Error(), nil)
  173. // //}
  174. // //return serializer.Suc(forms.UserLoginRes{
  175. // // ID: u.ID,
  176. // // UserName: u.UserName,
  177. // // Nickname: u.Nickname,
  178. // // Status: u.Status,
  179. // // Avatar: u.Avatar,
  180. // // Token: t,
  181. // //})
  182. //}
  183. func (s *sUser) Register(req forms.UserRegisterReq) serializer.Response {
  184. user := model.AdminUser{
  185. Nickname: req.Nickname,
  186. UserName: req.UserName,
  187. Status: consts.StatusNormal,
  188. }
  189. count := int64(0)
  190. config.DB.Model(&model.AdminUser{}).Where("nickname = ?", req.Nickname).Count(&count)
  191. if count > 0 {
  192. return serializer.Response{
  193. Code: 40001,
  194. Msg: "昵称被占用",
  195. }
  196. }
  197. config.DB.Model(&model.AdminUser{}).Where("user_name = ?", req.UserName).Count(&count)
  198. if count > 0 {
  199. return serializer.Response{
  200. Code: 40001,
  201. Msg: "用户名已经注册",
  202. }
  203. }
  204. // 加密密码
  205. password, err := s.SetPassword(req.Password)
  206. if err != nil {
  207. return serializer.Err(
  208. consts.CodeEncryptError,
  209. "密码加密失败",
  210. err,
  211. )
  212. }
  213. user.PasswordDigest = password
  214. if err = config.DB.Create(&user).Error; err != nil {
  215. return serializer.ParamErr("注册失败", err)
  216. }
  217. user.PasswordDigest = ""
  218. return serializer.Suc(user)
  219. }
  220. //func (s *sUser) List(ctx *gin.Context, req forms.AdminUserListReq) serializer.Response {
  221. // var (
  222. // q = query.Use(config.AdminDB).AdminUser
  223. // r = query.Use(config.AdminDB).AdminRole
  224. // m = q.WithContext(ctx)
  225. // offset int64 = 0
  226. // models forms.UserAccountListRes
  227. // lists []*forms.AdminUserListModel
  228. // )
  229. //
  230. // m = m.Order(q.ID.Desc())
  231. //
  232. // req.Page, req.PerPage, offset = forms.CalculatePage(req.Page, req.PerPage)
  233. //
  234. // count, err := m.Count()
  235. // if err != nil {
  236. // return serializer.Err(consts.CodeParamErr, "查询出错 count", err)
  237. // }
  238. //
  239. // if count > 0 {
  240. // if err = m.Limit(int(req.PerPage)).Offset(int(offset)).Scan(&lists); err != nil {
  241. // return serializer.Err(consts.CodeParamErr, "查询出错 lists", err)
  242. // }
  243. // }
  244. //
  245. // for _, v := range lists {
  246. // role, err := r.WithContext(ctx).Where(r.ID.Eq(v.RoleID)).First()
  247. // v.RoleName = "未绑定角色"
  248. // if role != nil && err == nil {
  249. // v.RoleName = role.Name
  250. // }
  251. // }
  252. //
  253. // models.List = lists
  254. // models.Page = req.Page
  255. // models.PerPage = req.PerPage
  256. // models.PageCount = (count + req.PerPage - 1) / req.PerPage
  257. //
  258. // return serializer.Suc(models)
  259. //}
  260. //func (s *sUser) Edit(ctx *gin.Context, req forms.AdminUserEditReq) serializer.Response {
  261. // q := query.Use(config.AdminDB).AdminUser
  262. //
  263. // logrus.Warnf("sUser Edit req:%+v", req)
  264. //
  265. // if req.RoleID <= 0 {
  266. // return serializer.ParamErr("角色不能为空", nil)
  267. // }
  268. //
  269. // if req.UserName == "" {
  270. // return serializer.ParamErr("用户名不能为空", nil)
  271. // }
  272. //
  273. // // 修改
  274. // if req.ID > 0 {
  275. // update := &model.AdminUser{
  276. // UserName: req.UserName,
  277. // RoleID: int32(req.RoleID),
  278. // Nickname: req.Nickname,
  279. // Status: req.Status,
  280. // UpdatedAt: time.Now(),
  281. // }
  282. // _, err := q.WithContext(ctx).Where(q.ID.Eq(req.ID)).Updates(update)
  283. // if err != nil {
  284. // return serializer.Err(consts.CodeParamErr, "更新出错", err)
  285. // }
  286. // // 维护redis token
  287. // config.TokenRedis.Del(config.GetUserTokenKey(req.ID))
  288. // return serializer.Suc(nil)
  289. // }
  290. //
  291. // if req.Password == "" {
  292. // return serializer.ParamErr("密码不能为空", nil)
  293. // }
  294. //
  295. // // 加密密码
  296. // password, err := s.SetPassword(req.Password)
  297. // if err != nil {
  298. // return serializer.Err(
  299. // consts.CodeEncryptError,
  300. // "密码加密失败",
  301. // err,
  302. // )
  303. // }
  304. //
  305. // // 新增
  306. // create := &model.AdminUser{
  307. // UserName: req.UserName,
  308. // RoleID: int32(req.RoleID),
  309. // Nickname: req.Nickname,
  310. // PasswordDigest: password,
  311. // Status: req.Status,
  312. // UpdatedAt: time.Now(),
  313. // CreatedAt: time.Now(),
  314. // }
  315. //
  316. // if err = query.Use(config.AdminDB).AdminUser.WithContext(ctx).Create(create); err != nil {
  317. // return serializer.DBErr(err.Error(), err)
  318. // }
  319. //
  320. // return serializer.Suc(nil)
  321. //}
  322. //func (s *sUser) ResetPassword(ctx *gin.Context, req forms.AdminUserResetPasswordReq) serializer.Response {
  323. // q := query.Use(config.AdminDB).AdminUser
  324. //
  325. // logrus.Warnf("sUser ResetPassword req:%+v", req)
  326. //
  327. // if req.ID <= 0 {
  328. // return serializer.ParamErr("用于ID不能为空", nil)
  329. // }
  330. //
  331. // if req.Password == "" {
  332. // return serializer.ParamErr("密码不能为空", nil)
  333. // }
  334. //
  335. // // 加密密码
  336. // password, err := s.SetPassword(req.Password)
  337. // if err != nil {
  338. // return serializer.Err(
  339. // consts.CodeEncryptError,
  340. // "密码加密失败",
  341. // err,
  342. // )
  343. // }
  344. // update := &model.AdminUser{
  345. // PasswordDigest: password,
  346. // UpdatedAt: time.Now(),
  347. // }
  348. //
  349. // _, err = q.WithContext(ctx).Where(q.ID.Eq(req.ID)).Updates(update)
  350. // if err != nil {
  351. // return serializer.Err(consts.CodeParamErr, "更新出错", err)
  352. // }
  353. // // 维护redis token
  354. // config.TokenRedis.Del(config.GetUserTokenKey(req.ID))
  355. // return serializer.Suc(nil)
  356. //}
  357. //func (s *sUser) UpdatePassword(ctx *gin.Context, req forms.AdminUserUpdatePasswordReq) serializer.Response {
  358. // q := query.Use(config.AdminDB).AdminUser
  359. //
  360. // logrus.Warnf("sUser UpdatePassword req:%+v", req)
  361. //
  362. // userId := token.GetUID(ctx)
  363. // if userId <= 0 {
  364. // return serializer.ParamErr("用户信息获取失败", nil)
  365. // }
  366. //
  367. // models, err := q.WithContext(ctx).Where(q.ID.Eq(userId)).First()
  368. // if err != nil {
  369. // return serializer.ParamErr(err.Error(), err)
  370. // }
  371. //
  372. // if models == nil {
  373. // return serializer.ParamErr("用户不存在", nil)
  374. // }
  375. //
  376. // if !s.CheckPasswordRight(models.PasswordDigest, req.OldPassword) {
  377. // return serializer.ParamErr("老密码不正确", nil)
  378. // }
  379. //
  380. // // 加密密码
  381. // password, err := s.SetPassword(req.NewPassword)
  382. // if err != nil {
  383. // return serializer.Err(
  384. // consts.CodeEncryptError,
  385. // "密码加密失败",
  386. // err,
  387. // )
  388. // }
  389. // update := &model.AdminUser{
  390. // PasswordDigest: password,
  391. // UpdatedAt: time.Now(),
  392. // }
  393. //
  394. // _, err = q.WithContext(ctx).Where(q.ID.Eq(userId)).Updates(update)
  395. // if err != nil {
  396. // return serializer.Err(consts.CodeParamErr, "更新出错", err)
  397. // }
  398. //
  399. // // 修改token状态
  400. // config.TokenRedis.Del(config.GetUserTokenKey(userId))
  401. //
  402. // return serializer.Suc(nil)
  403. //}
  404. //func (s *sUser) GetUserInfo(c *gin.Context) (*model.AdminUser, error) {
  405. // q := query.Use(config.AdminDB).AdminUser
  406. //
  407. // userId := token.GetUID(c)
  408. // if userId <= 0 {
  409. // c.JSON(200, serializer.Err(consts.CodeNoPermission, "用户信息获取失败", nil))
  410. // c.Abort()
  411. // }
  412. //
  413. // return q.WithContext(c).Where(q.ID.Eq(userId)).First()
  414. //}
  415. //func (s *sUser) GetUserRoleId(c *gin.Context) int64 {
  416. // info, err := s.GetUserInfo(c)
  417. // if err != nil {
  418. // return 0
  419. // }
  420. //
  421. // if info == nil {
  422. // return 0
  423. // }
  424. //
  425. // return int64(info.RoleID)
  426. //}
  427. //func (s *sUser) GetUserByUnionID(unionID string) (*model.AdminUser, error) {
  428. // q := query.Use(config.AdminDB).AdminUser
  429. // return q.Where(q.FeishuUnionID.Eq(unionID)).First()
  430. //}