Merge branch 'develop' of gitee.com:fusenpack/fusenapi into develop

This commit is contained in:
laodaming 2023-08-29 14:35:11 +08:00
commit d07b910e13
10 changed files with 146 additions and 52 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

@ -6,7 +6,6 @@ import (
"fusenapi/utils/auth"
"fusenapi/utils/basic"
"fusenapi/utils/wevent"
"log"
"time"
"context"
@ -90,20 +89,18 @@ 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)
}
log.Println("aaaa", "接收校验token", token.Platform)
switch token.OperateType {
case auth.OpTypeRegister:
if time.Since(token.CreateAt) >= 24*time.Hour {
return resp.SetStatus(basic.CodeOAuthConfirmationTimeoutErr)
}
logx.Info(token.Platform)
switch token.Platform {
case "google":
// 谷歌平台的注册流程

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,7 +22,7 @@ type ServiceContext struct {
MysqlConn *gorm.DB
AllModels *gmodel.AllModelsGen
RegisterTokenManger *auth.ConfirmationLink[auth.RegisterToken]
OAuthTokenManger *auth.ConfirmationLink[auth.RegisterToken]
ResetTokenManger *auth.ConfirmationLink[auth.ResetToken]
}
@ -35,7 +35,7 @@ func NewServiceContext(c config.Config) *ServiceContext {
MysqlConn: conn,
SharedState: nil,
AllModels: gmodel.NewAllModels(initalize.InitMysql(c.SourceMysql)),
RegisterTokenManger: auth.NewConfirmationLink[auth.RegisterToken](c.Auth.AccessSecret, registerAddress),
OAuthTokenManger: auth.NewConfirmationLink[auth.RegisterToken](c.Auth.AccessSecret, registerAddress),
ResetTokenManger: auth.NewConfirmationLink[auth.ResetToken](c.Auth.AccessSecret, registerAddress),
}
}

View File

@ -44,7 +44,7 @@ type RequestGoogleLogin struct {
}
type RequestEmailConfirmation struct {
Token string `query:"token"` // 操作Token
Token string `form:"token"` // 操作Token
}
type RequestEmailRegister struct {

View File

@ -94,7 +94,7 @@ type RequestGoogleLogin {
}
type RequestEmailConfirmation {
Token string `query:"token"` // 操作Token
Token string `form:"token"` // 操作Token
}
type RequestEmailRegister {

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
TraceId string // 链路Id
CreateAt time.Time // 创建时间
Extend map[string]interface{} // 扩展信息 Id int64 // 注册的 id google_id 或 facebook_id ...
}
type ResetToken struct {