Spaces:
Running on Zero
Running on Zero
File size: 5,149 Bytes
34a66f3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | from typing import Any, Dict, List, Optional
from fastapi import APIRouter, Header, HTTPException
import requests
from app.core.config import (
SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, SUPABASE_TIMEOUT_SECONDS,
PROFILE_SELECT_FIELDS, CORE_TABLES, supabase_configured, is_staff_role, LOGGER,
)
from app.security.auth import require_authenticated_user, require_developer_user, _supabase_headers, _normalize_spaces
router = APIRouter(tags=["admin"])
def _run_weekly_refresh_non_core() -> Dict[str, Any]:
core_set = {t.lower() for t in CORE_TABLES}
try:
table_response = requests.get(
f"{SUPABASE_URL}/rest/v1/rpc/",
timeout=SUPABASE_TIMEOUT_SECONDS,
)
except requests.RequestException:
table_response = requests.get(
f"{SUPABASE_URL}/rest/v1/",
headers=_supabase_headers(api_key=SUPABASE_SERVICE_ROLE_KEY, bearer=SUPABASE_SERVICE_ROLE_KEY),
timeout=SUPABASE_TIMEOUT_SECONDS,
)
deleted: List[str] = []
skipped: List[str] = []
try:
response = requests.get(
f"{SUPABASE_URL}/rest/v1/",
headers=_supabase_headers(api_key=SUPABASE_SERVICE_ROLE_KEY, bearer=SUPABASE_SERVICE_ROLE_KEY),
timeout=SUPABASE_TIMEOUT_SECONDS,
)
if response.status_code == 200:
tables_data = response.json()
if isinstance(tables_data, dict):
all_tables = [k for k in tables_data.keys() if not k.startswith("_")]
elif isinstance(tables_data, list):
all_tables = [t for t in tables_data if isinstance(t, str) and not t.startswith("_")]
else:
all_tables = []
for table_name in all_tables:
table_lower = table_name.lower()
if table_lower in core_set:
skipped.append(table_name)
continue
try:
del_response = requests.delete(
f"{SUPABASE_URL}/rest/v1/{table_name}",
params={"select": "id"},
headers=_supabase_headers(api_key=SUPABASE_SERVICE_ROLE_KEY, bearer=SUPABASE_SERVICE_ROLE_KEY),
timeout=SUPABASE_TIMEOUT_SECONDS,
)
if del_response.status_code in {200, 204}:
deleted.append(table_name)
else:
skipped.append(table_name)
except requests.RequestException:
skipped.append(table_name)
except Exception as exc:
LOGGER.warning("Weekly refresh encountered an error: %s", exc)
return {"deleted_tables": deleted, "skipped_tables": skipped, "core_tables_protected": sorted(CORE_TABLES)}
@router.get("/users")
def get_all_users(
authorization: Optional[str] = Header(default=None),
) -> Dict[str, Any]:
if not supabase_configured():
raise HTTPException(status_code=503, detail="Supabase is not configured.")
request_user = require_authenticated_user(authorization)
if request_user is None:
raise HTTPException(status_code=401, detail="Authentication is required.")
requester_role = (request_user.get("role") or "").strip().lower()
if not is_staff_role(requester_role):
raise HTTPException(status_code=403, detail="Admin/Security role required to view users.")
try:
response = requests.get(
f"{SUPABASE_URL}/rest/v1/profiles",
params={"select": PROFILE_SELECT_FIELDS},
headers=_supabase_headers(api_key=SUPABASE_SERVICE_ROLE_KEY, bearer=SUPABASE_SERVICE_ROLE_KEY),
timeout=SUPABASE_TIMEOUT_SECONDS,
)
if response.status_code != 200:
raise HTTPException(status_code=502, detail="Failed to fetch users from database.")
users = response.json()
if isinstance(users, dict) and "error" in users:
users = []
return {"status": "ok", "users": users}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@router.post("/admin/maintenance/weekly-refresh")
def admin_weekly_refresh(
authorization: Optional[str] = Header(default=None),
) -> Dict[str, Any]:
request_user = require_authenticated_user(authorization)
if request_user is None:
raise HTTPException(status_code=401, detail="Authentication is required.")
requester_id = str(request_user.get("id") or "").strip()
requester_role = (request_user.get("role") or "").strip().lower()
if not is_staff_role(requester_role):
raise HTTPException(status_code=403, detail="Only admin/security can run weekly refresh.")
try:
refresh_result = _run_weekly_refresh_non_core()
return {
"status": "ok",
"requested_by": requester_id,
"requested_by_role": requester_role,
"core_tables_protected": sorted(CORE_TABLES),
"refresh": refresh_result,
}
except Exception as exc:
raise HTTPException(status_code=502, detail=f"Weekly refresh failed: {exc}") from exc
|