Send verify response instead of http code for sitekey verification

This commit is contained in:
Taras Kushnir
2025-12-02 21:42:01 +01:00
parent 1ac836c713
commit cbab265d85
4 changed files with 39 additions and 6 deletions

View File

@@ -4,6 +4,7 @@ import (
"bytes"
"context"
"encoding/hex"
"encoding/json"
"errors"
"io"
"log/slog"
@@ -43,8 +44,21 @@ var (
headersContentPlain = map[string][]string{
http.CanonicalHeaderKey(common.HeaderContentType): []string{common.ContentTypePlain},
}
invalidPropertyResponse []byte
)
func init() {
var err error
vr := &VerificationResponse{
Success: false,
Code: puzzle.InvalidPropertyError,
}
invalidPropertyResponse, err = json.Marshal(vr)
if err != nil {
panic(err)
}
}
type Server struct {
APIHeaders map[string][]string
Stage string
@@ -282,7 +296,7 @@ func (s *Server) recaptchaVerifyHandler(w http.ResponseWriter, r *http.Request)
propertyID := payload.Puzzle().PropertyID()
if propertyExternalID := db.UUIDFromSiteKey(sitekey); !bytes.Equal(propertyExternalID.Bytes[:], propertyID[:]) {
slog.WarnContext(ctx, "Expected property ID does not match", "expected", sitekey, "actual", hex.EncodeToString(propertyID[:]))
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
common.SendReponse(ctx, w, invalidPropertyResponse, common.JSONContentHeaders, common.NoCacheHeaders, s.APIHeaders)
return
}
}
@@ -353,7 +367,7 @@ func (s *Server) pcVerifyHandler(w http.ResponseWriter, r *http.Request) {
propertyID := payload.Puzzle().PropertyID()
if propertyExternalID := db.UUIDFromSiteKey(sitekey); !bytes.Equal(propertyExternalID.Bytes[:], propertyID[:]) {
slog.WarnContext(ctx, "Expected property ID does not match", "expected", sitekey, "actual", hex.EncodeToString(propertyID[:]))
http.Error(w, "Expected sitekey does not match solution puzzle", http.StatusBadRequest)
common.SendReponse(ctx, w, invalidPropertyResponse, common.JSONContentHeaders, common.NoCacheHeaders, s.APIHeaders)
return
}
}

View File

@@ -186,8 +186,8 @@ func TestVerifyPuzzleWrongExpectedSitekey(t *testing.T) {
t.Fatal(err)
}
if resp.StatusCode != http.StatusBadRequest {
t.Errorf("Unexpected submit status code %d", resp.StatusCode)
if err := checkSiteVerifyError(resp, puzzle.InvalidPropertyError); err != nil {
t.Fatal(err)
}
}
@@ -226,8 +226,8 @@ func TestSiteVerifyWrongExpectedSitekey(t *testing.T) {
t.Fatal(err)
}
if resp.StatusCode != http.StatusBadRequest {
t.Errorf("Unexpected submit status code %d", resp.StatusCode)
if err := checkSiteVerifyError(resp, puzzle.InvalidPropertyError); err != nil {
t.Fatal(err)
}
}

View File

@@ -42,6 +42,9 @@ var (
HtmlContentHeaders = map[string][]string{
http.CanonicalHeaderKey(HeaderContentType): []string{ContentTypeHTML},
}
JSONContentHeaders = map[string][]string{
http.CanonicalHeaderKey(HeaderContentType): []string{ContentTypeJSON},
}
)
func NoopMiddleware(next http.Handler) http.Handler {

View File

@@ -68,6 +68,22 @@ func MaskEmail(email string, mask rune) string {
return prefix + xxx + suffix + "@" + parts[1]
}
func SendReponse(ctx context.Context, w http.ResponseWriter, response []byte, headers ...map[string][]string) {
wHeader := w.Header()
for _, hh := range headers {
for key, value := range hh {
wHeader[key] = value
}
}
n, err := w.Write(response)
if err != nil {
slog.ErrorContext(ctx, "Failed to send response", ErrAttr(err))
} else {
slog.Log(ctx, LevelTrace, "Sent response", "size", len(response), "sent", n)
}
}
func SendJSONResponse(ctx context.Context, w http.ResponseWriter, data interface{}, headers ...map[string][]string) {
response, err := json.Marshal(data)
if err != nil {