fix(): Ajustado endpoint de visualização de arquivo
This commit is contained in:
parent
4b208ad03e
commit
76bbc71fc6
1 changed files with 32 additions and 13 deletions
|
|
@ -1,7 +1,8 @@
|
||||||
from fastapi import APIRouter, Query, HTTPException
|
from fastapi import APIRouter, Query, HTTPException
|
||||||
from fastapi.responses import FileResponse
|
from fastapi.responses import FileResponse
|
||||||
from jose import jwt, JWTError
|
from jose import jwt, JWTError
|
||||||
from database.mysql import SessionLocal, get_database_settings
|
from datetime import datetime, timedelta
|
||||||
|
from database.mysql import get_database_settings
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
@ -15,31 +16,49 @@ ALGORITHM = "HS256"
|
||||||
STORAGE_DIR = Path("storage")
|
STORAGE_DIR = Path("storage")
|
||||||
|
|
||||||
|
|
||||||
@router.get("/{file_id}/{file_path:path}")
|
@router.get("/{hash}/{file_path:path}")
|
||||||
def visualizar_arquivo(file_id: str, file_path: str, token: str = Query(...)):
|
def visualizar_arquivo(hash: str, file_path: str, token: str = Query(...)):
|
||||||
"""
|
"""
|
||||||
Valida o token e retorna o arquivo do storage, se autorizado.
|
Valida o token JWT e retorna o arquivo PDF, se autorizado.
|
||||||
Exemplo de URL:
|
URL esperada:
|
||||||
/view/d7e8f9g0h1i2/100/57/documento.pdf?token=xxxx
|
/view/<hash>/<caminho_relativo>?token=<jwt>
|
||||||
|
Exemplo real:
|
||||||
|
/view/d7e8f9g0h1i2/100/57/documento.pdf?token=xxxxx
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# --- 1. Valida token JWT ---
|
|
||||||
try:
|
try:
|
||||||
|
# Decodifica o token usando a chave e algoritmo definidos
|
||||||
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
|
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
|
||||||
if payload["sub"] != file_id or payload["filename"] != file_path:
|
|
||||||
raise HTTPException(status_code=403, detail="Token inválido.")
|
# 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:
|
except JWTError:
|
||||||
raise HTTPException(status_code=401, detail="Token expirado ou inválido.")
|
raise HTTPException(status_code=401, detail="Token expirado ou inválido.")
|
||||||
|
|
||||||
# --- 2. Monta caminho real no disco ---
|
# Monta o caminho físico no disco
|
||||||
full_path = STORAGE_DIR / file_path
|
full_path = STORAGE_DIR / file_path
|
||||||
|
|
||||||
# --- 3. Retorna arquivo, se existir ---
|
|
||||||
if not full_path.exists():
|
if not full_path.exists():
|
||||||
raise HTTPException(status_code=404, detail="Arquivo não encontrado.")
|
raise HTTPException(status_code=404, detail="Arquivo não encontrado.")
|
||||||
|
|
||||||
|
# Retorna o arquivo inline (abre no navegador)
|
||||||
return FileResponse(
|
return FileResponse(
|
||||||
full_path,
|
full_path,
|
||||||
media_type="application/pdf",
|
media_type="application/pdf",
|
||||||
headers={"Content-Disposition": "inline"}, # abre no navegador
|
headers={"Content-Disposition": "inline"},
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue