Return additional info in authenticated pinfo requests

Real psql error messages will be sent (ephemeral bot side, so no user info can
leak that mods cannot already leak)

Hidden ban reason will be sent
This commit is contained in:
ppeb 2025-04-20 14:43:37 -05:00
parent c3063de93b
commit 6dc33d610b
No known key found for this signature in database
GPG Key ID: CC147AD1B3D318D0
6 changed files with 38 additions and 23 deletions

View File

@ -106,9 +106,9 @@ func handleBanImpl(r *http.Request) (*database.User, int, error) {
gpcm.KickPlayerCustomMessage(req.ProfileID, req.Reason, gpcm.WWFCMsgProfileRestrictedCustom)
user, success := database.GetProfile(pool, ctx, req.ProfileID)
user, err := database.GetProfile(pool, ctx, req.ProfileID)
if !success {
if err != nil {
return nil, http.StatusInternalServerError, ErrUserQueryTransaction
}

View File

@ -78,9 +78,9 @@ func handleKickImpl(r *http.Request) (*database.User, int, error) {
gpcm.KickPlayerCustomMessage(req.ProfileID, req.Reason, gpcm.WWFCMsgKickedCustom)
user, success := database.GetProfile(pool, ctx, req.ProfileID)
user, err := database.GetProfile(pool, ctx, req.ProfileID)
if !success {
if err != nil {
return nil, http.StatusInternalServerError, ErrUserQueryTransaction
}

View File

@ -63,14 +63,23 @@ func handlePinfoImpl(r *http.Request) (*database.User, int, error) {
return nil, http.StatusBadRequest, ErrRequestBody
}
realUser, success := database.GetProfile(pool, ctx, req.ProfileID)
var ret *database.User
if !success {
return &database.User{}, http.StatusInternalServerError, ErrUserQuery
goodSecret := false
if apiSecret != "" && req.Secret == apiSecret {
goodSecret = true
}
if apiSecret == "" || req.Secret != apiSecret {
realUser, err := database.GetProfile(pool, ctx, req.ProfileID)
var ret *database.User
if err != nil {
if !goodSecret {
err = ErrUserQuery
}
return &database.User{}, http.StatusInternalServerError, err
}
if !goodSecret {
// Invalid secret, only report normal user info
ret = &database.User{
ProfileId: realUser.ProfileId,

View File

@ -74,9 +74,9 @@ func handleUnbanImpl(r *http.Request) (*database.User, int, error) {
return nil, http.StatusInternalServerError, ErrTransaction
}
user, success := database.GetProfile(pool, ctx, req.ProfileID)
user, err := database.GetProfile(pool, ctx, req.ProfileID)
if !success {
if err != nil {
return nil, http.StatusInternalServerError, ErrUserQueryTransaction
}

View File

@ -16,7 +16,7 @@ const (
UpdateUserProfileID = `UPDATE users SET profile_id = $3 WHERE user_id = $1 AND gsbrcd = $2`
UpdateUserNGDeviceID = `UPDATE users SET ng_device_id = $2 WHERE profile_id = $1`
UpdateUserCsnum = `UPDATE users SET csnum = $2 WHERE profile_id = $1`
GetUser = `SELECT user_id, gsbrcd, ng_device_id, email, unique_nick, firstname, lastname, has_ban, ban_reason, open_host, last_ingamesn, last_ip_address, csnum, ban_moderator, ban_issued, ban_expires FROM users WHERE profile_id = $1`
GetUser = `SELECT user_id, gsbrcd, ng_device_id, email, unique_nick, firstname, lastname, has_ban, ban_reason, open_host, last_ingamesn, last_ip_address, csnum, ban_moderator, ban_reason_hidden, ban_issued, ban_expires FROM users WHERE profile_id = $1`
ClearProfileQuery = `DELETE FROM users WHERE profile_id = $1 RETURNING user_id, gsbrcd, email, unique_nick, firstname, lastname, open_host, last_ip_address, last_ingamesn, csnum`
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)`
@ -46,10 +46,11 @@ type User struct {
LastInGameSn string
LastIPAddress string
Csnum []string
// Two fields only used in GetUser query
BanModerator string
BanIssued *time.Time
BanExpires *time.Time
// Following fields only used in GetUser query
BanModerator string
BanReasonHidden string
BanIssued *time.Time
BanExpires *time.Time
}
var (
@ -135,7 +136,7 @@ func (user *User) UpdateProfile(pool *pgxpool.Pool, ctx context.Context, data ma
}
}
func GetProfile(pool *pgxpool.Pool, ctx context.Context, profileId uint32) (User, bool) {
func GetProfile(pool *pgxpool.Pool, ctx context.Context, profileId uint32) (User, error) {
user := User{}
row := pool.QueryRow(ctx, GetUser, profileId)
@ -146,11 +147,12 @@ func GetProfile(pool *pgxpool.Pool, ctx context.Context, profileId uint32) (User
var lastInGameSn *string
var lastIPAddress *string
var banModerator *string
var banHiddenReason *string
err := row.Scan(&user.UserId, &user.GsbrCode, &user.NgDeviceId, &user.Email, &user.UniqueNick, &firstName, &lastName, &user.Restricted, &banReason, &user.OpenHost, &lastInGameSn, &lastIPAddress, &user.Csnum, &banModerator, &user.BanIssued, &user.BanExpires)
err := row.Scan(&user.UserId, &user.GsbrCode, &user.NgDeviceId, &user.Email, &user.UniqueNick, &firstName, &lastName, &user.Restricted, &banReason, &user.OpenHost, &lastInGameSn, &lastIPAddress, &user.Csnum, &banModerator, &banHiddenReason, &user.BanIssued, &user.BanExpires)
if err != nil {
return User{}, false
return User{}, err
}
user.ProfileId = profileId
@ -179,7 +181,11 @@ func GetProfile(pool *pgxpool.Pool, ctx context.Context, profileId uint32) (User
user.BanModerator = *banModerator
}
return user, true
if banHiddenReason != nil {
user.BanReasonHidden = *banHiddenReason
}
return user, nil
}
func ClearProfile(pool *pgxpool.Pool, ctx context.Context, profileId uint32) (User, bool) {

View File

@ -31,8 +31,8 @@ func (g *GameSpySession) getProfile(command common.GameSpyCommand) {
mutex.Unlock()
} else {
mutex.Unlock()
user, ok = database.GetProfile(pool, ctx, uint32(profileId))
if !ok {
user, err = database.GetProfile(pool, ctx, uint32(profileId))
if err != nil {
// The profile info was requested on is invalid.
g.replyError(ErrGetProfileBadProfile)
return