"""Login security whitelist and unblock.""" from datetime import datetime, timezone from sqlalchemy import delete from app.models.login_attempt import LoginAttempt from app.services.login_security_settings import ( clear_web_login_block, get_effective_login_security_config, is_ip_login_whitelisted, list_web_login_blocks, parse_ip_whitelist_text, upsert_login_security_settings, ) def test_parse_ip_whitelist_text(): assert parse_ip_whitelist_text("192.168.160.3\n192.168.160.4") == [ "192.168.160.3", "192.168.160.4", ] assert parse_ip_whitelist_text("192.168.160.3, 10.0.0.1") == [ "192.168.160.3", "10.0.0.1", ] assert parse_ip_whitelist_text("not-an-ip\n192.168.1.1") == ["192.168.1.1"] def test_whitelisted_ip_not_blocked(client, db_session, monkeypatch): monkeypatch.setenv("SAC_LOGIN_MAX_FAILURES", "2") monkeypatch.setenv("SAC_LOGIN_ALERT_TELEGRAM", "false") monkeypatch.setattr( "app.services.login_rate_limit.client_ip_from_request", lambda _request: "192.168.160.3", ) from app.config import get_settings get_settings.cache_clear() db_session.execute(delete(LoginAttempt)) db_session.commit() upsert_login_security_settings( db_session, ip_whitelist_text="192.168.160.3", sync_fail2ban=False, ) for _ in range(5): r = client.post( "/api/v1/auth/login", json={"username": "test-admin", "password": "wrong"}, ) assert r.status_code == 401 get_settings.cache_clear() def test_list_web_blocks_and_clear(db_session, monkeypatch): monkeypatch.setenv("SAC_LOGIN_MAX_FAILURES", "2") monkeypatch.setenv("SAC_LOGIN_FAILURE_WINDOW_MINUTES", "15") from app.config import get_settings get_settings.cache_clear() now = datetime.now(timezone.utc) db_session.add( LoginAttempt(ip_address="203.0.113.50", username="bad", success=False, created_at=now) ) db_session.add( LoginAttempt(ip_address="203.0.113.50", username="bad", success=False, created_at=now) ) db_session.commit() blocks = list_web_login_blocks(db_session) assert any(b.ip_address == "203.0.113.50" for b in blocks) deleted = clear_web_login_block(db_session, "203.0.113.50") assert deleted >= 2 assert not list_web_login_blocks(db_session) get_settings.cache_clear() def test_is_ip_login_whitelisted(): wl = ("192.168.160.3",) assert is_ip_login_whitelisted("192.168.160.3", wl) assert not is_ip_login_whitelisted("192.168.160.4", wl)