TinySkin/service/user.go
2023-09-02 17:39:58 +08:00

85 lines
1.8 KiB
Go

package service
import (
"context"
"crypto/md5"
"database/sql"
"encoding/hex"
"errors"
"fmt"
"strings"
"time"
"github.com/bwmarrin/snowflake"
"github.com/google/uuid"
"github.com/xmdhs/authlib-skin/config"
"github.com/xmdhs/authlib-skin/db/mysql"
"github.com/xmdhs/authlib-skin/model"
"github.com/xmdhs/authlib-skin/utils"
)
var (
ErrExistUser = errors.New("邮箱已存在")
ErrExitsName = errors.New("用户名已存在")
)
func Reg(ctx context.Context, u model.User, q mysql.Querier, db *sql.DB, snow *snowflake.Node,
c config.Config,
) error {
ou, err := q.GetUserByEmail(ctx, u.Email)
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return fmt.Errorf("Reg: %w", err)
}
if ou.Email != "" {
return fmt.Errorf("Reg: %w", ErrExistUser)
}
err = utils.WithTx(ctx, &sql.TxOptions{
Isolation: sql.LevelReadCommitted,
}, q, db, func(q mysql.Querier) error {
p, s := utils.Argon2ID(u.Password)
userID := snow.Generate().Int64()
_, err := q.CreateUser(ctx, mysql.CreateUserParams{
ID: userID,
Email: u.Email,
Password: p,
Salt: s,
State: 0,
RegTime: time.Now().Unix(),
})
if err != nil {
return err
}
var userUuid string
if c.OfflineUUID {
userUuid = uuidGen(u.Name)
} else {
userUuid = strings.ReplaceAll(uuid.New().String(), "-", "")
}
_, err = q.CreateUserProfile(ctx, mysql.CreateUserProfileParams{
UserID: userID,
Name: u.Name,
Uuid: userUuid,
})
if err != nil {
return err
}
return nil
})
if err != nil {
return fmt.Errorf("Reg: %w", err)
}
return nil
}
func uuidGen(t string) string {
data := []byte("OfflinePlayer:" + t)
h := md5.New()
h.Write(data)
uuid := h.Sum(nil)
uuid[6] = (uuid[6] & 0x0f) | uint8((3&0xf)<<4)
uuid[8] = (uuid[8] & 0x3f) | 0x80
return hex.EncodeToString(uuid)
}