Compare commits

...

7 Commits

Author SHA1 Message Date
Robin 85d8ed2b14 by Robin at 20241217 2024-12-17 16:53:23 +08:00
Robin 8ca149f002 by Robin at 20241217 2024-12-17 16:37:59 +08:00
Robin b866791055 1 2024-12-17 16:26:37 +08:00
Robin e2357aeac8 1 2024-12-17 14:01:22 +08:00
Robin 50e3e76698 by Robin at 20241217 2024-12-17 13:36:31 +08:00
Robin 2a4343553f 1 2024-12-16 13:39:46 +08:00
Robin 131bc242c1 by Robin at 20241216 2024-12-16 13:35:55 +08:00
11 changed files with 158 additions and 28 deletions

View File

@ -29,17 +29,18 @@ var ErrCodeMsgMap = map[ErrCode]string{
ErrCodeResourceSrvFail: "资源位服务错误",
ErrCodeResourceNotExist: "资源位不存在",
ErrCodeLoginSrvFail: "登录服务错误",
ErrCodeLoginNotExist: "登录信息不存在",
ErrCodeLoginWrongPswd: "登录密码错误",
ErrCodeLoginWrongVeriCode: "验证码错误",
ErrCodeLoginVeriCodeExpired: "验证码已过期",
ErrCodeLoginAcctLocked: "账户已锁定,请明日再试",
ErrCodeLoginAcctBanned: "登录账户已被封禁",
ErrCodeLoginAcctNotEnabled: "登录账户未设置密码,请使用验证码登录",
ErrCodeLoginNoChangeInAPswdReset: "新旧密码相同",
ErrCodeLoginRegisterUserFail: "账号注册失败,请稍后重试",
ErrCodeLoginWrongOldPswd: "旧密码错误",
ErrCodeLoginSrvFail: "登录服务错误",
ErrCodeLoginNotExist: "登录信息不存在",
ErrCodeLoginWrongPswd: "登录密码错误",
ErrCodeLoginWrongVeriCode: "验证码错误",
ErrCodeLoginVeriCodeExpired: "验证码已过期",
ErrCodeLoginAcctLocked: "账户已锁定,请明日再试",
ErrCodeLoginAcctBanned: "登录账户已被封禁",
ErrCodeLoginAcctNotEnabled: "登录账户未设置密码,请使用验证码登录",
ErrCodeLoginNoChangeInAPswdReset: "新旧密码相同",
ErrCodeLoginRegisterUserFail: "账号注册失败,请稍后重试",
ErrCodeLoginWrongOldPswd: "旧密码错误",
ErrCodeLoginMobilePhoneHasBeenRegistered: "该手机号已被注册",
ErrCodeAccountSrvFail: "账户服务错误",
ErrCodeAccountNotExist: "账户信息不存在",
@ -304,18 +305,19 @@ const (
ErrCodeBannerNotExist ErrCode = -4002 // banner不存在
// Login: 5xxx
ErrCodeLoginSrvOk ErrCode = ErrCodeOk
ErrCodeLoginSrvFail ErrCode = -5001 //登录服务错误
ErrCodeLoginNotExist ErrCode = -5002 //登录信息不存在
ErrCodeLoginWrongPswd ErrCode = -5003 //登录密码错误
ErrCodeLoginWrongVeriCode ErrCode = -5004 //验证码错误
ErrCodeLoginVeriCodeExpired ErrCode = -5005 //验证码已过期
ErrCodeLoginAcctLocked ErrCode = -5006 //登录账户尝试爆破登录,已被锁定
ErrCodeLoginAcctBanned ErrCode = -5007 //登录账户已被封禁
ErrCodeLoginAcctNotEnabled ErrCode = -5008 //登录账户未启用
ErrCodeLoginNoChangeInAPswdReset ErrCode = -5009 //新旧密码相同
ErrCodeLoginRegisterUserFail ErrCode = -5010 //注册账户失败
ErrCodeLoginWrongOldPswd ErrCode = -5011 //旧密码错误
ErrCodeLoginSrvOk ErrCode = ErrCodeOk
ErrCodeLoginSrvFail ErrCode = -5001 //登录服务错误
ErrCodeLoginNotExist ErrCode = -5002 //登录信息不存在
ErrCodeLoginWrongPswd ErrCode = -5003 //登录密码错误
ErrCodeLoginWrongVeriCode ErrCode = -5004 //验证码错误
ErrCodeLoginVeriCodeExpired ErrCode = -5005 //验证码已过期
ErrCodeLoginAcctLocked ErrCode = -5006 //登录账户尝试爆破登录,已被锁定
ErrCodeLoginAcctBanned ErrCode = -5007 //登录账户已被封禁
ErrCodeLoginAcctNotEnabled ErrCode = -5008 //登录账户未启用
ErrCodeLoginNoChangeInAPswdReset ErrCode = -5009 //新旧密码相同
ErrCodeLoginRegisterUserFail ErrCode = -5010 //注册账户失败
ErrCodeLoginWrongOldPswd ErrCode = -5011 //旧密码错误
ErrCodeLoginMobilePhoneHasBeenRegistered ErrCode = -5013 //手机号已被注册
// Account: 6xxx
ErrCodeAccountSrvOk ErrCode = ErrCodeOk

View File

@ -105,6 +105,7 @@ type OpGetMobilePhoneByUserIdReq struct {
type OpGetMobilePhoneByUserIdData struct {
MobilePhone string `json:"mobile_phone"`
*OpListOthersVO
}
type OpGetMobilePhoneByUserIdResp struct {

View File

@ -30,6 +30,10 @@ type OpListOthersVO struct {
Role *int64 `json:"role" bson:"role"` // 角色
}
func NewOpListOthersVO() *OpListOthersVO {
return &OpListOthersVO{}
}
func (vo *OpListVO) CopyAccount(account *dbstruct.Account) *OpListVO {
if account == nil {
return vo

View File

@ -182,3 +182,17 @@ type OpUpdateByMidResp struct {
base.BaseResponse
Data *OpUpdateByMidData `json:"data"`
}
// 更改手机号
type OpResetMobilePhoneReq struct {
base.BaseRequest
MobilePhoneInfoComponent `jcrypto:"true"`
NewMobilePhone string `json:"new_mobile_phone" jcrypto:"rsa"` // 用户手机号
}
type OpResetMobilePhoneData struct{}
type OpResetMobilePhoneResp struct {
base.BaseResponse
Data *OpResetPswdData `json:"data"`
}

View File

@ -101,7 +101,7 @@ func OpGetAccountListByUserId(ctx *gin.Context) {
func OpGetMobilePhoneByUserId(ctx *gin.Context) {
req := ctx.MustGet("client_req").(*accountproto.OpGetMobilePhoneByUserIdReq)
mobilePhone, ec := service.DefaultService.OpGetMobilePhoneByUserId(ctx, req)
mobilePhone, vo, ec := service.DefaultService.OpGetMobilePhoneByUserId(ctx, req)
if ec != errcode.ErrCodeAccountSrvOk {
logger.Error("OpGetMobilePhoneByUserId fail, req: %v, ec: %v", util.ToJson(req), ec)
ReplyErrCodeMsg(ctx, ec)
@ -109,7 +109,8 @@ func OpGetMobilePhoneByUserId(ctx *gin.Context) {
}
data := &accountproto.OpGetMobilePhoneByUserIdData{
MobilePhone: mobilePhone,
MobilePhone: mobilePhone,
OpListOthersVO: vo,
}
ReplyOk(ctx, data)

View File

@ -392,6 +392,7 @@ func Init(r *gin.Engine) {
opLoginGroup.POST("reset_password", middleware.JSONParamValidator(loginproto.OpResetPswdReq{}), middleware.RequestDecryptor(), OpResetPassword)
opLoginGroup.POST("update_password", middleware.JSONParamValidator(loginproto.OpUpdatePswdReq{}), middleware.JwtAuthenticator(), middleware.RequestDecryptor(), OpUpdatePassword)
opLoginGroup.POST("validate", middleware.JSONParamValidator(base.BaseRequest{}), middleware.JwtAuthenticator(), OpValidate)
opLoginGroup.POST("reset_mobile_phone", middleware.JSONParamValidator(loginproto.OpResetMobilePhoneReq{}), middleware.JwtAuthenticator(), middleware.RequestDecryptor(), OpResetMobilePhone)
// 账号
opAccountGroup := r.Group("/op/account", PrepareOp())

View File

@ -109,3 +109,15 @@ func OpLogout(ctx *gin.Context) {
func OpValidate(ctx *gin.Context) {
ReplyOk(ctx, nil)
}
func OpResetMobilePhone(ctx *gin.Context) {
req := ctx.MustGet("client_req").(*loginproto.OpResetMobilePhoneReq)
ec := service.DefaultService.OpResetMobilePhone(ctx, req)
if ec != errcode.ErrCodeLoginSrvOk {
logger.Error("OpResetMobilePhone fail, req: %v, ec: %v", util.ToJson(req), ec)
ReplyErrCodeMsg(ctx, ec)
return
}
ReplyOk(ctx, nil)
}

View File

@ -10,6 +10,7 @@ import (
"service/dbstruct"
"service/library/apollo"
"service/library/logger"
"service/library/mycrypto"
"time"
"github.com/gin-gonic/gin"
@ -77,6 +78,27 @@ func (l *LoginBusinessValidator) EnsureLoginExist() *LoginBusinessValidator {
return l
}
func (l *LoginBusinessValidator) EnsureNewMobilePhoneNotRegistered(QueryFunc func(ctx *gin.Context, phonehash string) ([]*dbstruct.Account, error), mobilePhone string) *LoginBusinessValidator {
l.oplist = append(l.oplist, func() {
phoneHash := mycrypto.CryptoServiceInstance().SHA256.Encrypt([]byte(mobilePhone))
accounts, err := QueryFunc(l.ctx, phoneHash)
if err != nil {
logger.Error("Query account failed, err: %v", err)
l.ec = errcode.ErrCodeAccountSrvFail
return
}
if len(accounts) > 0 {
logger.Error("This mobile phone has been registered")
l.ec = errcode.ErrCodeLoginMobilePhoneHasBeenRegistered
return
}
})
return l
}
func (l *LoginBusinessValidator) EnsureLoginAcctEnabled() *LoginBusinessValidator {
l.oplist = append(l.oplist, func() {
if util.DerefInt64(l.login.IsEnabled) == 0 { //账户未启用

View File

@ -58,7 +58,14 @@ func (p *Account) OpCreate(ctx *gin.Context, req *accountproto.OpCreateReq) erro
}
func (p *Account) OpUpdate(ctx *gin.Context, req *accountproto.OpUpdateReq) error {
err := p.store.UpdateAccount(ctx, req.Account)
err := interceptor.EncryptTagInterceptorInstance().Intercept(req.Account, "bcrypto")
if err != nil {
logger.Error("Account encryption err : %v", err)
return err
}
err = p.store.UpdateAccount(ctx, req.Account)
if err != nil {
logger.Error("UpdateAccount fail, err: %v", err)
return err

View File

@ -240,6 +240,30 @@ func (s *Service) OpUpdatePasswordBusinessValidate(ctx *gin.Context, req *loginp
return
}
// 重置手机号
func (s *Service) OpResetMobilePhoneBusinessValidate(ctx *gin.Context, req *loginproto.OpResetMobilePhoneReq) (login *dbstruct.Login, ec errcode.ErrCode) {
ec = errcode.ErrCodeLoginSrvOk
// 1.业务校验
req.CalcPhoneHash() //计算手机号哈希
resultList := businessvalidator.NewLoginBusinessValidator(ctx, req).
QueryLogin(_DefaultLogin.OpListByPhoneHash).
EnsureLoginExist().
EnsureNewMobilePhoneNotRegistered(_DefaultAccount.OpListByPhoneHash, req.NewMobilePhone).
Validate().
Collect()
// 2.校验结果
ec, _ = resultList[0].(errcode.ErrCode)
if ec != errcode.ErrCodeLoginSrvOk {
logger.Error("OpResetMobilePhone business validation failed")
return
}
login, _ = resultList[1].(*dbstruct.Login)
return
}
// Account
func (s *Service) OpUpdateAccountBusinessValidate(ctx *gin.Context, req *accountproto.OpUpdateReq) (ec errcode.ErrCode) {
ec = errcode.ErrCodeAccountSrvOk

View File

@ -835,6 +835,48 @@ func (s *Service) OpUpdatePassword(ctx *gin.Context, req *loginproto.OpUpdatePsw
return
}
// 手机号换绑
func (s *Service) OpResetMobilePhone(ctx *gin.Context, req *loginproto.OpResetMobilePhoneReq) (ec errcode.ErrCode) {
ec = errcode.ErrCodeLoginSrvOk
// 1.业务校验
login, ec := s.OpResetMobilePhoneBusinessValidate(ctx, req)
if ec != errcode.ErrCodeLoginSrvOk {
return
}
// 2.计算phoneHash
phoneHash := mycrypto.CryptoServiceInstance().SHA256.Encrypt([]byte(req.NewMobilePhone))
// 3.更新account表
if err := _DefaultAccount.OpUpdate(ctx, &accountproto.OpUpdateReq{
Account: &dbstruct.Account{
Mid: goproto.Int64(util.DerefInt64(login.Mid)),
MobilePhone: goproto.String(req.NewMobilePhone),
PhoneHash: goproto.String(phoneHash),
},
}); err != nil {
logger.Error("Account OpUpdate failed : %v", err)
ec = errcode.ErrCodeAccountSrvFail
return
}
// 4.更新login表
if err := _DefaultLogin.OpUpdate(ctx, &loginproto.OpUpdateReq{
Login: &dbstruct.Login{
Id: goproto.Int64(util.DerefInt64(login.Id)),
PhoneHash: goproto.String(phoneHash),
},
}); err != nil {
logger.Error("Login OpUpdate failed : %v", err)
ec = errcode.ErrCodeLoginSrvFail
return
}
return
}
// Account
func (s *Service) OpUpdateAccount(ctx *gin.Context, req *accountproto.OpUpdateReq) (ec errcode.ErrCode) {
ec = errcode.ErrCodeAccountSrvOk
@ -943,7 +985,7 @@ func (s *Service) OpGetAccountListByUserId(ctx *gin.Context, req *accountproto.O
return
}
func (s *Service) OpGetMobilePhoneByUserId(ctx *gin.Context, req *accountproto.OpGetMobilePhoneByUserIdReq) (mobilePhone string, ec errcode.ErrCode) {
func (s *Service) OpGetMobilePhoneByUserId(ctx *gin.Context, req *accountproto.OpGetMobilePhoneByUserIdReq) (mobilePhone string, vo *accountproto.OpListOthersVO, ec errcode.ErrCode) {
ec = errcode.ErrCodeAccountSrvOk
// 业务鉴权
@ -963,7 +1005,7 @@ func (s *Service) OpGetMobilePhoneByUserId(ctx *gin.Context, req *accountproto.O
base64DecryptedBytes, _ := base64.StdEncoding.DecodeString(util.DerefString(account.MobilePhone))
phoneBytes, _ := mycrypto.CryptoServiceInstance().AES.Decrypt(base64DecryptedBytes)
mobilePhone = string(phoneBytes)
vo = accountproto.NewOpListOthersVO().CopyAccount(account)
}
return