Skip to content

Commit b70c693

Browse files
committed
API: Reformat API error responses
1 parent 51610cb commit b70c693

6 files changed

Lines changed: 38 additions & 22 deletions

File tree

api/ban.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func HandleBan(w http.ResponseWriter, r *http.Request) {
3434
}
3535

3636
if req.Reason == "" {
37-
replyError(w, http.StatusBadRequest, APIErrorInvalidBanReason)
37+
replyError(w, http.StatusBadRequest, APIErrorInvalidReason)
3838
return
3939
}
4040

@@ -51,8 +51,6 @@ func HandleBan(w http.ResponseWriter, r *http.Request) {
5151

5252
length := time.Duration(minutes) * time.Minute
5353

54-
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))
55-
5654
if !db.BanUser(req.ProfileID, req.Tos, length, req.Reason, req.ReasonHidden, moderator) {
5755
replyError(w, http.StatusInternalServerError, APIErrorBanFailed)
5856
return
@@ -70,4 +68,6 @@ func HandleBan(w http.ResponseWriter, r *http.Request) {
7068
"reason_hidden": req.ReasonHidden,
7169
"moderator": moderator,
7270
})
71+
72+
logging.Notice("API:"+moderator, "Ban:", aurora.Cyan(req.ProfileID), "TOS:", aurora.Cyan(req.Tos), "Length:", aurora.Cyan(length), "Reason:", aurora.BrightCyan(req.Reason), "Reason (Hidden):", aurora.BrightCyan(req.ReasonHidden))
7373
}

