54 lines
1.9 KiB
Python
54 lines
1.9 KiB
Python
"""PostgreSQL persistence for Agent authentication."""
|
|
|
|
from collections.abc import Callable
|
|
|
|
import psycopg
|
|
from psycopg.rows import dict_row
|
|
|
|
from app.config import settings
|
|
|
|
|
|
ConnectionFactory = Callable[[], psycopg.Connection]
|
|
|
|
|
|
def default_connection_factory() -> psycopg.Connection:
|
|
return psycopg.connect(
|
|
host=settings.postgres_host,
|
|
port=settings.postgres_port,
|
|
dbname=settings.postgres_db,
|
|
user=settings.postgres_user,
|
|
password=settings.postgres_password,
|
|
connect_timeout=5,
|
|
)
|
|
|
|
|
|
class AgentAuthRepository:
|
|
def __init__(self, connection_factory: ConnectionFactory | None = None):
|
|
self._connection_factory = connection_factory or default_connection_factory
|
|
|
|
def get_credential(self, agent_id: str) -> dict | None:
|
|
connection = self._connection_factory()
|
|
try:
|
|
with connection.cursor(row_factory=dict_row) as cur:
|
|
cur.execute(
|
|
"""
|
|
SELECT identity.agent_id,
|
|
agent.agent_secret_hash,
|
|
agent.credential_created_at,
|
|
agent.credential_revoked_at,
|
|
retirement.retired_at AS legacy_auth_disabled_at
|
|
FROM (VALUES (%s::text)) AS identity(agent_id)
|
|
LEFT JOIN minerops_site_agents AS agent
|
|
ON agent.agent_id = identity.agent_id
|
|
LEFT JOIN agent_legacy_auth_retirements AS retirement
|
|
ON retirement.agent_id = identity.agent_id
|
|
WHERE agent.agent_id IS NOT NULL
|
|
OR retirement.agent_id IS NOT NULL
|
|
""",
|
|
(agent_id,),
|
|
)
|
|
row = cur.fetchone()
|
|
return dict(row) if row else None
|
|
finally:
|
|
connection.close()
|