mirror of
https://github.com/WiiLink24/wfc-server.git
synced 2026-09-12 10:35:46 -05:00
Database: Allow user creation with existing profile ID
This commit is contained in:
@@ -8,16 +8,17 @@ import (
|
||||
"wwfc/logging"
|
||||
)
|
||||
|
||||
func LoginUserToGPCM(pool *pgxpool.Pool, ctx context.Context, userId uint64, gsbrcd string) (User, bool) {
|
||||
func LoginUserToGPCM(pool *pgxpool.Pool, ctx context.Context, userId uint64, gsbrcd string, profileId uint32) (User, bool) {
|
||||
var exists bool
|
||||
err := pool.QueryRow(ctx, DoesUserExist, userId, gsbrcd).Scan(&exists)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return User{}, false
|
||||
}
|
||||
|
||||
uniqueNickname := common.Base32Encode(userId) + gsbrcd
|
||||
|
||||
user := User{
|
||||
ProfileId: profileId,
|
||||
UserId: userId,
|
||||
GsbrCode: gsbrcd,
|
||||
Email: uniqueNickname + "@nds",
|
||||
@@ -26,13 +27,32 @@ func LoginUserToGPCM(pool *pgxpool.Pool, ctx context.Context, userId uint64, gsb
|
||||
|
||||
if !exists {
|
||||
// Create the GPCM account
|
||||
user.CreateUser(pool, ctx)
|
||||
|
||||
logging.Notice("DATABASE", "Created new GPCM user:", aurora.Cyan(userId), aurora.Cyan(gsbrcd), "-", aurora.Cyan(user.ProfileId))
|
||||
} else {
|
||||
err := pool.QueryRow(ctx, GetUserProfileID, userId, gsbrcd).Scan(&user.ProfileId)
|
||||
err := user.CreateUser(pool, ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
logging.Error("DATABASE", "Error creating user:", aurora.Cyan(userId), aurora.Cyan(gsbrcd), aurora.Cyan(user.ProfileId), "\nerror:", err.Error())
|
||||
return User{}, false
|
||||
}
|
||||
|
||||
logging.Notice("DATABASE", "Created new GPCM user:", aurora.Cyan(userId), aurora.Cyan(gsbrcd), aurora.Cyan(user.ProfileId))
|
||||
} else {
|
||||
err := pool.QueryRow(ctx, GetUserProfileID, userId, gsbrcd).Scan(&user.ProfileId, &user.Email, &user.UniqueNick, &user.FirstName, &user.LastName)
|
||||
if err != nil {
|
||||
return User{}, false
|
||||
}
|
||||
|
||||
if profileId != 0 && user.ProfileId != profileId {
|
||||
err := user.UpdateProfileID(pool, ctx, profileId)
|
||||
if err != nil {
|
||||
logging.Warn("DATABASE", "Could not update", aurora.Cyan(userId), aurora.Cyan(gsbrcd), "profile ID from", aurora.Cyan(user.ProfileId), "to", aurora.Cyan(profileId))
|
||||
} else {
|
||||
logging.Notice("DATABASE", "Updated GPCM user profile ID:", aurora.Cyan(userId), aurora.Cyan(gsbrcd), aurora.Cyan(user.ProfileId))
|
||||
}
|
||||
}
|
||||
|
||||
if user.LastName == "" {
|
||||
user = UpdateProfile(pool, ctx, profileId, map[string]string{
|
||||
"lastname": "000000000" + gsbrcd,
|
||||
})
|
||||
}
|
||||
|
||||
logging.Notice("DATABASE", "Log in GPCM user:", aurora.Cyan(userId), aurora.Cyan(user.GsbrCode), "-", aurora.Cyan(user.ProfileId))
|
||||
|
||||
@@ -2,19 +2,21 @@ package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/jackc/pgx/v4/pgxpool"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
const (
|
||||
InsertUser = `INSERT INTO users (user_id, gsbrcd, password, email, unique_nick) VALUES ($1, $2, $3, $4, $5) RETURNING profile_id`
|
||||
UpdateUserTable = `UPDATE users SET firstname = CASE WHEN $3 THEN $2 ELSE firstname END, lastname = CASE WHEN $5 THEN $4 ELSE lastname END WHERE profile_id = $1 RETURNING user_id, gsbrcd, email, unique_nick, firstname, lastname`
|
||||
GetUser = `SELECT user_id, gsbrcd, email, unique_nick, firstname, lastname FROM users WHERE profile_id = $1`
|
||||
CreateUserSession = `INSERT INTO sessions (session_key, profile_id, login_ticket) VALUES ($1, $2, $3)`
|
||||
GetTicketSession = `SELECT session_key, profile_id FROM sessions WHERE login_ticket = $1`
|
||||
DoesUserExist = `SELECT EXISTS(SELECT 1 FROM users WHERE user_id = $1 AND gsbrcd = $2)`
|
||||
DeleteUserSession = `DELETE FROM sessions WHERE profile_id = $1`
|
||||
GetUserProfileID = `SELECT profile_id FROM users WHERE user_id = $1 AND gsbrcd = $2`
|
||||
InsertUser = `INSERT INTO users (user_id, gsbrcd, password, email, unique_nick) VALUES ($1, $2, $3, $4, $5) RETURNING profile_id`
|
||||
InsertUserWithProfileID = `INSERT INTO users (user_id, gsbrcd, password, email, unique_nick) VALUES ($1, $2, $3, $4, $5)`
|
||||
UpdateUserTable = `UPDATE users SET firstname = CASE WHEN $3 THEN $2 ELSE firstname END, lastname = CASE WHEN $5 THEN $4 ELSE lastname END WHERE profile_id = $1 RETURNING user_id, gsbrcd, email, unique_nick, firstname, lastname`
|
||||
UpdateUserProfileID = `UPDATE users SET profile_id = $3 WHERE user_id = $1 AND gsbrcd = $2`
|
||||
GetUser = `SELECT user_id, gsbrcd, email, unique_nick, firstname, lastname FROM users WHERE profile_id = $1`
|
||||
DoesUserExist = `SELECT EXISTS(SELECT 1 FROM users WHERE user_id = $1 AND gsbrcd = $2)`
|
||||
IsProfileIDInUse = `SELECT EXISTS(SELECT 1 FROM users WHERE profile_id = $1)`
|
||||
DeleteUserSession = `DELETE FROM sessions WHERE profile_id = $1`
|
||||
GetUserProfileID = `SELECT profile_id, email, unique_nick, firstname, lastname FROM users WHERE user_id = $1 AND gsbrcd = $2`
|
||||
|
||||
GetMKWFriendInfoQuery = `SELECT mariokartwii_friend_info FROM users WHERE profile_id = $1`
|
||||
UpdateMKWFriendInfoQuery = `UPDATE users SET mariokartwii_friend_info = $2 WHERE profile_id = $1`
|
||||
@@ -30,11 +32,55 @@ type User struct {
|
||||
LastName string
|
||||
}
|
||||
|
||||
func (user *User) CreateUser(pool *pgxpool.Pool, ctx context.Context) {
|
||||
err := pool.QueryRow(ctx, InsertUser, user.UserId, user.GsbrCode, "", user.Email, user.UniqueNick).Scan(&user.ProfileId)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
var (
|
||||
ErrProfileIDInUse = errors.New("profile ID is already in use")
|
||||
ErrReservedProfileIDRange = errors.New("profile ID is in reserved range")
|
||||
)
|
||||
|
||||
func (user *User) CreateUser(pool *pgxpool.Pool, ctx context.Context) error {
|
||||
if user.ProfileId == 0 {
|
||||
return pool.QueryRow(ctx, InsertUser, user.UserId, user.GsbrCode, "", user.Email, user.UniqueNick).Scan(&user.ProfileId)
|
||||
}
|
||||
|
||||
if user.ProfileId >= 1000000000 {
|
||||
return ErrReservedProfileIDRange
|
||||
}
|
||||
|
||||
var exists bool
|
||||
err := pool.QueryRow(ctx, IsProfileIDInUse, user.ProfileId).Scan(&exists)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if exists {
|
||||
return ErrProfileIDInUse
|
||||
}
|
||||
|
||||
_, err = pool.Exec(ctx, InsertUserWithProfileID, user.UserId, user.GsbrCode, "", user.Email, user.UniqueNick, user.ProfileId)
|
||||
return err
|
||||
}
|
||||
|
||||
func (user *User) UpdateProfileID(pool *pgxpool.Pool, ctx context.Context, newProfileId uint32) error {
|
||||
if newProfileId >= 1000000000 {
|
||||
return ErrReservedProfileIDRange
|
||||
}
|
||||
|
||||
var exists bool
|
||||
err := pool.QueryRow(ctx, IsProfileIDInUse, newProfileId).Scan(&exists)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if exists {
|
||||
return ErrProfileIDInUse
|
||||
}
|
||||
|
||||
_, err = pool.Exec(ctx, UpdateUserProfileID, user.UserId, user.GsbrCode, newProfileId)
|
||||
if err == nil {
|
||||
user.ProfileId = newProfileId
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func GetUniqueUserID() uint64 {
|
||||
|
||||
@@ -154,8 +154,23 @@ func (g *GameSpySession) login(command common.GameSpyCommand) {
|
||||
|
||||
proof := generateProof(g.Challenge, challenge, command.OtherValues["authtoken"], command.OtherValues["challenge"])
|
||||
|
||||
cmdProfileId := uint32(0)
|
||||
if cmdProfileIdStr, exists := command.OtherValues["profileid"]; exists {
|
||||
cmdProfileId2, err := strconv.ParseUint(cmdProfileIdStr, 10, 32)
|
||||
if err != nil {
|
||||
g.replyError(GPError{
|
||||
ErrorCode: ErrLogin.ErrorCode,
|
||||
ErrorString: "The provided profile ID is invalid.",
|
||||
Fatal: true,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
cmdProfileId = uint32(cmdProfileId2)
|
||||
}
|
||||
|
||||
// Perform the login with the database.
|
||||
user, ok := database.LoginUserToGPCM(pool, ctx, userId, gsbrcd)
|
||||
user, ok := database.LoginUserToGPCM(pool, ctx, userId, gsbrcd, cmdProfileId)
|
||||
if !ok {
|
||||
// There was an error logging in to the GP backend.
|
||||
g.replyError(ErrLogin)
|
||||
|
||||
@@ -191,8 +191,6 @@ func getRequestIdentity(moduleName string, request StorageRequestData) (uint32,
|
||||
panic("Invalid secret key")
|
||||
}
|
||||
|
||||
logging.Notice(moduleName, request.LoginTicket)
|
||||
|
||||
err, profileId, _ := common.UnmarshalGPCMLoginTicket(request.LoginTicket)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
||||
Reference in New Issue
Block a user