Initial: Pokedexter TCG-Collector webapp
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
import os
|
||||
from fastapi import FastAPI, Depends, Request
|
||||
from fastapi.responses import RedirectResponse, HTMLResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from fastapi.templating import Jinja2Templates
|
||||
from contextlib import asynccontextmanager
|
||||
from sqlalchemy import select
|
||||
|
||||
from .database import engine, async_session, Base
|
||||
from .routers import auth, admin, cards
|
||||
from .auth import get_current_user, hash_password
|
||||
from .models import User
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(_app: FastAPI):
|
||||
async with engine.begin() as conn:
|
||||
await conn.run_sync(Base.metadata.create_all)
|
||||
|
||||
# Create default admin user if not exists
|
||||
async with async_session() as session:
|
||||
result = await session.execute(select(User).where(User.username == "admin"))
|
||||
if not result.scalar_one_or_none():
|
||||
session.add(User(
|
||||
username="admin",
|
||||
password_hash=hash_password("admin123"),
|
||||
role="admin",
|
||||
))
|
||||
await session.commit()
|
||||
yield
|
||||
|
||||
|
||||
app = FastAPI(lifespan=lifespan)
|
||||
|
||||
app.mount("/static", StaticFiles(directory="app/static"), name="static")
|
||||
app.include_router(cards.router)
|
||||
app.include_router(auth.router)
|
||||
app.include_router(admin.router)
|
||||
|
||||
templates = Jinja2Templates(directory="app/templates")
|
||||
|
||||
|
||||
@app.middleware("http")
|
||||
async def auth_middleware(request: Request, call_next):
|
||||
"""Attach user to request for templates."""
|
||||
token = request.cookies.get("token")
|
||||
request.state.user = None
|
||||
if token:
|
||||
from .auth import decode_token
|
||||
from sqlalchemy import select
|
||||
from .database import async_session
|
||||
payload = decode_token(token)
|
||||
if payload:
|
||||
async with async_session() as db:
|
||||
result = await db.execute(
|
||||
select(User).where(User.username == payload["sub"])
|
||||
)
|
||||
request.state.user = result.scalar_one_or_none()
|
||||
response = await call_next(request)
|
||||
return response
|
||||
|
||||
|
||||
@app.get("/", response_class=HTMLResponse)
|
||||
async def root(request: Request):
|
||||
if not request.state.user:
|
||||
return RedirectResponse(url="/login")
|
||||
return await cards.index(request)
|
||||
|
||||
|
||||
@app.get("/logout")
|
||||
async def logout_redirect():
|
||||
resp = RedirectResponse(url="/login", status_code=302)
|
||||
resp.delete_cookie("token")
|
||||
return resp
|
||||
Reference in New Issue
Block a user