""" Autenticação simples do painel administrativo. Não é um sistema de usuários completo (não há cadastro, nem papéis) — é uma única senha de acesso, guardada em variável de ambiente, validada contra uma sessão assinada em cookie (via SessionMiddleware do Starlette). O objetivo é apenas fechar a porta que antes estava totalmente aberta em /admin.html e nas rotas de escrita da API de anúncios. Definir em produção: ADMIN_PASSWORD -> senha de acesso ao painel SECRET_KEY -> chave usada para assinar o cookie de sessão Se não forem definidas, caem em valores padrão de demonstração (a senha é avisada no log de startup) — não use os padrões em produção. """ import hmac import os from fastapi import HTTPException, Request SESSION_KEY = "admin_autenticado" SESSION_COOKIE = "sk_admin_sessao" ADMIN_PASSWORD = os.environ.get("ADMIN_PASSWORD", "sk-imobiliaria-2026") SECRET_KEY = os.environ.get("SECRET_KEY") or os.environ.get("SESSION_SECRET_KEY") or os.urandom(32).hex() USANDO_SENHA_PADRAO = "ADMIN_PASSWORD" not in os.environ def senha_correta(senha: str) -> bool: """Compara em tempo constante para não vazar a senha por timing.""" return hmac.compare_digest((senha or "").strip(), ADMIN_PASSWORD) def esta_autenticado(request: Request) -> bool: return bool(request.session.get(SESSION_KEY)) def autenticar(request: Request) -> None: request.session[SESSION_KEY] = True def deslogar(request: Request) -> None: request.session.clear() def exigir_admin_api(request: Request) -> None: """Dependência para proteger rotas de escrita da API usadas pelo painel admin.""" if not esta_autenticado(request): raise HTTPException( status_code=401, detail="Não autenticado. Faça login em /admin/login para gerenciar anúncios.", )