habulaj commited on
Commit
5844082
·
verified ·
1 Parent(s): 816121e

Create users.py

Browse files
Files changed (1) hide show
  1. routes/users.py +120 -0
routes/users.py ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import logging
3
+ import asyncio
4
+ import aiohttp
5
+ from fastapi import APIRouter, HTTPException, Header, Depends
6
+ from functools import lru_cache
7
+ from typing import List, Dict, Any
8
+
9
+ router = APIRouter()
10
+
11
+ # Configuração do Supabase
12
+ SUPABASE_URL = "https://ussxqnifefkgkaumjann.supabase.co"
13
+ SUPABASE_KEY = os.getenv("SUPA_KEY")
14
+
15
+ if not SUPABASE_KEY:
16
+ raise ValueError("❌ SUPA_KEY não foi definido no ambiente!")
17
+
18
+ SUPABASE_HEADERS = {
19
+ "apikey": SUPABASE_KEY,
20
+ "Authorization": f"Bearer {SUPABASE_KEY}",
21
+ "Content-Type": "application/json"
22
+ }
23
+
24
+ # Configuração do logging
25
+ logging.basicConfig(level=logging.INFO)
26
+ logger = logging.getLogger(__name__)
27
+
28
+ # Cache para reduzir chamadas repetidas
29
+ @lru_cache(maxsize=128)
30
+ def get_cached_admin_status(user_id: str) -> bool:
31
+ """Obtém e armazena em cache se um usuário é admin"""
32
+ import requests
33
+ user_data_url = f"{SUPABASE_URL}/rest/v1/User?id=eq.{user_id}"
34
+ response = requests.get(user_data_url, headers=SUPABASE_HEADERS)
35
+
36
+ if response.status_code != 200 or not response.json():
37
+ return False
38
+
39
+ user_info = response.json()[0]
40
+ return user_info.get("is_admin", False)
41
+
42
+ async def verify_admin_token(user_token: str) -> str:
43
+ """Verifica se o token pertence a um administrador de forma assíncrona"""
44
+ headers = {
45
+ "Authorization": f"Bearer {user_token}",
46
+ "apikey": SUPABASE_KEY,
47
+ "Content-Type": "application/json"
48
+ }
49
+
50
+ async with aiohttp.ClientSession() as session:
51
+ # Verificar se o token é válido
52
+ async with session.get(f"{SUPABASE_URL}/auth/v1/user", headers=headers) as response:
53
+ if response.status != 200:
54
+ raise HTTPException(status_code=401, detail="Token inválido ou expirado")
55
+
56
+ user_data = await response.json()
57
+ user_id = user_data.get("id")
58
+ if not user_id:
59
+ raise HTTPException(status_code=400, detail="ID do usuário não encontrado")
60
+
61
+ # Usar cache para verificar se é admin
62
+ is_admin = await asyncio.to_thread(get_cached_admin_status, user_id)
63
+
64
+ if not is_admin:
65
+ raise HTTPException(status_code=403, detail="Acesso negado: privilégios de administrador necessários")
66
+
67
+ return user_id
68
+
69
+ async def get_recent_users(limit: int = 10) -> List[Dict[str, Any]]:
70
+ """Obtém os usuários mais recentes da plataforma"""
71
+ try:
72
+ # URL para obter os usuários mais recentes, ordenados por data de criação (decrescente)
73
+ users_url = f"{SUPABASE_URL}/rest/v1/User?select=name&order=created_at.desc&limit={limit}"
74
+
75
+ # Modificar os headers para garantir que a resposta seja tratada como UTF-8
76
+ headers = SUPABASE_HEADERS.copy()
77
+ headers["Accept"] = "application/json; charset=utf-8"
78
+
79
+ async with aiohttp.ClientSession() as session:
80
+ async with session.get(users_url, headers=headers) as response:
81
+ if response.status != 200:
82
+ logger.error(f"❌ Erro ao obter usuários recentes: {response.status}")
83
+ return []
84
+
85
+ # Forçar a decodificação como UTF-8
86
+ text = await response.text(encoding='utf-8')
87
+ import json
88
+ users_data = json.loads(text)
89
+
90
+ return users_data
91
+
92
+ except Exception as e:
93
+ logger.error(f"❌ Erro ao obter usuários recentes: {str(e)}")
94
+ return []
95
+
96
+ @router.get("/admin/users/recent")
97
+ async def get_recent_users_endpoint(
98
+ user_token: str = Header(None, alias="User-key")
99
+ ):
100
+ """
101
+ Endpoint para obter os 10 usuários mais recentes da plataforma
102
+ """
103
+ try:
104
+ # Verificar se é um administrador
105
+ user_id = await verify_admin_token(user_token)
106
+
107
+ # Obter os 10 usuários mais recentes
108
+ recent_users = await get_recent_users(10)
109
+
110
+ return {
111
+ "recent_users": recent_users,
112
+ "count": len(recent_users)
113
+ }
114
+
115
+ except HTTPException as he:
116
+ raise he
117
+
118
+ except Exception as e:
119
+ logger.error(f"❌ Erro ao obter usuários recentes: {str(e)}")
120
+ raise HTTPException(status_code=500, detail=str(e))