|
import os |
|
import logging |
|
import aiohttp |
|
from fastapi import APIRouter, HTTPException, Header |
|
from pydantic import BaseModel |
|
from typing import Optional |
|
|
|
router = APIRouter() |
|
|
|
|
|
SUPABASE_URL = "https://ussxqnifefkgkaumjann.supabase.co" |
|
SUPABASE_KEY = os.getenv("SUPA_KEY") |
|
SUPABASE_ROLE_KEY = os.getenv("SUPA_SERVICE_KEY") |
|
|
|
if not SUPABASE_KEY or not SUPABASE_ROLE_KEY: |
|
raise ValueError("❌ SUPA_KEY or SUPA_SERVICE_KEY not set in environment!") |
|
|
|
SUPABASE_HEADERS = { |
|
"apikey": SUPABASE_KEY, |
|
"Authorization": f"Bearer {SUPABASE_KEY}", |
|
"Content-Type": "application/json" |
|
} |
|
|
|
SUPABASE_ROLE_HEADERS = { |
|
"apikey": SUPABASE_ROLE_KEY, |
|
"Authorization": f"Bearer {SUPABASE_ROLE_KEY}", |
|
"Content-Type": "application/json" |
|
} |
|
|
|
|
|
class RemoveCollaborationRequest(BaseModel): |
|
user_id: str |
|
|
|
|
|
class CreateCollaborationRequest(BaseModel): |
|
email: str |
|
password: str |
|
|
|
|
|
async def verify_admin_token(user_token: str) -> str: |
|
headers = { |
|
"Authorization": f"Bearer {user_token}", |
|
"apikey": SUPABASE_KEY, |
|
"Content-Type": "application/json" |
|
} |
|
|
|
async with aiohttp.ClientSession() as session: |
|
async with session.get(f"{SUPABASE_URL}/auth/v1/user", headers=headers) as response: |
|
if response.status != 200: |
|
raise HTTPException(status_code=401, detail="Invalid or expired token") |
|
|
|
user_data = await response.json() |
|
user_id = user_data.get("id") |
|
if not user_id: |
|
raise HTTPException(status_code=400, detail="User ID not found") |
|
|
|
|
|
async with aiohttp.ClientSession() as session: |
|
async with session.get( |
|
f"{SUPABASE_URL}/rest/v1/User?id=eq.{user_id}", |
|
headers=SUPABASE_HEADERS |
|
) as resp: |
|
if resp.status != 200: |
|
raise HTTPException(status_code=403, detail="Could not verify admin status") |
|
|
|
user_info = await resp.json() |
|
if not user_info or not user_info[0].get("is_admin", False): |
|
raise HTTPException(status_code=403, detail="Admin privileges required") |
|
|
|
return user_id |
|
|
|
@router.post("/admin/remove-collaboration") |
|
async def remove_collaboration( |
|
body: RemoveCollaborationRequest, |
|
user_token: str = Header(None, alias="User-key") |
|
): |
|
try: |
|
await verify_admin_token(user_token) |
|
|
|
update_payload = { |
|
"is_admin": False |
|
} |
|
|
|
async with aiohttp.ClientSession() as session: |
|
async with session.patch( |
|
f"{SUPABASE_URL}/rest/v1/User?id=eq.{body.user_id}", |
|
headers=SUPABASE_ROLE_HEADERS, |
|
json=update_payload |
|
) as response: |
|
|
|
if response.status != 204: |
|
error_detail = await response.text() |
|
raise HTTPException(status_code=500, detail=f"Failed to update user admin status: {error_detail}") |
|
|
|
return {"success": True, "message": "Colaborador removido com sucesso"} |
|
|
|
except HTTPException as http_ex: |
|
return {"success": False, "detail": http_ex.detail} |
|
except Exception as e: |
|
logging.error(f"❌ Unexpected error: {str(e)}") |
|
return {"success": False, "detail": str(e)} |
|
|
|
|
|
@router.post("/admin/create-collaboration") |
|
async def create_collaboration( |
|
body: CreateCollaborationRequest, |
|
user_token: str = Header(None, alias="User-key") |
|
): |
|
try: |
|
await verify_admin_token(user_token) |
|
|
|
|
|
create_user_payload = { |
|
"email": body.email, |
|
"password": body.password, |
|
"email_confirm": True |
|
} |
|
|
|
async with aiohttp.ClientSession() as session: |
|
async with session.post( |
|
f"{SUPABASE_URL}/auth/v1/admin/users", |
|
headers=SUPABASE_ROLE_HEADERS, |
|
json=create_user_payload |
|
) as user_response: |
|
|
|
if user_response.status != 200: |
|
error_detail = await user_response.json() |
|
raise HTTPException(status_code=400, detail=error_detail.get("msg", "Failed to create user")) |
|
|
|
user_data = await user_response.json() |
|
user_id = user_data.get("id") |
|
if not user_id: |
|
raise HTTPException(status_code=500, detail="User ID not returned after creation") |
|
|
|
|
|
user_insert_payload = { |
|
"id": user_id, |
|
"email": body.email, |
|
"is_admin": True |
|
} |
|
|
|
async with aiohttp.ClientSession() as session: |
|
async with session.post( |
|
f"{SUPABASE_URL}/rest/v1/User", |
|
headers=SUPABASE_ROLE_HEADERS, |
|
json=user_insert_payload |
|
) as insert_response: |
|
|
|
if insert_response.status != 201: |
|
error_detail = await insert_response.text() |
|
raise HTTPException(status_code=500, detail="Failed to insert user into User table") |
|
|
|
return {"success": True} |
|
|
|
except HTTPException as http_ex: |
|
return {"success": False, "detail": http_ex.detail} |
|
except Exception as e: |
|
logging.error(f"❌ Unexpected error: {str(e)}") |
|
return {"success": False, "detail": str(e)} |