feat(): Refeito logica de entrega de url protegidas por token
This commit is contained in:
parent
faa079fc53
commit
5ce1909eee
3 changed files with 46 additions and 29 deletions
|
|
@ -1,9 +1,11 @@
|
||||||
# utils/hash_generator.py
|
# utils/hash_generator.py
|
||||||
|
from jose import jwt
|
||||||
|
from datetime import datetime, timedelta
|
||||||
from datetime import date
|
from datetime import date
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
|
|
||||||
|
# Função que gera o hash baseado na data atual
|
||||||
def generate_storage_hash() -> str:
|
def generate_storage_hash() -> str:
|
||||||
"""
|
"""
|
||||||
Gera um hash SHA-256 baseado na data atual no formato YYYYMMDD.
|
Gera um hash SHA-256 baseado na data atual no formato YYYYMMDD.
|
||||||
|
|
@ -26,3 +28,21 @@ def generate_storage_hash() -> str:
|
||||||
|
|
||||||
# Retorna o hash em formato hexadecimal
|
# Retorna o hash em formato hexadecimal
|
||||||
return h.hexdigest()
|
return h.hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
# Função que gera o token temporário para acesso ao documento
|
||||||
|
def generate_temporary_token(
|
||||||
|
file_id: str,
|
||||||
|
filename: str,
|
||||||
|
expires_minutes: int,
|
||||||
|
secret_key: str,
|
||||||
|
algorithm: str,
|
||||||
|
) -> str:
|
||||||
|
"""Gera um token JWT válido por poucos minutos."""
|
||||||
|
expire = datetime.utcnow() + timedelta(minutes=expires_minutes)
|
||||||
|
payload = {
|
||||||
|
"sub": file_id,
|
||||||
|
"filename": filename,
|
||||||
|
"exp": expire,
|
||||||
|
}
|
||||||
|
return jwt.encode(payload, secret_key, algorithm=algorithm)
|
||||||
|
|
|
||||||
17
main.py
17
main.py
|
|
@ -15,8 +15,6 @@ from pathlib import Path
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
from fastapi.responses import Response
|
from fastapi.responses import Response
|
||||||
from starlette.middleware.base import BaseHTTPMiddleware
|
from starlette.middleware.base import BaseHTTPMiddleware
|
||||||
from actions.validations.hash import generate_storage_hash
|
|
||||||
from actions.validations.staticFiles import ProtectedStaticFiles
|
|
||||||
|
|
||||||
# Importa middleware de captura de erros junto ao banco de dados
|
# Importa middleware de captura de erros junto ao banco de dados
|
||||||
from middlewares.error_handler import database_error_handler
|
from middlewares.error_handler import database_error_handler
|
||||||
|
|
@ -35,21 +33,6 @@ config = Config.get("app.json")
|
||||||
# Instancia o app FastAPI com um título personalizado
|
# Instancia o app FastAPI com um título personalizado
|
||||||
app = FastAPI(title="Mirror | Orius")
|
app = FastAPI(title="Mirror | Orius")
|
||||||
|
|
||||||
# 1. Defina o caminho local absoluto da sua pasta de arquivos
|
|
||||||
STORAGE_DIR = "/app/storage"
|
|
||||||
|
|
||||||
# 2. Opcional: Crie o diretório se ele não existir
|
|
||||||
if not os.path.isdir(STORAGE_DIR):
|
|
||||||
os.makedirs(STORAGE_DIR)
|
|
||||||
|
|
||||||
# 3. Monte o diretório estático
|
|
||||||
# Isso mapeia o caminho local STORAGE_DIR para o prefixo de URL '/storage-files'
|
|
||||||
app.mount(
|
|
||||||
"/" + generate_storage_hash(), # <- ESTE É O PREFIXO DA URL PÚBLICA
|
|
||||||
ProtectedStaticFiles(directory=STORAGE_DIR),
|
|
||||||
name="storage_access",
|
|
||||||
)
|
|
||||||
|
|
||||||
# Adiciona o middleware global de erro
|
# Adiciona o middleware global de erro
|
||||||
# app.middleware("http")(database_error_handler)
|
# app.middleware("http")(database_error_handler)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,21 @@ from packages.v1.administrativo.models.ato_documento_model import AtoDocumento
|
||||||
from packages.v1.administrativo.schemas.ato_principal_schema import (
|
from packages.v1.administrativo.schemas.ato_principal_schema import (
|
||||||
AtoPrincipalCodigoAtoSchema,
|
AtoPrincipalCodigoAtoSchema,
|
||||||
)
|
)
|
||||||
from actions.validations.hash import generate_storage_hash
|
from actions.validations.hash import (
|
||||||
|
generate_storage_hash,
|
||||||
|
generate_temporary_token,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# === Recupera configurações e chave AES ===
|
# === Recupera configurações e chave AES ===
|
||||||
DB_SETTINGS = get_database_settings()
|
DB_SETTINGS = get_database_settings()
|
||||||
AES_KEY = getattr(DB_SETTINGS, "aeskey", None)
|
AES_KEY = getattr(DB_SETTINGS, "aeskey", None)
|
||||||
URL_API = getattr(DB_SETTINGS, "url_api", None)
|
URL_API = getattr(DB_SETTINGS, "url_api", None)
|
||||||
|
|
||||||
|
# === Configuração do token temporário ===
|
||||||
|
SECRET_KEY = getattr(DB_SETTINGS, "aeskey", None)
|
||||||
|
ALGORITHM = "HS256"
|
||||||
|
|
||||||
|
|
||||||
class ShowAtosRepository:
|
class ShowAtosRepository:
|
||||||
"""
|
"""
|
||||||
|
|
@ -107,11 +115,14 @@ class ShowAtosRepository:
|
||||||
documentos_list = [
|
documentos_list = [
|
||||||
{
|
{
|
||||||
"url": (
|
"url": (
|
||||||
URL_API
|
f"{URL_API}/view/{generate_storage_hash()}/{d.url.decode('utf-8')}?token="
|
||||||
+ "/"
|
+ generate_temporary_token(
|
||||||
+ generate_storage_hash()
|
generate_storage_hash(),
|
||||||
+ "/"
|
d.url.decode("utf-8"),
|
||||||
+ d.url.decode("utf-8")
|
10,
|
||||||
|
SECRET_KEY,
|
||||||
|
ALGORITHM,
|
||||||
|
)
|
||||||
if d.url
|
if d.url
|
||||||
else None
|
else None
|
||||||
),
|
),
|
||||||
|
|
@ -175,11 +186,14 @@ class ShowAtosRepository:
|
||||||
documentos_vinc_list = [
|
documentos_vinc_list = [
|
||||||
{
|
{
|
||||||
"url": (
|
"url": (
|
||||||
URL_API
|
f"{URL_API}/view/{generate_storage_hash()}/{d.url.decode('utf-8')}?token="
|
||||||
+ "/"
|
+ generate_temporary_token(
|
||||||
+ generate_storage_hash()
|
generate_storage_hash(),
|
||||||
+ "/"
|
d.url.decode("utf-8"),
|
||||||
+ d.url.decode("utf-8")
|
10,
|
||||||
|
SECRET_KEY,
|
||||||
|
ALGORITHM,
|
||||||
|
)
|
||||||
if d.url
|
if d.url
|
||||||
else None
|
else None
|
||||||
),
|
),
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue