Revert motd, clear, and user action response

This commit is contained in:
ppeb 2025-03-03 19:33:41 -06:00
parent ea56689f08
commit 3144bd7cf8
No known key found for this signature in database
GPG Key ID: CC147AD1B3D318D0
8 changed files with 57 additions and 288 deletions

View File

@ -11,33 +11,30 @@ import (
)
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(w, r)
success, err, statusCode = handleBanImpl(r)
} else {
err = "Incorrect request. POST or HEAD only."
err = "Incorrect request. POST only."
statusCode = http.StatusBadRequest
}
if user == nil {
user = &database.User{}
}
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
if r.Method == http.MethodHead {
w.WriteHeader(statusCode)
var jsonData []byte
if success {
jsonData, _ = json.Marshal(map[string]string{"success": "true"})
} else {
json, _ := json.Marshal(UserActionResponse{*user, success, err})
w.Header().Set("Content-Length", strconv.Itoa(len(json)))
w.WriteHeader(statusCode)
w.Write(json)
jsonData, _ = json.Marshal(map[string]string{"error": err})
}
w.Header().Set("Content-Length", strconv.Itoa(len(jsonData)))
w.WriteHeader(statusCode)
w.Write(jsonData)
}
type BanRequestSpec struct {
@ -52,30 +49,30 @@ type BanRequestSpec struct {
Moderator string
}
func handleBanImpl(w http.ResponseWriter, r *http.Request) (*database.User, bool, string, int) {
func handleBanImpl(r *http.Request) (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
return 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
return false, err.Error(), http.StatusBadRequest
}
if apiSecret == "" || req.Secret != apiSecret {
return nil, false, "Invalid API secret in request", http.StatusUnauthorized
return false, "Invalid API secret in request", http.StatusUnauthorized
}
if req.Pid == 0 {
return nil, false, "pid missing or 0 in request", http.StatusBadRequest
return false, "pid missing or 0 in request", http.StatusBadRequest
}
if req.Reason == "" {
return nil, false, "Missing ban reason in request", http.StatusBadRequest
return false, "Missing ban reason in request", http.StatusBadRequest
}
moderator := req.Moderator
@ -85,13 +82,13 @@ func handleBanImpl(w http.ResponseWriter, r *http.Request) (*database.User, bool
minutes := req.Days*24*60 + req.Hours*60 + req.Minutes
if minutes == 0 {
return nil, false, "Ban length missing or 0", http.StatusBadRequest
return false, "Ban length missing or 0", http.StatusBadRequest
}
length := time.Duration(minutes) * time.Minute
if !database.BanUser(pool, ctx, req.Pid, req.Tos, length, req.Reason, req.ReasonHidden, moderator) {
return nil, false, "Failed to ban user", http.StatusInternalServerError
return false, "Failed to ban user", http.StatusInternalServerError
}
gpcm.KickPlayerCustomMessage(req.Pid, req.Reason, gpcm.WWFCErrorMessage{
@ -105,14 +102,5 @@ func handleBanImpl(w http.ResponseWriter, r *http.Request) (*database.User, bool
},
})
var message string
user, success := database.GetProfile(pool, ctx, req.Pid)
if success {
message = ""
} else {
message = "Unable to query user data from the database"
}
return &user, success, message, http.StatusOK
return true, "", http.StatusOK
}

View File

@ -1,72 +0,0 @@
package api
import (
"encoding/json"
"io"
"net/http"
"strconv"
"wwfc/database"
)
func HandleClear(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 = handleClearImpl(w, r)
} else {
err = "Incorrect request. POST only."
statusCode = http.StatusBadRequest
}
if user == nil {
user = &database.User{}
}
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
if r.Method == http.MethodHead {
w.WriteHeader(statusCode)
} else {
json, _ := json.Marshal(UserActionResponse{*user, success, err})
w.Header().Set("Content-Length", strconv.Itoa(len(json)))
w.WriteHeader(statusCode)
w.Write(json)
}
}
type ClearRequestSpec struct {
Secret string
Pid uint32
}
func handleClearImpl(w http.ResponseWriter, 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 ClearRequestSpec
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
}
user, success := database.ClearProfile(pool, ctx, req.Pid)
if !success {
return nil, false, "Unable to query user data from the database", http.StatusInternalServerError
}
// Don't return empty JSON, this is placeholder for now.
return &user, true, "", http.StatusOK
}

