82 lines
3.3 KiB
Python
82 lines
3.3 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from sqlalchemy.orm import Session
|
|
from typing import List, Optional
|
|
from backend.database import get_db
|
|
from backend.models import User, UserRole
|
|
from backend.schemas import UserOut, UserCreate, UserUpdate
|
|
from backend.routers.auth import get_current_user, get_admin_user
|
|
|
|
router = APIRouter(prefix="/api/users", tags=["users"])
|
|
|
|
@router.get("", response_model=List[UserOut])
|
|
def get_all_users(db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
|
|
return db.query(User).order_by(User.id.asc()).all()
|
|
|
|
@router.post("", response_model=UserOut)
|
|
def create_user(user_in: UserCreate, db: Session = Depends(get_db), admin: User = Depends(get_admin_user)):
|
|
existing = db.query(User).filter(User.email == user_in.email).first()
|
|
if existing:
|
|
raise HTTPException(status_code=400, detail="User with this email already exists")
|
|
|
|
avatar = user_in.avatar_url or f"https://api.dicebear.com/7.x/bottts/svg?seed={user_in.email}"
|
|
new_user = User(
|
|
email=user_in.email,
|
|
name=user_in.name,
|
|
google_id=user_in.google_id,
|
|
avatar_url=avatar,
|
|
role=user_in.role,
|
|
weekly_star_quota=user_in.weekly_star_quota
|
|
)
|
|
db.add(new_user)
|
|
db.commit()
|
|
db.refresh(new_user)
|
|
return new_user
|
|
|
|
@router.get("/{user_id}", response_model=UserOut)
|
|
def get_user_by_id(user_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
|
|
user = db.query(User).filter(User.id == user_id).first()
|
|
if not user:
|
|
raise HTTPException(status_code=404, detail="User not found")
|
|
return user
|
|
|
|
@router.patch("/{user_id}", response_model=UserOut)
|
|
def update_user(user_id: int, user_in: UserUpdate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)):
|
|
# Regular users can only update their own avatar and name. Admins can update role, quota, active status.
|
|
if current_user.role != UserRole.ADMIN.value and current_user.id != user_id:
|
|
raise HTTPException(status_code=403, detail="Cannot edit another user's account")
|
|
|
|
user = db.query(User).filter(User.id == user_id).first()
|
|
if not user:
|
|
raise HTTPException(status_code=404, detail="User not found")
|
|
|
|
if user_in.name is not None:
|
|
user.name = user_in.name
|
|
if user_in.avatar_url is not None:
|
|
user.avatar_url = user_in.avatar_url
|
|
|
|
# Admin-only fields
|
|
if current_user.role == UserRole.ADMIN.value:
|
|
if user_in.role is not None:
|
|
user.role = user_in.role
|
|
if user_in.weekly_star_quota is not None:
|
|
user.weekly_star_quota = user_in.weekly_star_quota
|
|
if user_in.is_active is not None:
|
|
user.is_active = user_in.is_active
|
|
|
|
db.commit()
|
|
db.refresh(user)
|
|
return user
|
|
|
|
@router.delete("/{user_id}")
|
|
def delete_user(user_id: int, db: Session = Depends(get_db), admin: User = Depends(get_admin_user)):
|
|
if admin.id == user_id:
|
|
raise HTTPException(status_code=400, detail="Cannot delete your own admin account")
|
|
|
|
user = db.query(User).filter(User.id == user_id).first()
|
|
if not user:
|
|
raise HTTPException(status_code=404, detail="User not found")
|
|
|
|
db.delete(user)
|
|
db.commit()
|
|
return {"message": "User deleted successfully", "id": user_id}
|