api/baninfo.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func HandleBanInfo(w http.ResponseWriter, r *http.Request) {
2626

2727
search := query.Get("q")
2828
if search == "" {
29-
replyError(w, http.StatusBadRequest, APIErrorInvalidBanQuery)
29+
replyError(w, http.StatusBadRequest, APIErrorInvalidQuery)
3030
return
3131
}
3232

@@ -37,14 +37,14 @@ func HandleBanInfo(w http.ResponseWriter, r *http.Request) {
3737
if strings.HasPrefix(search, "NG") {
3838
ngId, err := strconv.ParseUint(search[2:], 16, 32)
3939
if err != nil {
40-
replyError(w, http.StatusBadRequest, APIErrorInvalidBanQuery)
40+
replyError(w, http.StatusBadRequest, APIErrorInvalidQuery)
4141
return
4242
}
4343
ngDeviceId = uint32(ngId)
4444
} else {
4545
pId, err := strconv.ParseUint(search, 10, 64)
4646
if err != nil {
47-
replyError(w, http.StatusBadRequest, APIErrorInvalidBanQuery)
47+
replyError(w, http.StatusBadRequest, APIErrorInvalidQuery)
4848
return
4949
}
5050
// Truncate to 32 bits as that's how friend codes work

api/groups.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ func HandleGroups(w http.ResponseWriter, r *http.Request) {
1414
groups := qr2.GetGroups(query["game"], query["id"], true)
1515

1616
if len(groups) == 0 {
17+
// I would return No Content, but here is compatibility
1718
replyOK(w, "[]")
1819
return
1920
}

api/kick.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"net/http"
55
"wwfc/gpcm"
66
"wwfc/logging"
7+
8+
"github.com/logrusorgru/aurora/v3"
79
)
810

911
type KickRequestSpec struct {
@@ -24,7 +26,7 @@ func HandleKick(w http.ResponseWriter, r *http.Request) {
2426
}
2527

2628
if req.Reason == "" {
27-
replyError(w, http.StatusBadRequest, APIErrorInvalidBanReason)
29+
replyError(w, http.StatusBadRequest, APIErrorInvalidReason)
2830
return
2931
}
3032

@@ -36,4 +38,6 @@ func HandleKick(w http.ResponseWriter, r *http.Request) {
3638
"profile_id": req.ProfileID,
3739
"reason": req.Reason,
3840
})
41+
42+
logging.Notice("API:admin", "Kick:", aurora.Cyan(req.ProfileID), "Reason:", aurora.BrightCyan(req.Reason))
3943
}

api/unban.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package api
33
import (
44
"net/http"
55
"wwfc/logging"
6+
7+
"github.com/logrusorgru/aurora/v3"
68
)
79

810
type UnbanRequestSpec struct {
@@ -31,4 +33,6 @@ func HandleUnban(w http.ResponseWriter, r *http.Request) {
3133
logging.Event("profile_unbanned", map[string]any{
3234
"profile_id": req.ProfileID,
3335
})
36+
37+
logging.Notice("API:admin", "Unban:", aurora.Cyan(req.ProfileID))
3438
}

api/util.go

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,14 @@ import (
1313
type APIErrorString string
1414

1515
const (
16-
APIErrorAuthenticationFailed APIErrorString = "AuthenticationFailed"
17-
APIErrorInvalidQuery APIErrorString = "InvalidQuery"
18-
APIErrorInvalidProfileID APIErrorString = "InvalidProfileID"
19-
APIErrorInvalidBanReason APIErrorString = "InvalidBanReason"
20-
APIErrorInvalidBanLength APIErrorString = "InvalidBanLength"
21-
APIErrorBanFailed APIErrorString = "BanFailed"
22-
APIErrorUnbanFailed APIErrorString = "UnbanFailed"
23-
APIErrorInvalidBanQuery APIErrorString = "InvalidBanQuery"
24-
APIErrorBanNotFound APIErrorString = "BanNotFound"
16+
APIErrorFailedAuthentication APIErrorString = "failed_authentication"
17+
APIErrorInvalidQuery APIErrorString = "invalid_query"
18+
APIErrorInvalidProfileID APIErrorString = "invalid_profile_id"
19+
APIErrorInvalidReason APIErrorString = "invalid_reason"
20+
APIErrorInvalidBanLength APIErrorString = "invalid_ban_length"
21+
APIErrorBanFailed APIErrorString = "ban_failed"
22+
APIErrorUnbanFailed APIErrorString = "unban_failed"
23+
APIErrorBanNotFound APIErrorString = "ban_not_found"
2524
)
2625

2726
type APIError struct {
@@ -80,7 +79,7 @@ func parseGet(r *http.Request, w http.ResponseWriter, requiredRole Role) (query
8079

8180
authInfo := makeAuthInfo(query)
8281
if !authenticate(authInfo, requiredRole) {
83-
replyError(w, http.StatusUnauthorized, APIErrorAuthenticationFailed)
82+
replyError(w, http.StatusUnauthorized, APIErrorFailedAuthentication)
8483
return nil, errAuthFailed
8584
}
8685
return query, nil
@@ -127,7 +126,7 @@ func parsePost(r *http.Request, w http.ResponseWriter, parsed any, requiredRole
127126
return errNoAuthInfo
128127
}
129128
if !authenticate(authInfo, requiredRole) {
130-
replyError(w, http.StatusUnauthorized, APIErrorAuthenticationFailed)
129+
replyError(w, http.StatusUnauthorized, APIErrorFailedAuthentication)
131130
return errAuthFailed
132131
}
133132
return nil
@@ -159,11 +158,19 @@ func replyOK(w http.ResponseWriter, data any) {
159158
}
160159

161160
w.Header().Set("Content-Type", "application/json")
162-
jsonData, err := json.Marshal(data)
163-
if err != nil {
164-
w.WriteHeader(http.StatusInternalServerError)
165-
return
161+
var jsonData []byte
162+
if reflect.ValueOf(data).Kind() == reflect.String {
163+
// Assume it's already JSON
164+
jsonData = []byte(data.(string))
165+
} else {
166+
var err error
167+
jsonData, err = json.Marshal(data)
168+
if err != nil {
169+
w.WriteHeader(http.StatusInternalServerError)
170+
return
171+
}
166172
}
173+
167174
w.Header().Set("Content-Length", strconv.Itoa(len(jsonData)))
168175
_, _ = w.Write(jsonData)
169176
}

0 commit comments

Comments
 (0)