package service import ( "errors" "time" "github.com/gin-gonic/gin" "hy2xs-admin/dao" "hy2xs-admin/model/bo" "hy2xs-admin/model/constant" "hy2xs-admin/model/entity" "hy2xs-admin/model/vo" "hy2xs-admin/util" ) func adminClaimsFromContext(c *gin.Context) (bo.AccountBo, bool) { if c == nil { return bo.AccountBo{}, false } v, ok := c.Get("adminClaims") if !ok { return bo.AccountBo{}, false } claims, castOK := v.(bo.AccountBo) return claims, castOK } func Login(username string, plainPassword string) (string, bool, error) { admin, err := dao.GetAdminUser("username = ? and status = 1", username) if err != nil { return "", false, err } verified, legacy := util.VerifyPassword(plainPassword, *admin.PasswordHash) if !verified { return "", false, errors.New(constant.WrongPassword) } if legacy { hash, hashErr := util.HashPassword(plainPassword) if hashErr == nil { _ = dao.UpdateAdminUser([]int64{*admin.Id}, map[string]interface{}{"password_hash": hash}) } } tokenVersion := int64(1) if admin.TokenVersion != nil && *admin.TokenVersion > 0 { tokenVersion = *admin.TokenVersion } accountBo := bo.AccountBo{Id: *admin.Id, Username: *admin.Username, Roles: []string{"admin"}, Deleted: 0, TokenVersion: tokenVersion} token, tokenErr := GenToken(accountBo) if tokenErr != nil { return "", false, tokenErr } requirePasswordChange := legacy if admin.ForcePasswordChange != nil { requirePasswordChange = *admin.ForcePasswordChange != 0 } return token, requirePasswordChange, nil } func GetAdminInfo(c *gin.Context) (vo.AdminInfoVo, error) { claims, ok := adminClaimsFromContext(c) if !ok { myClaims, err := ParseToken(GetToken(c)) if err != nil { return vo.AdminInfoVo{}, err } claims = myClaims.Admin } admin, err := dao.GetAdminUser("id = ?", claims.Id) if err != nil { return vo.AdminInfoVo{}, err } if admin.Status != nil && *admin.Status == 0 { return vo.AdminInfoVo{}, errors.New("this account has been disabled") } force := admin.ForcePasswordChange != nil && *admin.ForcePasswordChange != 0 return vo.AdminInfoVo{Id: claims.Id, Username: claims.Username, Roles: claims.Roles, ForcePasswordChange: force}, nil } func UpdateAdminLastLoginAt(id int64, loginAt int64) error { return dao.UpdateAdminUser([]int64{id}, map[string]interface{}{"last_login_at": loginAt}) } func ChangeAdminPassword(c *gin.Context, oldPassword string, newPassword string) error { info, err := GetAdminInfo(c) if err != nil { return err } admin, err := dao.GetAdminUser("id = ?", info.Id) if err != nil { return err } if admin.PasswordHash == nil { return errors.New(constant.SysError) } verified, _ := util.VerifyPassword(oldPassword, *admin.PasswordHash) if !verified { return errors.New(constant.WrongPassword) } hash, hashErr := util.HashPassword(newPassword) if hashErr != nil { return hashErr } nowMs := time.Now().UnixMilli() currentTokenVersion := int64(1) if admin.TokenVersion != nil && *admin.TokenVersion > 0 { currentTokenVersion = *admin.TokenVersion } return dao.UpdateAdminUser([]int64{info.Id}, map[string]interface{}{ "password_hash": hash, "force_password_change": 0, "password_changed_at": nowMs, "token_version": currentTokenVersion + 1, }) } func GetAdminForTokenValidation(id int64) (entity.AdminUser, error) { return dao.GetAdminUser("id = ?", id) }