Authorization-code flow with PKCE through an idp adapter (with a fake), ID token validation, identity and roles resolved from the directory with a short cache, refusal of unknown, disabled and locked accounts with one generic page, sessions that end when the account becomes unavailable, sign-out that ends the server-side session, role decorators and the trusted-proxy client address rule. Adds the OIDC_* and PUBLIC_BASE_URL configuration. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N3t4WL7bd9bdHHNjEsxzqC
36 lines
1.2 KiB
Python
36 lines
1.2 KiB
Python
"""The client address, trusting X-Forwarded-For only from configured proxies (AD-7)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import ipaddress
|
|
from collections.abc import Iterable
|
|
|
|
Network = ipaddress.IPv4Network | ipaddress.IPv6Network
|
|
|
|
|
|
def parse_networks(items: Iterable[str]) -> list[Network]:
|
|
return [ipaddress.ip_network(item, strict=False) for item in items]
|
|
|
|
|
|
def _address(value: str) -> ipaddress.IPv4Address | ipaddress.IPv6Address | None:
|
|
try:
|
|
return ipaddress.ip_address(value.strip())
|
|
except ValueError:
|
|
return None
|
|
|
|
|
|
def client_ip(peer: str, forwarded_for: str, trusted: list[Network]) -> str:
|
|
"""The TCP peer, or the last X-Forwarded-For entry when the peer is a trusted proxy.
|
|
|
|
The last entry is the one the proxy appended itself; earlier ones come from the client and
|
|
can be forged. X-Real-IP is never used.
|
|
"""
|
|
peer_address = _address(peer)
|
|
if peer_address is None:
|
|
return ""
|
|
if not any(peer_address in network for network in trusted):
|
|
return str(peer_address)
|
|
last = forwarded_for.rsplit(",", 1)[-1] if forwarded_for else ""
|
|
forwarded = _address(last)
|
|
return str(forwarded) if forwarded is not None else str(peer_address)
|