Rate limit public registration writes
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

This commit is contained in:
tegwick 2026-08-10 17:52:53 +02:00
parent cccca324c1
commit b80de5a1f4
6 changed files with 129 additions and 1 deletions

View file

@ -30,7 +30,7 @@ SECRET = "test-proxy-secret-with-adequate-length"
def invoke(
app, path, *, method="GET", claims=None, marker=SECRET, body=None,
form=None, cookie=None, headers=None, query="",
form=None, cookie=None, headers=None, query="", remote_addr="127.0.0.1",
):
payload = (
urlencode(form).encode()
@ -44,6 +44,7 @@ def invoke(
"CONTENT_LENGTH": str(len(payload)),
"wsgi.input": io.BytesIO(payload),
"HTTP_X_REQUEST_ID": "corr_test",
"REMOTE_ADDR": remote_addr,
}
if form is not None:
environ["CONTENT_TYPE"] = "application/x-www-form-urlencoded"
@ -370,6 +371,36 @@ class PortalApplicationTests(unittest.TestCase):
)
self.assertEqual("400 Bad Request", result["status"])
def test_public_registration_rate_limit_uses_peer_not_forwarded_header(self):
self.app.registration_verification = FakeRegistrationVerification()
self.app.registration_rate_limit = 2
self.app.registration_rate_window_seconds = 60
body = {
"username": "person", "email": "person@example.test",
"client_id": "unknown", "tenant": "tenant:coulomb",
}
first, _ = invoke(
self.app, "/api/v1/public/registrations", method="POST", body=body,
headers={"HTTP_X_FORWARDED_FOR": "198.51.100.1"},
)
second, _ = invoke(
self.app, "/api/v1/public/registrations", method="POST", body=body,
headers={"HTTP_X_FORWARDED_FOR": "198.51.100.2"},
)
limited, payload = invoke(
self.app, "/api/v1/public/registrations", method="POST", body=body,
headers={"HTTP_X_FORWARDED_FOR": "198.51.100.3"},
)
other_peer, _ = invoke(
self.app, "/api/v1/public/registrations", method="POST", body=body,
remote_addr="127.0.0.2",
)
self.assertEqual("400 Bad Request", first["status"])
self.assertEqual("400 Bad Request", second["status"])
self.assertEqual("429 Too Many Requests", limited["status"])
self.assertEqual("rate_limited", json.loads(payload)["error"]["code"])
self.assertEqual("400 Bad Request", other_peer["status"])
def test_provision_api_links_provider_subject(self):
self.app.provisioning = FakeProvisioning()
created, payload = invoke(