Files
SkinsPins/app/dependencies.py
Rolf 3a1da1482c Add full SkinsPins application
- 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>
2026-03-20 10:16:46 +01:00

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