wfc-server/api/ban.go
ppeb 41f7fddc4d
Revert "Revert motd, clear, and user action response"
This reverts commit 3144bd7cf8.

The reason this commit had to be made was because certain apis were PR'd
upstream, but were unwanted and thus removed in a separate commit. It
would likely have been better to drop the commits pushed upstream but
it's too late to fix that, so now we have a revert of a revert.
2025-03-05 20:33:20 -06:00

121 lines
3.2 KiB
Go

package api
import (
"encoding/json"
"io"
"net/http"
"strconv"
"time"
"wwfc/database"
"wwfc/gpcm"
"wwfc/logging"
"github.com/logrusorgru/aurora/v3"
)
func HandleBan(w http.ResponseWriter, r *http.Request) {
var user *database.User
var success bool
var err string
var statusCode int
if r.Method == http.MethodPost {
user, success, err, statusCode = handleBanImpl(r)
} else if r.Method == http.MethodOptions {
statusCode = http.StatusNoContent
w.Header().Set("Access-Control-Allow-Methods", "POST")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
} else {
err = "Incorrect request. POST only."
statusCode = http.StatusMethodNotAllowed
w.Header().Set("Allow", "POST")
}
w.Header().Set("Access-Control-Allow-Origin", "*")
if user == nil {
user = &database.User{}
}
var jsonData []byte
if statusCode != http.StatusNoContent {
w.Header().Set("Content-Type", "application/json")
jsonData, _ = json.Marshal(UserActionResponse{*user, success, err})
}
w.Header().Set("Content-Length", strconv.Itoa(len(jsonData)))
w.WriteHeader(statusCode)
w.Write(jsonData)
}
type BanRequestSpec struct {
Secret string `json:"secret"`
ProfileID uint32 `json:"pid"`
Days uint64 `json:"days"`
Hours uint64 `json:"hours"`
Minutes uint64 `json:"minutes"`
Tos bool `json:"tos"`
Reason string `json:"reason"`
ReasonHidden string `json:"reason_hidden"`
Moderator string `json:"moderator"`
}
func handleBanImpl(r *http.Request) (*database.User, bool, string, int) {
// TODO: Actual authentication rather than a fixed secret
body, err := io.ReadAll(r.Body)
if err != nil {
return nil, false, "Unable to read request body", http.StatusBadRequest
}
var req BanRequestSpec
err = json.Unmarshal(body, &req)
if err != nil {
return nil, false, err.Error(), http.StatusBadRequest
}
if apiSecret == "" || req.Secret != apiSecret {
return nil, false, "Invalid API secret in request", http.StatusUnauthorized
}
if req.ProfileID == 0 {
return nil, false, "Profile ID missing or 0 in request", http.StatusBadRequest
}
if req.Reason == "" {
return nil, false, "Missing ban reason in request", http.StatusBadRequest
}
moderator := req.Moderator
if moderator == "" {
moderator = "admin"
}
minutes := req.Days*24*60 + req.Hours*60 + req.Minutes
if minutes == 0 {
return nil, false, "Ban length missing or 0", http.StatusBadRequest
}
length := time.Duration(minutes) * time.Minute
logging.Notice("API:"+moderator, "Ban profile:", aurora.Cyan(req.ProfileID), "TOS:", aurora.Cyan(req.Tos), "Length:", aurora.Cyan(length), "Reason:", aurora.BrightCyan(req.Reason), "Reason (Hidden):", aurora.BrightCyan(req.ReasonHidden))
if !database.BanUser(pool, ctx, req.ProfileID, req.Tos, length, req.Reason, req.ReasonHidden, moderator) {
return nil, false, "Failed to ban user", http.StatusInternalServerError
}
gpcm.KickPlayerCustomMessage(req.ProfileID, req.Reason, gpcm.WWFCMsgProfileRestrictedCustom)
var message string
user, success := database.GetProfile(pool, ctx, req.ProfileID)
if success {
message = ""
} else {
message = "Unable to query user data from the database"
}
return &user, success, message, http.StatusOK
}