from fastapi import APIRouter, HTTPException, Depends from pydantic import BaseModel from typing import Optional, List from app.models.user import get_db_connection from app.api.v1.auth import get_current_user from app.core.auth import hash_password router = APIRouter() def require_admin(current_user: dict = Depends(get_current_user)): if current_user.get("role") != "admin": raise HTTPException(status_code=403, detail="Chỉ Admin hệ thống mới có quyền truy cập tính năng này") return current_user class UpdateUserQuotaRequest(BaseModel): storage_limit_mb: int max_tracks: Optional[int] = 16 class UpdateUserRoleRequest(BaseModel): role: str # 'admin', 'standard', 'premium' is_active: Optional[bool] = True @router.get("/users") async def list_users(admin: dict = Depends(require_admin)): conn = get_db_connection() cursor = conn.cursor() cursor.execute(""" SELECT u.id, u.username, u.email, u.role, u.is_active, u.must_change_password, u.created_at, q.storage_limit_mb, q.max_tracks, (SELECT COALESCE(SUM(p.size_bytes), 0) FROM projects p WHERE p.user_id = u.id) as used_bytes FROM users u LEFT JOIN user_quotas q ON u.id = q.user_id ORDER BY u.created_at DESC """) rows = cursor.fetchall() conn.close() users = [] for r in rows: used_mb = round((r["used_bytes"] or 0) / (1024 * 1024), 2) users.append({ "id": r["id"], "username": r["username"], "email": r["email"], "role": r["role"], "is_active": bool(r["is_active"]), "must_change_password": bool(r["must_change_password"]), "created_at": r["created_at"], "quota_mb": r["storage_limit_mb"] or 500, "used_mb": used_mb, "max_tracks": r["max_tracks"] or 16 }) return users @router.put("/users/{user_id}/role") async def update_user_role(user_id: str, req: UpdateUserRoleRequest, admin: dict = Depends(require_admin)): conn = get_db_connection() cursor = conn.cursor() cursor.execute("UPDATE users SET role = ?, is_active = ? WHERE id = ?", (req.role, int(req.is_active), user_id)) conn.commit() conn.close() return {"message": "Cập nhật vai trò người dùng thành công"} @router.put("/quotas/{user_id}") async def update_user_quota(user_id: str, req: UpdateUserQuotaRequest, admin: dict = Depends(require_admin)): conn = get_db_connection() cursor = conn.cursor() cursor.execute(""" INSERT INTO user_quotas (user_id, storage_limit_mb, max_tracks) VALUES (?, ?, ?) ON CONFLICT(user_id) DO UPDATE SET storage_limit_mb = excluded.storage_limit_mb, max_tracks = excluded.max_tracks """, (user_id, req.storage_limit_mb, req.max_tracks)) conn.commit() conn.close() return {"message": "Cập nhật hạn mức Quota thành công"} @router.delete("/users/{user_id}") async def delete_user(user_id: str, admin: dict = Depends(require_admin)): if user_id == admin["user_id"]: raise HTTPException(status_code=400, detail="Không thể xóa chính tài khoản Admin đang đăng nhập") conn = get_db_connection() cursor = conn.cursor() cursor.execute("DELETE FROM users WHERE id = ?", (user_id,)) cursor.execute("DELETE FROM user_quotas WHERE id = ?", (user_id,)) cursor.execute("DELETE FROM projects WHERE user_id = ?", (user_id,)) conn.commit() conn.close() return {"message": "Đã xóa người dùng thành công"}