from __future__ import annotations from quart import session as qsession, g from sqlalchemy import select from sqlalchemy.orm import selectinload from shared.models.user import User from shared.models.ghost_membership_entities import UserNewsletter async def load_user_by_id(session, user_id: int): """Load a user by ID with labels and newsletters eagerly loaded.""" stmt = ( select(User) .options( selectinload(User.labels), selectinload(User.user_newsletters).selectinload( UserNewsletter.newsletter ), ) .where(User.id == user_id) ) result = await session.execute(stmt) return result.scalar_one_or_none() async def load_current_user(): uid = qsession.get("uid") if not uid: g.user = None g.rights = {"admin": False} return # User table lives in the account DB — use account session when # the per-request session (g.s) targets a different database. from shared.db.session import DATABASE_URL, DATABASE_URL_ACCOUNT if DATABASE_URL_ACCOUNT != DATABASE_URL: from shared.db.session import get_account_session async with get_account_session() as s: g.user = await load_user_by_id(s, uid) # Expunge so the object is usable outside this session if g.user: s.expunge(g.user) else: g.user = await load_user_by_id(g.s, uid) g.rights = {l.name: True for l in g.user.labels} if g.user else {}