MirrorAPI/packages/v1/administrativo/endpoints/atos_view_document_endpoint.py

64 lines
2.2 KiB
Python

from fastapi import APIRouter, Query, HTTPException
from fastapi.responses import FileResponse
from jose import jwt, JWTError
from datetime import datetime, timedelta
from database.mysql import get_database_settings
from pathlib import Path
router = APIRouter()
# === Configuração do token temporário ===
DB_SETTINGS = get_database_settings()
SECRET_KEY = getattr(DB_SETTINGS, "aeskey", None)
ALGORITHM = "HS256"
# Pasta base onde os arquivos são armazenados
STORAGE_DIR = Path("storage")
@router.get("/{hash}/{file_path:path}")
def visualizar_arquivo(hash: str, file_path: str, token: str = Query(...)):
"""
Valida o token JWT e retorna o arquivo PDF, se autorizado.
URL esperada:
/view/<hash>/<caminho_relativo>?token=<jwt>
Exemplo real:
/view/d7e8f9g0h1i2/100/57/documento.pdf?token=xxxxx
"""
try:
# Decodifica o token usando a chave e algoritmo definidos
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
# Extrai os campos esperados do token
faixa_superior = payload.get("faixa_superior")
ato_id = payload.get("ato_id")
file_name = payload.get("file_name")
# Se algum campo essencial estiver faltando → token inválido
if not all([faixa_superior, ato_id, file_name]):
raise HTTPException(status_code=400, detail="Token malformado.")
# Reconstrói o caminho esperado a partir do token
expected_path = f"{faixa_superior}/{ato_id}/{file_name}"
# Se o caminho do arquivo solicitado não bate com o token → bloqueia
if expected_path != file_path:
raise HTTPException(
status_code=403, detail="Token não corresponde ao arquivo."
)
except JWTError:
raise HTTPException(status_code=401, detail="Token expirado ou inválido.")
# Monta o caminho físico no disco
full_path = STORAGE_DIR / file_path
if not full_path.exists():
raise HTTPException(status_code=404, detail="Arquivo não encontrado.")
# Retorna o arquivo inline (abre no navegador)
return FileResponse(
full_path,
media_type="application/pdf",
headers={"Content-Disposition": "inline"},
)