Self-hosted personal YouTube management app. FastAPI + SQLite backend, React + Vite + Tailwind frontend. Dockerfiles and compose included for Portainer deployment. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
87 lines
2.5 KiB
Python
87 lines
2.5 KiB
Python
from datetime import datetime
|
|
from typing import Optional
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException
|
|
from pydantic import BaseModel
|
|
from sqlalchemy.orm import Session
|
|
|
|
from ..auth_utils import get_current_user
|
|
from ..database import get_db
|
|
from ..models import SystemConfig, User
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
def _require_admin(current_user: User = Depends(get_current_user)) -> User:
|
|
if not current_user.is_admin:
|
|
raise HTTPException(status_code=403, detail="Admin only")
|
|
return current_user
|
|
|
|
|
|
class UserOut(BaseModel):
|
|
id: int
|
|
username: str
|
|
email: str
|
|
is_admin: bool
|
|
created_at: Optional[datetime]
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
class ConfigOut(BaseModel):
|
|
allow_registration: bool
|
|
|
|
|
|
class ConfigPatch(BaseModel):
|
|
allow_registration: Optional[bool] = None
|
|
|
|
|
|
@router.get("/users", response_model=list[UserOut])
|
|
def list_users(
|
|
db: Session = Depends(get_db),
|
|
_: User = Depends(_require_admin),
|
|
):
|
|
return db.query(User).order_by(User.id).all()
|
|
|
|
|
|
@router.delete("/users/{user_id}", status_code=204)
|
|
def delete_user(
|
|
user_id: int,
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(_require_admin),
|
|
):
|
|
if user_id == current_user.id:
|
|
raise HTTPException(status_code=400, detail="Cannot delete your own account")
|
|
user = db.query(User).filter_by(id=user_id).first()
|
|
if not user:
|
|
raise HTTPException(status_code=404, detail="User not found")
|
|
db.delete(user)
|
|
db.commit()
|
|
|
|
|
|
@router.get("/config", response_model=ConfigOut)
|
|
def get_config(
|
|
db: Session = Depends(get_db),
|
|
_: User = Depends(_require_admin),
|
|
):
|
|
row = db.query(SystemConfig).filter_by(key="allow_registration").first()
|
|
return ConfigOut(allow_registration=row.value == "true" if row else True)
|
|
|
|
|
|
@router.patch("/config", response_model=ConfigOut)
|
|
def update_config(
|
|
body: ConfigPatch,
|
|
db: Session = Depends(get_db),
|
|
_: User = Depends(_require_admin),
|
|
):
|
|
if body.allow_registration is not None:
|
|
row = db.query(SystemConfig).filter_by(key="allow_registration").first()
|
|
if row:
|
|
row.value = "true" if body.allow_registration else "false"
|
|
else:
|
|
db.add(SystemConfig(key="allow_registration",
|
|
value="true" if body.allow_registration else "false"))
|
|
db.commit()
|
|
row = db.query(SystemConfig).filter_by(key="allow_registration").first()
|
|
return ConfigOut(allow_registration=row.value == "true" if row else True)
|