151 lines
4.4 KiB
Go
151 lines
4.4 KiB
Go
package logic
|
|
|
|
import (
|
|
"context"
|
|
|
|
"lone-services/pkg/utils"
|
|
"lone-services/pkg/validate"
|
|
user "lone-services/rpc/user/pb"
|
|
userconfig "lone-services/services/user/internal/config"
|
|
"lone-services/services/user/internal/dao"
|
|
"lone-services/services/user/internal/svc"
|
|
"lone-services/services/user/validator"
|
|
|
|
"github.com/zeromicro/go-zero/core/logx"
|
|
"google.golang.org/grpc/status"
|
|
)
|
|
|
|
type LoginLogic struct {
|
|
ctx context.Context
|
|
svcCtx *svc.ServiceContext
|
|
logx.Logger
|
|
}
|
|
|
|
func NewLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginLogic {
|
|
return &LoginLogic{
|
|
ctx: ctx,
|
|
svcCtx: svcCtx,
|
|
Logger: logx.WithContext(ctx),
|
|
}
|
|
}
|
|
|
|
func (l *LoginLogic) Login(in *user.LoginReq) (*user.Response, error) {
|
|
var req validator.LoginValidator
|
|
if msg := validate.ValidateFromProto(in, &req); msg != utils.StringEmpty {
|
|
return outResponse(utils.ErrorParams, msg), nil
|
|
}
|
|
|
|
switch req.GrantType {
|
|
case dao.GrantTypeOpenid:
|
|
return l.loginByOpenid(req)
|
|
case dao.GrantTypePassword:
|
|
return l.loginByPassword(req)
|
|
case dao.GrantTypeSms:
|
|
return outResponse(utils.ErrorParams, "验证码登录暂未开放"), nil
|
|
default:
|
|
return outResponse(utils.ErrorParams, "不支持的登录方式"), nil
|
|
}
|
|
}
|
|
|
|
func (l *LoginLogic) loginByOpenid(req validator.LoginValidator) (*user.Response, error) {
|
|
client, err := loadEnabledClient(req.ClientCode)
|
|
if err != nil {
|
|
l.Errorf("login load client: %v", err)
|
|
return failResponse(utils.Fail), nil
|
|
}
|
|
if !clientAllowsGrant(client.AllowedGrants, dao.GrantTypeOpenid) {
|
|
return outResponse(utils.ErrorParams, "该端不支持微信登录"), nil
|
|
}
|
|
|
|
wxClient, cfgErr := userconfig.NewWechatClient(req.ClientCode)
|
|
if cfgErr != nil {
|
|
l.Errorf("login wechat config: %v", cfgErr)
|
|
return outResponse(utils.Fail, "微信配置缺失"), nil
|
|
}
|
|
|
|
session, wxErr := wxClient.Code2Session(req.Code)
|
|
if wxErr != nil {
|
|
l.Errorf("login code2session: %v", wxErr)
|
|
return outResponse(utils.Fail, "微信登录失败"), nil
|
|
}
|
|
|
|
userId, resolveErr := resolveOrCreateWechatUser(l.ctx, l.svcCtx.DB, session.OpenID, session.UnionID, req.ClientCode)
|
|
if resolveErr != nil {
|
|
l.Errorf("login resolve wechat user: %v", resolveErr)
|
|
if st, ok := status.FromError(resolveErr); ok {
|
|
return outResponse(utils.Fail, st.Message()), nil
|
|
}
|
|
return failResponse(utils.Fail), nil
|
|
}
|
|
|
|
row, userErr := loadEnabledUser(userId)
|
|
if userErr != nil {
|
|
l.Errorf("login load user: %v", userErr)
|
|
return failResponse(utils.ErrorNotFund), nil
|
|
}
|
|
|
|
ret, tokenErr := issueLoginToken(l.ctx, l.svcCtx.JWT, l.svcCtx.SaleSvcName, row, client)
|
|
if tokenErr != nil {
|
|
l.Errorf("login issue token: %v", tokenErr)
|
|
return failResponse(utils.Fail), nil
|
|
}
|
|
return okResponse(ret), nil
|
|
}
|
|
|
|
func (l *LoginLogic) loginByPassword(req validator.LoginValidator) (*user.Response, error) {
|
|
client, err := loadEnabledClient(req.ClientCode)
|
|
if err != nil {
|
|
l.Errorf("login load client: %v", err)
|
|
return failResponse(utils.Fail), nil
|
|
}
|
|
if !clientAllowsGrant(client.AllowedGrants, dao.GrantTypePassword) {
|
|
return outResponse(utils.ErrorParams, "该端不支持密码登录"), nil
|
|
}
|
|
|
|
if len(req.Mobile) != utils.NumberEleven {
|
|
return failResponse(utils.ErrorMobileError), nil
|
|
}
|
|
encryptMobile, encErr := utils.EncryptPhone(req.Mobile)
|
|
if encErr != nil {
|
|
l.Errorf("login encrypt mobile: %v", encErr)
|
|
return failResponse(utils.ErrorEncryptAesError), nil
|
|
}
|
|
|
|
cred, credErr := findCredential(dao.CredentialTypePassword, encryptMobile)
|
|
if credErr != nil {
|
|
l.Errorf("login find credential: %v", credErr)
|
|
return failResponse(utils.Fail), nil
|
|
}
|
|
if cred == nil {
|
|
return failResponse(utils.ErrorNotFund), nil
|
|
}
|
|
if cred.Status == dao.StatusDisabled {
|
|
return outResponse(utils.Fail, "登录凭证已禁用"), nil
|
|
}
|
|
if !utils.EqualsPassword(req.Password, cred.Secret) {
|
|
return failResponse(utils.ErrorPwdError), nil
|
|
}
|
|
|
|
hasClient, clientErr := userHasEnabledClient(cred.UserId, req.ClientCode)
|
|
if clientErr != nil {
|
|
l.Errorf("login check user client: %v", clientErr)
|
|
return failResponse(utils.Fail), nil
|
|
}
|
|
if !hasClient {
|
|
return outResponse(utils.ErrorParams, "该端未开通或已禁用"), nil
|
|
}
|
|
|
|
row, userErr := loadEnabledUser(cred.UserId)
|
|
if userErr != nil {
|
|
l.Errorf("login load user: %v", userErr)
|
|
return failResponse(utils.ErrorNotFund), nil
|
|
}
|
|
|
|
ret, tokenErr := issueLoginToken(l.ctx, l.svcCtx.JWT, l.svcCtx.SaleSvcName, row, client)
|
|
if tokenErr != nil {
|
|
l.Errorf("login issue token: %v", tokenErr)
|
|
return failResponse(utils.Fail), nil
|
|
}
|
|
return okResponse(ret), nil
|
|
}
|