import hashlib import secrets from psycopg import AsyncConnection def _hash_secret(secret: str) -> str: return hashlib.sha256(secret.encode()).hexdigest() def generate_secret() -> str: return secrets.token_urlsafe(32) async def verify_client(conn: AsyncConnection, secret: str) -> bool: h = _hash_secret(secret) row = await (await conn.execute( "SELECT id FROM api_clients WHERE secret_hash = %s AND is_active = TRUE", (h,) )).fetchone() return row is not None async def create_client(conn: AsyncConnection, name: str) -> dict: secret = generate_secret() h = _hash_secret(secret) row = await (await conn.execute( "INSERT INTO api_clients (name, secret_hash) VALUES (%s, %s) RETURNING id, name, created_at", (name, h) )).fetchone() await conn.commit() # secret yalnızca bir kez döner, sonra erişilemez return {"id": row[0], "name": row[1], "secret": secret, "created_at": row[2]} async def list_clients(conn: AsyncConnection) -> list[dict]: rows = await (await conn.execute( "SELECT id, name, is_active, created_at FROM api_clients ORDER BY created_at DESC" )).fetchall() return [{"id": r[0], "name": r[1], "is_active": r[2], "created_at": r[3]} for r in rows] async def set_active(conn: AsyncConnection, client_id: int, is_active: bool) -> dict: row = await (await conn.execute( "UPDATE api_clients SET is_active = %s WHERE id = %s RETURNING id, name, is_active, created_at", (is_active, client_id) )).fetchone() if not row: raise ValueError("Client bulunamadı") await conn.commit() return {"id": row[0], "name": row[1], "is_active": row[2], "created_at": row[3]}