feat: IP & device rate limits
This commit is contained in:
@@ -167,3 +167,68 @@ def test_phone_auth_request_rate_limit_returns_retry_after(client):
|
||||
data = second.json()
|
||||
assert "detail" in data
|
||||
assert data["retry_after_seconds"] > 0
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@override_settings(
|
||||
OTP_PROVIDER="console",
|
||||
OTP_MAX_PER_WINDOW=20,
|
||||
OTP_WINDOW_MINUTES=15,
|
||||
OTP_RESEND_COOLDOWN_SECONDS=0,
|
||||
PHONE_AUTH_RISK_WINDOW_MINUTES=15,
|
||||
PHONE_AUTH_IP_MAX_PER_WINDOW=2,
|
||||
PHONE_AUTH_DEVICE_MAX_PER_WINDOW=20,
|
||||
)
|
||||
def test_phone_auth_request_ip_throttle_returns_retry_after(client):
|
||||
with patch("apps.accounts.services.otp.generate_code", return_value="123456"):
|
||||
first = client.post(
|
||||
reverse("phone_auth_request"),
|
||||
{"phone_number": "0512345678", "channel": "sms"},
|
||||
content_type="application/json",
|
||||
REMOTE_ADDR="203.0.113.10",
|
||||
)
|
||||
assert first.status_code == 201
|
||||
|
||||
second = client.post(
|
||||
reverse("phone_auth_request"),
|
||||
{"phone_number": "0512345679", "channel": "sms"},
|
||||
content_type="application/json",
|
||||
REMOTE_ADDR="203.0.113.10",
|
||||
)
|
||||
assert second.status_code == 201
|
||||
|
||||
third = client.post(
|
||||
reverse("phone_auth_request"),
|
||||
{"phone_number": "0512345680", "channel": "sms"},
|
||||
content_type="application/json",
|
||||
REMOTE_ADDR="203.0.113.10",
|
||||
)
|
||||
|
||||
assert third.status_code == 429
|
||||
data = third.json()
|
||||
assert "detail" in data
|
||||
assert data["retry_after_seconds"] > 0
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@override_settings(
|
||||
OTP_PROVIDER="console",
|
||||
OTP_RESEND_COOLDOWN_SECONDS=0,
|
||||
OTP_MAX_PER_WINDOW=20,
|
||||
PHONE_AUTH_IP_MAX_PER_WINDOW=20,
|
||||
PHONE_AUTH_DEVICE_MAX_PER_WINDOW=20,
|
||||
)
|
||||
def test_phone_auth_request_persists_request_ip_and_device_signal(client):
|
||||
with patch("apps.accounts.services.otp.generate_code", return_value="123456"):
|
||||
response = client.post(
|
||||
reverse("phone_auth_request"),
|
||||
{"phone_number": "0512345678", "channel": "sms", "device_id": "device-abc"},
|
||||
content_type="application/json",
|
||||
REMOTE_ADDR="198.51.100.40",
|
||||
HTTP_USER_AGENT="pytest-agent",
|
||||
)
|
||||
|
||||
assert response.status_code == 201
|
||||
otp = PhoneOTP.objects.get(id=response.json()["request_id"])
|
||||
assert otp.request_ip == "198.51.100.40"
|
||||
assert otp.device_signal
|
||||
|
||||
Reference in New Issue
Block a user