diff --git a/model/gmodel/fs_user_logic.go b/model/gmodel/fs_user_logic.go index 75fbb41f..1435213c 100644 --- a/model/gmodel/fs_user_logic.go +++ b/model/gmodel/fs_user_logic.go @@ -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 } diff --git a/model/gmodel/var.go b/model/gmodel/var.go new file mode 100644 index 00000000..3bd8af16 --- /dev/null +++ b/model/gmodel/var.go @@ -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 +} diff --git a/server/auth/internal/logic/useremailconfirmationlogic.go b/server/auth/internal/logic/useremailconfirmationlogic.go index 5140d214..a323fad1 100644 --- a/server/auth/internal/logic/useremailconfirmationlogic.go +++ b/server/auth/internal/logic/useremailconfirmationlogic.go @@ -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) diff --git a/server/auth/internal/logic/useremailregisterlogic.go b/server/auth/internal/logic/useremailregisterlogic.go index 805b11dc..50b360e2 100644 --- a/server/auth/internal/logic/useremailregisterlogic.go +++ b/server/auth/internal/logic/useremailregisterlogic.go @@ -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) diff --git a/server/auth/internal/logic/usergoogleloginlogic.go b/server/auth/internal/logic/usergoogleloginlogic.go index fee80dbe..4ccca7af 100644 --- a/server/auth/internal/logic/usergoogleloginlogic.go +++ b/server/auth/internal/logic/usergoogleloginlogic.go @@ -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) diff --git a/server/auth/internal/logic/userregisterlogic.go b/server/auth/internal/logic/userregisterlogic.go index 12b87530..3840dffe 100644 --- a/server/auth/internal/logic/userregisterlogic.go +++ b/server/auth/internal/logic/userregisterlogic.go @@ -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) diff --git a/server/auth/internal/svc/servicecontext.go b/server/auth/internal/svc/servicecontext.go index 50f62783..b5a0687a 100644 --- a/server/auth/internal/svc/servicecontext.go +++ b/server/auth/internal/svc/servicecontext.go @@ -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), } } diff --git a/utils/auth/register.go b/utils/auth/register.go index 9857abb4..45d64019 100644 --- a/utils/auth/register.go +++ b/utils/auth/register.go @@ -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 {