View File

@ -5,38 +5,34 @@ import (
"io"
"net/http"
"strconv"
"wwfc/database"
"wwfc/gpcm"
)
func HandleKick(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 = handleKickImpl(w, r)
success, err, statusCode = handleKickImpl(r)
} else {
err = "Incorrect request. POST or HEAD only."
err = "Incorrect request. POST only."
statusCode = http.StatusBadRequest
}
if user == nil {
user = &database.User{}
}
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
if r.Method == http.MethodHead {
w.WriteHeader(statusCode)
var jsonData []byte
if success {
jsonData, _ = json.Marshal(map[string]string{"success": "true"})
} else {
json, _ := json.Marshal(UserActionResponse{*user, success, err})
w.Header().Set("Content-Length", strconv.Itoa(len(json)))
w.WriteHeader(statusCode)
w.Write(json)
jsonData, _ = json.Marshal(map[string]string{"error": err})
}
w.Header().Set("Content-Length", strconv.Itoa(len(jsonData)))
w.WriteHeader(statusCode)
w.Write(jsonData)
}
type KickRequestSpec struct {
@ -45,30 +41,30 @@ type KickRequestSpec struct {
Pid uint32
}
func handleKickImpl(w http.ResponseWriter, r *http.Request) (*database.User, bool, string, int) {
func handleKickImpl(r *http.Request) (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
return false, "Unable to read request body", http.StatusBadRequest
}
var req KickRequestSpec
err = json.Unmarshal(body, &req)
if err != nil {
return nil, false, err.Error(), http.StatusBadRequest
return false, err.Error(), http.StatusBadRequest
}
if apiSecret == "" || req.Secret != apiSecret {
return nil, false, "Invalid API secret in request", http.StatusUnauthorized
return false, "Invalid API secret in request", http.StatusUnauthorized
}
if req.Pid == 0 {
return nil, false, "pid missing or 0 in request", http.StatusBadRequest
return false, "pid missing or 0 in request", http.StatusBadRequest
}
if req.Reason == "" {
return nil, false, "Missing kick reason in request", http.StatusBadRequest
return false, "Missing kick reason in request", http.StatusBadRequest
}
gpcm.KickPlayerCustomMessage(req.Pid, "moderator_kick", gpcm.WWFCErrorMessage{
@ -82,14 +78,5 @@ func handleKickImpl(w http.ResponseWriter, r *http.Request) (*database.User, boo
},
})
var message string
user, success := database.GetProfile(pool, ctx, req.Pid)
if success {
message = ""
} else {
message = "Unable to query user data from the database"
}
return &user, success, message, http.StatusOK
return true, "", http.StatusOK
}

View File

@ -1,85 +0,0 @@
package api
import (
"encoding/json"
"io"
"net/http"
"strconv"
"wwfc/gpcm"
)
func HandleMotd(w http.ResponseWriter, r *http.Request) {
var motd string
var success bool
var err string
var statusCode int
switch r.Method {
case http.MethodGet:
_motd, motdErr := gpcm.GetMessageOfTheDay()
if motdErr != nil {
err = motdErr.Error()
statusCode = http.StatusInternalServerError
break
}
motd = _motd
success = true
statusCode = http.StatusOK
case http.MethodPost:
success, err, statusCode = handleMotdImpl(w, r)
default:
err = "Incorrect request. POST, GET, or HEAD only."
statusCode = http.StatusBadRequest
}
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
if r.Method == http.MethodHead {
w.WriteHeader(statusCode)
} else {
json, _ := json.Marshal(MotdResponse{motd, success, err})
w.Header().Set("Content-Length", strconv.Itoa(len(json)))
w.WriteHeader(statusCode)
w.Write(json)
}
}
type MotdRequestSpec struct {
Secret string
Motd string
}
type MotdResponse struct {
Motd string
Success bool
Error string
}
func handleMotdImpl(w http.ResponseWriter, r *http.Request) (bool, string, int) {
// TODO: Actual authentication rather than a fixed secret
body, err := io.ReadAll(r.Body)
if err != nil {
return false, "Unable to read request body", http.StatusBadRequest
}
var req MotdRequestSpec
err = json.Unmarshal(body, &req)
if err != nil {
return false, err.Error(), http.StatusBadRequest
}
if apiSecret == "" || req.Secret != apiSecret {
return false, "Invalid API secret in request", http.StatusUnauthorized
}
err = gpcm.SetMessageOfTheDay(req.Motd)
if err != nil {
return false, err.Error(), http.StatusInternalServerError
}
// Don't return empty JSON, this is placeholder for now.
return true, "", http.StatusOK
}

View File

@ -9,33 +9,30 @@ import (
)
func HandleUnban(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 = handleUnbanImpl(w, r)
success, err, statusCode = handleUnbanImpl(r)
} else {
err = "Incorrect request. POST or HEAD only."
err = "Incorrect request. POST only."
statusCode = http.StatusBadRequest
}
if user == nil {
user = &database.User{}
}
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
if r.Method == http.MethodHead {
w.WriteHeader(statusCode)
var jsonData []byte
if success {
jsonData, _ = json.Marshal(map[string]string{"success": "true"})
} else {
json, _ := json.Marshal(UserActionResponse{*user, success, err})
w.Header().Set("Content-Length", strconv.Itoa(len(json)))
w.WriteHeader(statusCode)
w.Write(json)
jsonData, _ = json.Marshal(map[string]string{"error": err})
}
w.Header().Set("Content-Length", strconv.Itoa(len(jsonData)))
w.WriteHeader(statusCode)
w.Write(jsonData)
}
type UnbanRequestSpec struct {
@ -43,40 +40,31 @@ type UnbanRequestSpec struct {
Pid uint32
}
func handleUnbanImpl(w http.ResponseWriter, r *http.Request) (*database.User, bool, string, int) {
func handleUnbanImpl(r *http.Request) (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
return false, "Unable to read request body", http.StatusBadRequest
}
var req UnbanRequestSpec
err = json.Unmarshal(body, &req)
if err != nil {
return nil, false, err.Error(), http.StatusBadRequest
return false, err.Error(), http.StatusBadRequest
}
if apiSecret == "" || req.Secret != apiSecret {
return nil, false, "Invalid API secret in request", http.StatusUnauthorized
return false, "Invalid API secret in request", http.StatusUnauthorized
}
if req.Pid == 0 {
return nil, false, "pid missing or 0 in request", http.StatusBadRequest
return false, "pid missing or 0 in request", http.StatusBadRequest
}
if !database.UnbanUser(pool, ctx, req.Pid) {
return nil, false, "Failed to unban user", http.StatusInternalServerError
return false, "Failed to unban user", http.StatusInternalServerError
}
var message string
user, success := database.GetProfile(pool, ctx, req.Pid)
if success {
message = ""
} else {
message = "Unable to query user data from the database"
}
return &user, success, message, http.StatusOK
return true, "", http.StatusOK
}

View File

@ -1,11 +0,0 @@
package api
import (
"wwfc/database"
)
type UserActionResponse struct {
User database.User
Success bool
Error string
}

View File

@ -1,33 +1,17 @@
package gpcm
import (
"errors"
"os"
)
var motdFilepath = "./motd.txt"
var motd string = ""
func GetMessageOfTheDay() (string, error) {
if motd == "" {
contents, err := os.ReadFile(motdFilepath)
if err != nil {
return "", err
}
motd = string(contents)
contents, err := os.ReadFile(motdFilepath)
if err != nil {
return "", err
}
return motd, nil
return string(contents), nil
}
func SetMessageOfTheDay(nmotd string) error {
if nmotd == "" {
return errors.New("Motd cannot be empty")
}
err := os.WriteFile(motdFilepath, []byte(nmotd), 0644)
motd = nmotd
return err
}

View File

@ -168,16 +168,6 @@ func handleRequest(w http.ResponseWriter, r *http.Request) {
return
}
if r.URL.Path == "/api/motd" {
api.HandleMotd(w, r)
return
}
if r.URL.Path == "/api/clear" {
api.HandleClear(w, r)
return
}
logging.Info("NAS", aurora.Yellow(r.Method), aurora.Cyan(r.URL), "via", aurora.Cyan(r.Host), "from", aurora.BrightCyan(r.RemoteAddr))
replyHTTPError(w, 404, "404 Not Found")
}