This commit is contained in:
@@ -157,10 +157,10 @@ index 48a487e..946d8cf 100644
|
||||
flusher.Flush()
|
||||
return
|
||||
diff --git a/internal/app/server_test.go b/internal/app/server_test.go
|
||||
index b56bb27..c9ab68e 100644
|
||||
index b56bb27..730e658 100644
|
||||
--- a/internal/app/server_test.go
|
||||
+++ b/internal/app/server_test.go
|
||||
@@ -1,7 +1,10 @@
|
||||
@@ -1,12 +1,16 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
@@ -171,7 +171,61 @@ index b56bb27..c9ab68e 100644
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
@@ -188,3 +191,74 @@ func TestParseClientIP(t *testing.T) {
|
||||
"strings"
|
||||
"testing"
|
||||
+ "time"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
@@ -101,6 +105,47 @@ func TestHandleOAuth_InvalidBody(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
+func useSingleRequestRateLimiter(t *testing.T) {
|
||||
+ t.Helper()
|
||||
+ previous := rateLimiter
|
||||
+ rateLimiter = &RateLimiter{
|
||||
+ requests: make(map[string][]time.Time),
|
||||
+ refunds: make(map[string][]time.Time),
|
||||
+ limit: 1,
|
||||
+ window: time.Hour,
|
||||
+ enabled: true,
|
||||
+ }
|
||||
+ t.Cleanup(func() { rateLimiter = previous })
|
||||
+}
|
||||
+
|
||||
+func setSpoofedClientHeaders(req *http.Request, suffix string) {
|
||||
+ req.Header.Set("Forwarded", "for=203.0.113."+suffix)
|
||||
+ req.Header.Set("X-Forwarded-For", "198.51.100."+suffix)
|
||||
+ req.Header.Set("X-Real-IP", "192.0.2."+suffix)
|
||||
+}
|
||||
+
|
||||
+func TestHandleOAuthRateLimitUsesDirectPeer(t *testing.T) {
|
||||
+ useSingleRequestRateLimiter(t)
|
||||
+
|
||||
+ first := httptest.NewRequest(http.MethodPost, "/oauth", strings.NewReader("invalid json"))
|
||||
+ first.RemoteAddr = "10.0.0.8:41001"
|
||||
+ setSpoofedClientHeaders(first, "11")
|
||||
+ firstResponse := httptest.NewRecorder()
|
||||
+ handleOAuth(firstResponse, first)
|
||||
+ if firstResponse.Code != http.StatusBadRequest {
|
||||
+ t.Fatalf("first status = %d, want %d", firstResponse.Code, http.StatusBadRequest)
|
||||
+ }
|
||||
+
|
||||
+ second := httptest.NewRequest(http.MethodPost, "/oauth", strings.NewReader("invalid json"))
|
||||
+ second.RemoteAddr = "10.0.0.8:41001"
|
||||
+ setSpoofedClientHeaders(second, "22")
|
||||
+ secondResponse := httptest.NewRecorder()
|
||||
+ handleOAuth(secondResponse, second)
|
||||
+ if secondResponse.Code != http.StatusTooManyRequests {
|
||||
+ t.Fatalf("second status = %d, want %d", secondResponse.Code, http.StatusTooManyRequests)
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
func TestHandleOAuth_MissingFields(t *testing.T) {
|
||||
body := `{"brand":"MyPeugeot","country":"","email":"","password":""}`
|
||||
req := httptest.NewRequest(http.MethodPost, "/oauth", strings.NewReader(body))
|
||||
@@ -188,3 +233,74 @@ func TestParseClientIP(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -354,7 +408,7 @@ index 00b9cf8..3dbe54a 100644
|
||||
// authorize URL's redirect_uri query parameter; the code-capture listener keys on
|
||||
// "<scheme>://".
|
||||
diff --git a/internal/app/worker_test.go b/internal/app/worker_test.go
|
||||
index e64964d..2a05a3b 100644
|
||||
index e64964d..7141640 100644
|
||||
--- a/internal/app/worker_test.go
|
||||
+++ b/internal/app/worker_test.go
|
||||
@@ -2,12 +2,81 @@ package app
|
||||
@@ -439,10 +493,32 @@ index e64964d..2a05a3b 100644
|
||||
func TestHandleWorker_MethodNotAllowed(t *testing.T) {
|
||||
req := httptest.NewRequest(http.MethodGet, "/worker", nil)
|
||||
w := httptest.NewRecorder()
|
||||
@@ -30,6 +99,25 @@ func TestHandleWorker_InvalidBody(t *testing.T) {
|
||||
@@ -30,6 +99,47 @@ func TestHandleWorker_InvalidBody(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
+func TestHandleWorkerRateLimitUsesDirectPeer(t *testing.T) {
|
||||
+ useSingleRequestRateLimiter(t)
|
||||
+
|
||||
+ first := httptest.NewRequest(http.MethodPost, "/worker", strings.NewReader("invalid json"))
|
||||
+ first.RemoteAddr = "10.0.0.9:41002"
|
||||
+ setSpoofedClientHeaders(first, "33")
|
||||
+ firstResponse := httptest.NewRecorder()
|
||||
+ handleWorker(firstResponse, first)
|
||||
+ if firstResponse.Code != http.StatusBadRequest {
|
||||
+ t.Fatalf("first status = %d, want %d", firstResponse.Code, http.StatusBadRequest)
|
||||
+ }
|
||||
+
|
||||
+ second := httptest.NewRequest(http.MethodPost, "/worker", strings.NewReader("invalid json"))
|
||||
+ second.RemoteAddr = "10.0.0.9:41002"
|
||||
+ setSpoofedClientHeaders(second, "44")
|
||||
+ secondResponse := httptest.NewRecorder()
|
||||
+ handleWorker(secondResponse, second)
|
||||
+ if secondResponse.Code != http.StatusTooManyRequests {
|
||||
+ t.Fatalf("second status = %d, want %d", secondResponse.Code, http.StatusTooManyRequests)
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+func TestHandleWorker_RequestTooLarge(t *testing.T) {
|
||||
+ body := `{"url":"` + strings.Repeat("x", 65<<10) + `"}`
|
||||
+ req := httptest.NewRequest(http.MethodPost, "/worker", strings.NewReader(body))
|
||||
@@ -465,7 +541,7 @@ index e64964d..2a05a3b 100644
|
||||
func TestHandleWorker_MissingParams(t *testing.T) {
|
||||
body := `{"url":"","email":"","password":""}`
|
||||
req := httptest.NewRequest(http.MethodPost, "/worker", strings.NewReader(body))
|
||||
@@ -83,7 +171,7 @@ func TestRedirectScheme(t *testing.T) {
|
||||
@@ -83,7 +193,7 @@ func TestRedirectScheme(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "opel custom scheme",
|
||||
|
||||
Reference in New Issue
Block a user