3a1da1482c
- FastAPI + SQLite + Alpine.js + HTMX PWA for Bingo Bango Bongo golf scoring - Passwordless magic link auth with email (aiosmtplib) and admin invite system - Real-time score entry via WebSocket with drag-and-drop player ordering - Course management with per-hole par and stroke index - Scorecard with golf score markers (birdie, eagle, bogey, etc.) - Two-step new game form with tee selection per player - Dashboard with stats, live games social stream, and recent game history - Game summary view (read-only scorecard with leaderboard) - User profile pages with win stats - PWA install support with generated PNG icons - Admin panel for users, courses, games, and invitations Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
56 lines
1.2 KiB
Python
56 lines
1.2 KiB
Python
import os
|
|
from datetime import datetime, timezone
|
|
|
|
from fastapi import Request, Depends
|
|
import aiosqlite
|
|
|
|
from app.database import get_db
|
|
|
|
ADMIN_EMAIL = os.getenv("ADMIN_EMAIL", "")
|
|
SESSION_COOKIE = "session"
|
|
|
|
|
|
class NeedsLogin(Exception):
|
|
pass
|
|
|
|
|
|
class NeedsOnboarding(Exception):
|
|
pass
|
|
|
|
|
|
class NeedsAdmin(Exception):
|
|
pass
|
|
|
|
|
|
async def get_current_user(request: Request, db: aiosqlite.Connection = Depends(get_db)):
|
|
token = request.cookies.get(SESSION_COOKIE)
|
|
if not token:
|
|
raise NeedsLogin()
|
|
|
|
async with db.execute(
|
|
"""
|
|
SELECT u.id, u.email, u.name, u.handicap, u.avatar, u.is_onboarded
|
|
FROM sessions s
|
|
JOIN users u ON s.user_id = u.id
|
|
WHERE s.token = ? AND s.expires_at > ?
|
|
""",
|
|
(token, datetime.now(timezone.utc).isoformat()),
|
|
) as cursor:
|
|
row = await cursor.fetchone()
|
|
|
|
if row is None:
|
|
raise NeedsLogin()
|
|
|
|
user = dict(row)
|
|
|
|
if not user["is_onboarded"] and request.url.path not in ("/onboarding", "/logout"):
|
|
raise NeedsOnboarding()
|
|
|
|
return user
|
|
|
|
|
|
async def require_admin(user: dict = Depends(get_current_user)):
|
|
if user["email"] != ADMIN_EMAIL:
|
|
raise NeedsAdmin()
|
|
return user
|