34 lines
1 KiB
Python
34 lines
1 KiB
Python
from app.auth.rate_limit import SlidingWindowRateLimiter
|
|
from app.auth.security import PasswordService
|
|
|
|
|
|
def test_password_service_hash_and_verify_round_trip() -> None:
|
|
password_service = PasswordService()
|
|
password_hash = password_service.hash_password("example-password")
|
|
|
|
assert password_hash.startswith("$argon2id$")
|
|
assert password_service.verify_password(password_hash, "example-password")
|
|
assert not password_service.verify_password(password_hash, "wrong-password")
|
|
|
|
|
|
def test_rate_limiter_enforces_windowed_attempt_budget() -> None:
|
|
clock = {"now": 0.0}
|
|
limiter = SlidingWindowRateLimiter(
|
|
max_attempts=2,
|
|
window_seconds=10,
|
|
now=lambda: clock["now"],
|
|
)
|
|
key = "127.0.0.1:test@example.com"
|
|
|
|
assert limiter.check(key).allowed
|
|
limiter.record_failure(key)
|
|
assert limiter.check(key).allowed
|
|
limiter.record_failure(key)
|
|
|
|
decision = limiter.check(key)
|
|
assert not decision.allowed
|
|
assert decision.retry_after_seconds == 10
|
|
|
|
clock["now"] = 11.0
|
|
assert limiter.check(key).allowed
|
|
|