feat: login IP whitelist, blocks UI and fail2ban sync (0.4.1)
Admin settings for web login whitelist, blocked IP list with unblock, and optional fail2ban ignoreip sync for SSH jail. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -12,6 +12,10 @@ from sqlalchemy.orm import Session
|
||||
|
||||
from app.config import get_settings
|
||||
from app.models.login_attempt import LoginAttempt
|
||||
from app.services.login_security_settings import (
|
||||
get_effective_login_security_config,
|
||||
is_ip_login_whitelisted,
|
||||
)
|
||||
from app.services.telegram_notify import send_telegram_text
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -91,6 +95,9 @@ def ensure_login_allowed(db: Session, request: Request) -> str:
|
||||
"""Raise 429 if IP exceeded failed login threshold. Returns client IP."""
|
||||
cfg = get_login_rate_limit_config()
|
||||
ip_address = client_ip_from_request(request)
|
||||
sec = get_effective_login_security_config(db)
|
||||
if is_ip_login_whitelisted(ip_address, sec.ip_whitelist):
|
||||
return ip_address
|
||||
since = datetime.now(timezone.utc) - timedelta(minutes=cfg.window_minutes)
|
||||
failures = _failure_count(db, ip_address, since=since)
|
||||
if failures >= cfg.max_failures:
|
||||
@@ -119,6 +126,9 @@ def record_login_failure(
|
||||
request: Request | None = None,
|
||||
) -> None:
|
||||
del request # reserved
|
||||
sec = get_effective_login_security_config(db)
|
||||
if is_ip_login_whitelisted(ip_address, sec.ip_whitelist):
|
||||
return
|
||||
cfg = get_login_rate_limit_config()
|
||||
since = datetime.now(timezone.utc) - timedelta(minutes=cfg.window_minutes)
|
||||
prior_failures = _failure_count(db, ip_address, since=since)
|
||||
|
||||
Reference in New Issue
Block a user