This commit is contained in:
eson 2023-08-29 14:19:47 +08:00
parent 79b6277332
commit 3103d69bae
8 changed files with 136 additions and 39 deletions

View File

@ -2,8 +2,11 @@ package gmodel
import (
"context"
"encoding/json"
"fmt"
"fusenapi/utils/auth"
"log"
"time"
"gorm.io/gorm"
@ -47,11 +50,20 @@ func (u *FsUserModel) Transaction(ctx context.Context, fc func(tx *gorm.DB) erro
}
// 继承guest_id的资源表
func InheritGuestIdResource(tx *gorm.DB, userId, guestId int64) error {
func InheritGuestIdResource(tx *gorm.DB, userId, guestId int64, afterDo func(txResouce *gorm.DB, txUserMaterial *gorm.DB, txUserInfo *gorm.DB) error) error {
var err error
if guestId != 0 {
// 继承guest_id的资源表
err = tx.Model(&FsResource{}).
txRes := tx.Model(&FsResource{})
err = txRes.
Where("guest_id = ?", guestId).
UpdateColumn("user_id", userId).Error
if err != nil {
return err
}
txUserMaterial := tx.Model(&FsUserMaterial{})
err = txUserMaterial.
Where("guest_id = ?", guestId).
UpdateColumn("user_id", userId).Error
@ -59,19 +71,16 @@ func InheritGuestIdResource(tx *gorm.DB, userId, guestId int64) error {
return err
}
err = tx.Model(&FsUserMaterial{}).
txUserInfo := tx.Model(&FsUserInfo{})
err = txUserInfo.
Where("guest_id = ?", guestId).
UpdateColumn("user_id", userId).Error
if err != nil {
return err
}
err = tx.Model(&FsUserInfo{}).
Where("guest_id = ?", guestId).
UpdateColumn("user_id", userId).Error
if err != nil {
return err
if afterDo != nil {
return afterDo(txRes, txUserMaterial, txUserInfo)
}
}
return fmt.Errorf("guest_id must not be 0")
@ -82,15 +91,17 @@ func (u *FsUserModel) RegisterByGoogleOAuth(ctx context.Context, token *auth.Reg
user := &FsUser{}
err := u.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
googleId := token.Extend["google_id"].(int64)
err := tx.Model(user).Where("email = ?", token.Email).Take(user).Error
if err != nil {
// 没有找到在数据库就创建注册
if err == gorm.ErrRecordNotFound {
createAt := time.Now().UTC().Unix()
user.Email = &token.Email
user.CreatedAt = &createAt
user.GoogleId = &token.Id
user.GoogleId = &googleId
user.PasswordHash = &token.Password
err = tx.Model(user).Create(user).Error
if err != nil {
@ -99,7 +110,7 @@ func (u *FsUserModel) RegisterByGoogleOAuth(ctx context.Context, token *auth.Reg
if token.GuestId != 0 {
// 继承guest_id的资源表
return InheritGuestIdResource(tx, user.Id, token.GuestId)
return InheritGuestIdResource(tx, user.Id, token.GuestId, nil)
}
return err
}
@ -108,7 +119,7 @@ func (u *FsUserModel) RegisterByGoogleOAuth(ctx context.Context, token *auth.Reg
}
// 如果已经存在,把谷歌id 加入到用户信息里
user.GoogleId = &token.Id
user.GoogleId = &googleId
return tx.Model(user).Update("google_id", user).Error
})
@ -119,27 +130,64 @@ func (u *FsUserModel) RegisterByGoogleOAuth(ctx context.Context, token *auth.Reg
return user, nil
}
type UserProfile struct {
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Resetaurant string `json:"resetaurant"`
}
// 自平台的注册流程
func (u *FsUserModel) RegisterByFusen(ctx context.Context, token *auth.RegisterToken) (*FsUser, error) {
user := &FsUser{}
err := u.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
err := tx.Model(user).Where("email = ?", token.Email).Take(user).Error
UserTx := tx.Model(user)
err := UserTx.Where("email = ?", token.Email).Take(user).Error
if err != nil {
// 没有找到在数据库就创建注册
if err == gorm.ErrRecordNotFound {
FirstName := token.Extend["first_name"].(string)
LastName := token.Extend["last_name"].(string)
Resetaurant := token.Extend["resetaurant"].(string)
createAt := time.Now().UTC().Unix()
user.Email = &token.Email
user.CreatedAt = &createAt
user.PasswordHash = &token.Password
err = tx.Model(user).Create(user).Error
user.FirstName = &FirstName
user.LastName = &LastName
err = UserTx.Create(user).Error
log.Println("create")
if err != nil {
return err
}
if token.GuestId != 0 {
// 继承guest_id的资源表
return InheritGuestIdResource(tx, user.Id, token.GuestId)
return InheritGuestIdResource(tx, user.Id, token.GuestId, func(txResouce, txUserMaterial, txUserInfo *gorm.DB) error {
userProfile := &UserProfile{
FirstName: FirstName,
LastName: LastName,
Resetaurant: Resetaurant,
}
metadata, err := json.Marshal(userProfile)
if err != nil {
return err
}
now := time.Now()
uinfo := &FsUserInfo{
Module: FsString("profile"),
UserId: &user.Id,
GuestId: &token.GuestId,
Metadata: &metadata,
Ctime: &now,
Utime: &now,
}
return txUserInfo.Create(uinfo).Error
})
}
return err
}

37
model/gmodel/var.go Normal file
View File

@ -0,0 +1,37 @@
package gmodel
func FsString(v string) *string {
return &v
}
func FsInt(v int) *int {
return &v
}
func FsInt32(v int32) *int32 {
return &v
}
func FsInt64(v int64) *int64 {
return &v
}
func FsUint(v uint) *uint {
return &v
}
func FsUint32(v uint32) *uint32 {
return &v
}
func FsUint64(v uint64) *uint64 {
return &v
}
func FsFloat(v float64) *float64 {
return &v
}
func FsBool(v bool) *bool {
return &v
}

View File

@ -90,7 +90,7 @@ func (l *UserEmailConfirmationLogic) UserEmailConfirmation(req *types.RequestEma
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
// userinfo 传入值时, 一定不为null
token, err := l.svcCtx.RegisterTokenManger.Decrypt(req.Token)
token, err := l.svcCtx.OAuthTokenManger.Decrypt(req.Token)
if err != nil {
logx.Error(err)
return resp.SetStatus(basic.CodeOAuthRegisterTokenErr)

View File

@ -47,7 +47,7 @@ func (l *UserEmailRegisterLogic) UserEmailRegister(req *types.RequestEmailRegist
return resp.SetStatus(basic.CodeOAuthEmailErr)
}
token, err := l.svcCtx.RegisterTokenManger.Decrypt(req.RegisterToken)
token, err := l.svcCtx.OAuthTokenManger.Decrypt(req.RegisterToken)
if err != nil {
logx.Error(err)
return resp.SetStatus(basic.CodeOAuthRegisterTokenErr)
@ -62,7 +62,7 @@ func (l *UserEmailRegisterLogic) UserEmailRegister(req *types.RequestEmailRegist
token.Wid = req.Wid
token.GuestId = userinfo.GuestId
clurl, err := l.svcCtx.RegisterTokenManger.Generate(token)
clurl, err := l.svcCtx.OAuthTokenManger.Generate(token)
if err != nil {
logx.Error(err)
return resp.SetStatus(basic.CodeOAuthRegisterTokenErr)

View File

@ -91,16 +91,19 @@ func (l *UserGoogleLoginLogic) UserGoogleLogin(req *types.RequestGoogleLogin, us
}
l.registerInfo = &auth.RegisterToken{
Id: googleId,
Password: base64.RawURLEncoding.EncodeToString(nonce),
Platform: "google",
OperateType: auth.OpTypeRegister,
TraceId: uuid.NewString(),
CreateAt: time.Now(),
Extend: map[string]interface{}{
"google_id": googleId,
},
}
l.isRegistered = false
token, err := l.svcCtx.RegisterTokenManger.Encrypt(l.registerInfo)
token, err := l.svcCtx.OAuthTokenManger.Encrypt(l.registerInfo)
if err != nil {
logx.Error(err)
return resp.SetStatus(basic.CodeOAuthRegisterTokenErr)

View File

@ -43,7 +43,6 @@ func (l *UserRegisterLogic) UserRegister(req *types.RequestUserRegister, userinf
token := &auth.RegisterToken{
OperateType: auth.OpTypeRegister,
Id: 0,
GuestId: userinfo.GuestId,
Wid: req.Wid,
Email: req.Email,
@ -51,9 +50,14 @@ func (l *UserRegisterLogic) UserRegister(req *types.RequestUserRegister, userinf
Platform: "fusen",
TraceId: uuid.NewString(),
CreateAt: time.Now(),
Extend: map[string]interface{}{
"first_name": req.FirstName,
"last_name": req.LastName,
"resetaurant": req.Resetaurant,
},
}
clurl, err := l.svcCtx.RegisterTokenManger.Generate(token)
clurl, err := l.svcCtx.OAuthTokenManger.Generate(token)
if err != nil {
logx.Error(err)
return resp.SetStatus(basic.CodeOAuthRegisterTokenErr)

View File

@ -22,8 +22,8 @@ type ServiceContext struct {
MysqlConn *gorm.DB
AllModels *gmodel.AllModelsGen
RegisterTokenManger *auth.ConfirmationLink[auth.RegisterToken]
ResetTokenManger *auth.ConfirmationLink[auth.ResetToken]
OAuthTokenManger *auth.ConfirmationLink[auth.RegisterToken]
ResetTokenManger *auth.ConfirmationLink[auth.ResetToken]
}
func NewServiceContext(c config.Config) *ServiceContext {
@ -31,12 +31,12 @@ func NewServiceContext(c config.Config) *ServiceContext {
// StateServer := shared.StartNode(c.ReplicaId, autoconfig.AutoGetAllServerConfig(), conn)
registerAddress := fmt.Sprintf("%s/api/auth/email/confirmation", c.MainAddress)
return &ServiceContext{
Config: c,
MysqlConn: conn,
SharedState: nil,
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
RegisterTokenManger: auth.NewConfirmationLink[auth.RegisterToken](c.Auth.AccessSecret, registerAddress),
ResetTokenManger: auth.NewConfirmationLink[auth.ResetToken](c.Auth.AccessSecret, registerAddress),
Config: c,
MysqlConn: conn,
SharedState: nil,
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
OAuthTokenManger: auth.NewConfirmationLink[auth.RegisterToken](c.Auth.AccessSecret, registerAddress),
ResetTokenManger: auth.NewConfirmationLink[auth.ResetToken](c.Auth.AccessSecret, registerAddress),
}
}

View File

@ -3,6 +3,7 @@ package auth
import (
"crypto/sha256"
"encoding/binary"
"encoding/gob"
"errors"
"fmt"
"net/http"
@ -12,16 +13,20 @@ import (
"github.com/golang-jwt/jwt"
)
func init() {
gob.Register(map[string]interface{}{})
}
type RegisterToken struct {
OperateType // 操作的类型, 验证的token 必须要继承这个
Id int64 // 注册的 id google_id 或 facebook_id ...
GuestId int64 // guest_id 需要继承
Wid string // websocket 通道id
Email string // email
Password string // 密码
Platform string // 平台
TraceId string //链路Id
CreateAt time.Time // 创建时间
OperateType // 操作的类型, 验证的token 必须要继承这个
GuestId int64 // guest_id 需要继承
Wid string // websocket 通道id
Email string // email
Password string // 密码
Platform string // 平台
TraceId string // 链路Id
CreateAt time.Time // 创建时间
Extend map[string]interface{} // 扩展信息 Id int64 // 注册的 id google_id 或 facebook_id ...
}
type ResetToken struct {