From cfec099bdd73d292ab5e10537825ce832be5f79c Mon Sep 17 00:00:00 2001 From: ppeb Date: Sat, 24 Aug 2024 20:42:00 -0500 Subject: [PATCH] Add IP logging to ban, kick, unban --- api/ban.go | 36 +++++++++++++++++++----------------- api/kick.go | 22 +++++++++++++--------- api/unban.go | 21 ++++++++++++--------- database/user.go | 11 +++++++++++ 4 files changed, 55 insertions(+), 35 deletions(-) diff --git a/api/ban.go b/api/ban.go index f158eab..3fd177d 100644 --- a/api/ban.go +++ b/api/ban.go @@ -11,7 +11,7 @@ import ( ) func HandleBan(w http.ResponseWriter, r *http.Request) { - errorString := handleBanImpl(w, r) + errorString, ip := handleBanImpl(w, r) if errorString != "" { jsonData, _ := json.Marshal(map[string]string{"error": errorString}) w.Header().Set("Content-Type", "application/json") @@ -19,7 +19,7 @@ func HandleBan(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Length", strconv.Itoa(len(jsonData))) w.Write(jsonData) } else { - jsonData, _ := json.Marshal(map[string]string{"success": "true"}) + jsonData, _ := json.Marshal(map[string]string{"success": "true", "ip": ip}) w.Header().Set("Content-Type", "application/json") w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Content-Length", strconv.Itoa(len(jsonData))) @@ -27,42 +27,42 @@ func HandleBan(w http.ResponseWriter, r *http.Request) { } } -func handleBanImpl(w http.ResponseWriter, r *http.Request) string { +func handleBanImpl(w http.ResponseWriter, r *http.Request) (string, string) { // TODO: Actual authentication rather than a fixed secret // TODO: Use POST instead of GET u, err := url.Parse(r.URL.String()) if err != nil { - return "Bad request" + return "Bad request", "" } query, err := url.ParseQuery(u.RawQuery) if err != nil { - return "Bad request" + return "Bad request", "" } if apiSecret == "" || query.Get("secret") != apiSecret { - return "Invalid API secret" + return "Invalid API secret", "" } pidStr := query.Get("pid") if pidStr == "" { - return "Missing pid in request" + return "Missing pid in request", "" } pid, err := strconv.ParseUint(pidStr, 10, 32) if err != nil { - return "Invalid pid" + return "Invalid pid", "" } tosStr := query.Get("tos") if tosStr == "" { - return "Missing tos in request" + return "Missing tos in request", "" } tos, err := strconv.ParseBool(tosStr) if err != nil { - return "Invalid tos" + return "Invalid tos", "" } minutes := uint64(0) @@ -70,7 +70,7 @@ func handleBanImpl(w http.ResponseWriter, r *http.Request) string { minutesStr := query.Get("minutes") minutes, err = strconv.ParseUint(minutesStr, 10, 32) if err != nil { - return "Invalid minutes" + return "Invalid minutes", "" } } @@ -79,7 +79,7 @@ func handleBanImpl(w http.ResponseWriter, r *http.Request) string { hoursStr := query.Get("hours") hours, err = strconv.ParseUint(hoursStr, 10, 32) if err != nil { - return "Invalid hours" + return "Invalid hours", "" } } @@ -88,13 +88,13 @@ func handleBanImpl(w http.ResponseWriter, r *http.Request) string { daysStr := query.Get("days") days, err = strconv.ParseUint(daysStr, 10, 32) if err != nil { - return "Invalid days" + return "Invalid days", "" } } reason := query.Get("reason") if "reason" == "" { - return "Missing ban reason" + return "Missing ban reason", "" } // reason_hidden is optional @@ -107,13 +107,13 @@ func handleBanImpl(w http.ResponseWriter, r *http.Request) string { minutes = days*24*60 + hours*60 + minutes if minutes == 0 { - return "Missing ban length" + return "Missing ban length", "" } length := time.Duration(minutes) * time.Minute if !database.BanUser(pool, ctx, uint32(pid), tos, length, reason, reasonHidden, moderator) { - return "Failed to ban user" + return "Failed to ban user", "" } if tos { @@ -122,5 +122,7 @@ func handleBanImpl(w http.ResponseWriter, r *http.Request) string { gpcm.KickPlayer(uint32(pid), "restricted") } - return "" + ip := database.GetUserIP(pool, ctx, uint32(pid)) + + return "", ip } diff --git a/api/kick.go b/api/kick.go index 09e1c8b..bd9eb47 100644 --- a/api/kick.go +++ b/api/kick.go @@ -5,11 +5,12 @@ import ( "net/http" "net/url" "strconv" + "wwfc/database" "wwfc/gpcm" ) func HandleKick(w http.ResponseWriter, r *http.Request) { - errorString := handleKickImpl(w, r) + errorString, ip := handleKickImpl(w, r) if errorString != "" { jsonData, _ := json.Marshal(map[string]string{"error": errorString}) w.Header().Set("Content-Type", "application/json") @@ -17,7 +18,7 @@ func HandleKick(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Length", strconv.Itoa(len(jsonData))) w.Write(jsonData) } else { - jsonData, _ := json.Marshal(map[string]string{"success": "true"}) + jsonData, _ := json.Marshal(map[string]string{"success": "true", "ip": ip}) w.Header().Set("Content-Type", "application/json") w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Content-Length", strconv.Itoa(len(jsonData))) @@ -25,34 +26,37 @@ func HandleKick(w http.ResponseWriter, r *http.Request) { } } -func handleKickImpl(w http.ResponseWriter, r *http.Request) string { +func handleKickImpl(w http.ResponseWriter, r *http.Request) (string, string) { // TODO: Actual authentication rather than a fixed secret // TODO: Use POST instead of GET u, err := url.Parse(r.URL.String()) if err != nil { - return "Bad request" + return "Bad request", "" } query, err := url.ParseQuery(u.RawQuery) if err != nil { - return "Bad request" + return "Bad request", "" } if apiSecret == "" || query.Get("secret") != apiSecret { - return "Invalid API secret" + return "Invalid API secret", "" } pidStr := query.Get("pid") if pidStr == "" { - return "Missing pid in request" + return "Missing pid in request", "" } pid, err := strconv.ParseUint(pidStr, 10, 32) if err != nil { - return "Invalid pid" + return "Invalid pid", "" } gpcm.KickPlayer(uint32(pid), "moderator_kick") - return "" + + ip := database.GetUserIP(pool, ctx, uint32(pid)) + + return "", ip } diff --git a/api/unban.go b/api/unban.go index ad258f8..1e9e917 100644 --- a/api/unban.go +++ b/api/unban.go @@ -9,7 +9,7 @@ import ( ) func HandleUnban(w http.ResponseWriter, r *http.Request) { - errorString := handleUnbanImpl(w, r) + errorString, ip := handleUnbanImpl(w, r) if errorString != "" { jsonData, _ := json.Marshal(map[string]string{"error": errorString}) w.Header().Set("Content-Type", "application/json") @@ -17,7 +17,7 @@ func HandleUnban(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Length", strconv.Itoa(len(jsonData))) w.Write(jsonData) } else { - jsonData, _ := json.Marshal(map[string]string{"success": "true"}) + jsonData, _ := json.Marshal(map[string]string{"success": "true", "ip": ip}) w.Header().Set("Content-Type", "application/json") w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Content-Length", strconv.Itoa(len(jsonData))) @@ -25,34 +25,37 @@ func HandleUnban(w http.ResponseWriter, r *http.Request) { } } -func handleUnbanImpl(w http.ResponseWriter, r *http.Request) string { +func handleUnbanImpl(w http.ResponseWriter, r *http.Request) (string, string) { // TODO: Actual authentication rather than a fixed secret // TODO: Use POST instead of GET u, err := url.Parse(r.URL.String()) if err != nil { - return "Bad request" + return "Bad request", "" } query, err := url.ParseQuery(u.RawQuery) if err != nil { - return "Bad request" + return "Bad request", "" } if apiSecret == "" || query.Get("secret") != apiSecret { - return "Invalid API secret" + return "Invalid API secret", "" } pidStr := query.Get("pid") if pidStr == "" { - return "Missing pid in request" + return "Missing pid in request", "" } pid, err := strconv.ParseUint(pidStr, 10, 32) if err != nil { - return "Invalid pid" + return "Invalid pid", "" } database.UnbanUser(pool, ctx, uint32(pid)) - return "" + + ip := database.GetUserIP(pool, ctx, uint32(pid)) + + return "", ip } diff --git a/database/user.go b/database/user.go index 7fc2a77..691a772 100644 --- a/database/user.go +++ b/database/user.go @@ -16,6 +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` GetUser = `SELECT user_id, gsbrcd, email, unique_nick, firstname, lastname, open_host FROM users WHERE profile_id = $1` + GetUserLastIPAddress = `SELECT last_ip_address 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` @@ -147,6 +148,16 @@ func UnbanUser(pool *pgxpool.Pool, ctx context.Context, profileId uint32) bool { return err == nil } +func GetUserIP(pool *pgxpool.Pool, ctx context.Context, profileId uint32) string { + var ip string + err := pool.QueryRow(ctx, GetUserLastIPAddress, profileId).Scan(&ip) + if err != nil { + return "Unknown" + } + + return ip +} + func GetMKWFriendInfo(pool *pgxpool.Pool, ctx context.Context, profileId uint32) string { var info string err := pool.QueryRow(ctx, GetMKWFriendInfoQuery, profileId).Scan(&info)