|
| 1 | +from fastapi import APIRouter, Depends, HTTPException |
| 2 | +from bson import ObjectId |
| 3 | +from app.auth import get_current_user, get_current_user_with_role |
| 4 | +from app.database.config import get_db |
| 5 | +import os |
| 6 | + |
| 7 | +router = APIRouter(prefix="/api/v1/admin", tags=["Admin"]) |
| 8 | + |
| 9 | +VALID_ROLES = ("hr", "applicant", "admin") |
| 10 | +BOOTSTRAP_SECRET = os.getenv("ADMIN_BOOTSTRAP_SECRET", "") |
| 11 | + |
| 12 | +async def require_admin(user_info: dict = Depends(get_current_user_with_role)): |
| 13 | + if user_info["role"] != "admin": |
| 14 | + raise HTTPException(status_code=403, detail="Chỉ Admin mới có quyền thực hiện thao tác này") |
| 15 | + return user_info["email"] |
| 16 | + |
| 17 | +@router.post("/bootstrap") |
| 18 | +async def bootstrap_admin(body: dict): |
| 19 | + """Dùng 1 lần để tạo admin đầu tiên. Cần ADMIN_BOOTSTRAP_SECRET trong .env""" |
| 20 | + if not BOOTSTRAP_SECRET: |
| 21 | + raise HTTPException(status_code=403, detail="Bootstrap đã bị tắt") |
| 22 | + if body.get("secret") != BOOTSTRAP_SECRET: |
| 23 | + raise HTTPException(status_code=403, detail="Secret không đúng") |
| 24 | + email = body.get("email") |
| 25 | + if not email: |
| 26 | + raise HTTPException(status_code=400, detail="Thiếu email") |
| 27 | + db = get_db() |
| 28 | + result = await db["hr_users"].update_one({"email": email}, {"$set": {"role": "admin"}}) |
| 29 | + if result.matched_count == 0: |
| 30 | + raise HTTPException(status_code=404, detail="Không tìm thấy tài khoản") |
| 31 | + return {"status": "success", "message": f"{email} đã được set làm Admin"} |
| 32 | + |
| 33 | +@router.get("/users") |
| 34 | +async def list_users(_: str = Depends(require_admin)): |
| 35 | + db = get_db() |
| 36 | + cursor = db["hr_users"].find({}, {"hashed_password": 0, "raw_text": 0}) |
| 37 | + users = await cursor.to_list(length=500) |
| 38 | + for u in users: |
| 39 | + u["id"] = str(u["_id"]) |
| 40 | + del u["_id"] |
| 41 | + return users |
| 42 | + |
| 43 | +@router.patch("/users/{user_id}/role") |
| 44 | +async def update_user_role(user_id: str, body: dict, _: str = Depends(require_admin)): |
| 45 | + new_role = body.get("role") |
| 46 | + if new_role not in VALID_ROLES: |
| 47 | + raise HTTPException(status_code=400, detail=f"Role không hợp lệ. Chọn: {VALID_ROLES}") |
| 48 | + db = get_db() |
| 49 | + result = await db["hr_users"].update_one( |
| 50 | + {"_id": ObjectId(user_id)}, |
| 51 | + {"$set": {"role": new_role}} |
| 52 | + ) |
| 53 | + if result.matched_count == 0: |
| 54 | + raise HTTPException(status_code=404, detail="Không tìm thấy người dùng") |
| 55 | + return {"status": "success", "message": f"Đã cập nhật role thành '{new_role}'"} |
0 commit comments