Remove get_session_context setting of host (now read only op as expected). Make session host, ip and user_agent always set (the ua potentially empty string).

This commit is contained in:
2026-01-28 02:14:34 +00:00
parent d156fb9221
commit d3d5f5a3c8
6 changed files with 35 additions and 35 deletions
+19 -19
View File
@@ -41,16 +41,21 @@ _logger = logging.getLogger(__name__)
_db = DB() _db = DB()
_store = JsonlStore(_db) _store = JsonlStore(_db)
_db._store = _store _db._store = _store
_initialized = False
async def init(*args, **kwargs): async def init(*args, **kwargs):
"""Load database from JSONL file.""" """Load database from JSONL file."""
global _db global _db, _initialized
if _initialized:
_logger.debug("Database already initialized, skipping reload")
return
db_path = os.environ.get("PASKIA_DB", DB_PATH_DEFAULT) db_path = os.environ.get("PASKIA_DB", DB_PATH_DEFAULT)
if db_path.startswith("json:"): if db_path.startswith("json:"):
db_path = db_path[5:] db_path = db_path[5:]
await _store.load(db_path) await _store.load(db_path)
_db = _store.db _db = _store.db
_initialized = True
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
@@ -150,15 +155,10 @@ def get_session_context(
if s.expiry < datetime.now(timezone.utc): if s.expiry < datetime.now(timezone.utc):
return None return None
# Handle host binding # Validate host matches (sessions are always created with a host)
if host is not None: if host is not None and s.host != host:
if s.host is None: # Session bound to different host
# Bind session to this host return None
with _db.transaction("bind_session_host"):
s.host = host
elif s.host != host:
# Session bound to different host
return None
# Validate user exists # Validate user exists
if s.user not in _db.users: if s.user not in _db.users:
@@ -558,9 +558,9 @@ def create_session(
key: str, key: str,
user_uuid: UUID, user_uuid: UUID,
credential_uuid: UUID, credential_uuid: UUID,
host: str | None, host: str,
ip: str | None, ip: str,
user_agent: str | None, user_agent: str,
expiry: datetime, expiry: datetime,
*, *,
ctx: SessionContext | None = None, ctx: SessionContext | None = None,
@@ -708,9 +708,9 @@ def _create_token() -> str:
def login( def login(
user_uuid: UUID, user_uuid: UUID,
credential: Credential, credential: Credential,
host: str | None, host: str,
ip: str | None, ip: str,
user_agent: str | None, user_agent: str,
expiry: datetime, expiry: datetime,
) -> str: ) -> str:
"""Update user/credential on login and create session in a single transaction. """Update user/credential on login and create session in a single transaction.
@@ -755,9 +755,9 @@ def login(
def create_credential_session( def create_credential_session(
user_uuid: UUID, user_uuid: UUID,
credential: Credential, credential: Credential,
host: str | None, host: str,
ip: str | None, ip: str,
user_agent: str | None, user_agent: str,
display_name: str | None = None, display_name: str | None = None,
reset_key: bytes | None = None, reset_key: bytes | None = None,
) -> str: ) -> str:
+3 -3
View File
@@ -190,9 +190,9 @@ class Session(msgspec.Struct, dict=True):
user: UUID user: UUID
credential: UUID credential: UUID
host: str | None host: str
ip: str | None ip: str
user_agent: str | None user_agent: str
expiry: datetime expiry: datetime
def __post_init__(self): def __post_init__(self):
+2 -2
View File
@@ -19,8 +19,8 @@ AUTH_COOKIE = Cookie(None, alias=AUTH_COOKIE_NAME)
def infodict(request: Request | WebSocket, type: str) -> dict: def infodict(request: Request | WebSocket, type: str) -> dict:
"""Extract client information from request.""" """Extract client information from request."""
return { return {
"ip": request.client.host if request.client else None, "ip": request.client.host if request.client else "",
"user_agent": request.headers.get("user-agent", "")[:500] or None, "user_agent": request.headers.get("user-agent", "")[:500],
"session_type": type, "session_type": type,
} }
+4 -4
View File
@@ -65,8 +65,8 @@ async def websocket_register_add(
reset_key=(s.key if reset is not None else None), reset_key=(s.key if reset is not None else None),
display_name=user_name, display_name=user_name,
host=host, host=host,
ip=metadata.get("ip"), ip=metadata["ip"],
user_agent=metadata.get("user_agent"), user_agent=metadata["user_agent"],
) )
auth = token auth = token
@@ -117,8 +117,8 @@ async def websocket_authenticate(ws: WebSocket, auth=AUTH_COOKIE):
user_uuid=cred.user, user_uuid=cred.user,
credential=cred, credential=cred,
host=normalized_host, host=normalized_host,
ip=metadata.get("ip") or "", ip=metadata["ip"],
user_agent=metadata.get("user_agent") or "", user_agent=metadata["user_agent"],
expiry=expires(), expiry=expires(),
) )