Aug 20 - Session tenant binding

This commit is contained in:
2026-08-20 14:24:41 -04:00
parent 8b2582705d
commit 54a4a44bae
10 changed files with 325 additions and 13 deletions
+18 -1
View File
@@ -18,8 +18,25 @@ login_manager = LoginManager()
migrate = Migrate()
mail = Mail()
csrf = CSRFProtect() # initialized here; .init_app() called in create_app()
def _rate_limit_key():
"""MT-21: scope rate-limit buckets per tenant as well as per client IP.
With a bare remote-address key, two tenants behind the same NAT egress
share every route's counter, so one tenant's traffic can lock another out
of (for example) /auth/login. Falls back to the plain address in
single-tenant mode and on tenant-exempt paths, leaving today's buckets
unchanged there.
"""
from flask import g, has_request_context
addr = get_remote_address()
if not has_request_context():
return addr
tenant = getattr(g, 'tenant', None)
return f't{tenant.id}|{addr}' if tenant is not None else addr
limiter = Limiter(
key_func = get_remote_address,
key_func = _rate_limit_key,
default_limits = [], # no global limit — applied per-route only
# Use Redis when REDIS_URL is set in the environment (production multi-worker).
# Falls back to in-process memory for local development (single-worker only;