O algoritmo (CHAVE_INTERNA + funcoes gerarReativacao/gerarInstalacao) ficava 100% legivel no codigo-fonte da pagina — qualquer pessoa com acesso ao painel conseguia abrir o DevTools e extrair a logica pra gerar chaves de licenca fora do sistema. Move tudo pra app/gerador_chave.py (roda so no servidor) e expoe via POST /gerador-chave/gerar (autenticado, protegido por CSRF). A pagina agora so manda os dados do formulario e mostra o resultado que volta do backend. Algoritmo verificado byte-a-byte contra os 3 exemplos reais conhecidos (cliente 000001, ALUGUEL). Bonus: o byte inicial agora usa secrets.randbelow (CSPRNG) em vez de Math.random() do JS. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
103 lines
3.6 KiB
Python
103 lines
3.6 KiB
Python
from fastapi import FastAPI
|
|
from fastapi.testclient import TestClient
|
|
|
|
from app.auth import exigir_login
|
|
from app.routers import chave_manual as router_chave_manual
|
|
|
|
app_teste = FastAPI()
|
|
app_teste.include_router(router_chave_manual.router)
|
|
app_teste.dependency_overrides[exigir_login] = lambda: "teste"
|
|
client = TestClient(app_teste)
|
|
CSRF_TESTE = "teste-csrf-token"
|
|
client.cookies.set("csrf_token", CSRF_TESTE)
|
|
|
|
|
|
def test_pagina_gerador_carrega():
|
|
resposta = client.get("/gerador-chave")
|
|
assert resposta.status_code == 200
|
|
assert "Gerador de Chave" in resposta.text
|
|
# O algoritmo NUNCA pode voltar a aparecer no HTML/JS da página — ele
|
|
# roda só no backend (app/gerador_chave.py) desde que essa exposição
|
|
# foi corrigida.
|
|
assert "CHAVE_INTERNA" not in resposta.text
|
|
assert "function gerarReativacao" not in resposta.text
|
|
assert "function gerarInstalacao" not in resposta.text
|
|
|
|
|
|
def test_pagina_gerador_nao_grava_nada():
|
|
# GET /gerador-chave não recebe csrf_token no cookie/form combinando
|
|
# com nada que grave — só há dois POSTs possíveis nesse router:
|
|
# /gerador-chave (não existe, 405) e /gerador-chave/gerar (não grava
|
|
# em Clientes_Chaves, só calcula e devolve).
|
|
resposta = client.post("/gerador-chave")
|
|
assert resposta.status_code == 405
|
|
|
|
|
|
def test_gerar_reativacao_com_sucesso():
|
|
resposta = client.post(
|
|
"/gerador-chave/gerar",
|
|
data={"csrf_token": CSRF_TESTE, "tipo": "reativacao", "codigo": "123", "referencia": "2026-08"},
|
|
)
|
|
assert resposta.status_code == 200
|
|
corpo = resposta.json()
|
|
assert len(corpo["chave"]) == 22
|
|
assert all(c in "0123456789ABCDEF" for c in corpo["chave"])
|
|
|
|
|
|
def test_gerar_instalacao_com_sucesso_bate_com_exemplo_conhecido():
|
|
# Não dá pra fixar o byte aleatório via HTTP, mas confere que o valor do
|
|
# cliente (1*19+31=50) aparece embutido no meio da chave, como o
|
|
# algoritmo real exige.
|
|
resposta = client.post(
|
|
"/gerador-chave/gerar",
|
|
data={"csrf_token": CSRF_TESTE, "tipo": "instalacao", "codigo": "000001", "modalidade": "ALUGUEL"},
|
|
)
|
|
assert resposta.status_code == 200
|
|
corpo = resposta.json()
|
|
assert len(corpo["chave"]) == 8
|
|
assert corpo["chave"][3:5] == "50"
|
|
|
|
|
|
def test_gerar_codigo_invalido_bloqueia():
|
|
resposta = client.post(
|
|
"/gerador-chave/gerar",
|
|
data={"csrf_token": CSRF_TESTE, "tipo": "instalacao", "codigo": "abc123", "modalidade": "ALUGUEL"},
|
|
)
|
|
assert resposta.status_code == 400
|
|
assert "6 dígitos" in resposta.json()["erro"]
|
|
|
|
|
|
def test_gerar_reativacao_sem_referencia_bloqueia():
|
|
resposta = client.post(
|
|
"/gerador-chave/gerar",
|
|
data={"csrf_token": CSRF_TESTE, "tipo": "reativacao", "codigo": "123", "referencia": ""},
|
|
)
|
|
assert resposta.status_code == 400
|
|
assert "mês/ano" in resposta.json()["erro"]
|
|
|
|
|
|
def test_gerar_instalacao_modalidade_invalida_bloqueia():
|
|
resposta = client.post(
|
|
"/gerador-chave/gerar",
|
|
data={"csrf_token": CSRF_TESTE, "tipo": "instalacao", "codigo": "123", "modalidade": "X"},
|
|
)
|
|
assert resposta.status_code == 400
|
|
assert "Modalidade" in resposta.json()["erro"]
|
|
|
|
|
|
def test_gerar_tipo_invalido_bloqueia():
|
|
resposta = client.post(
|
|
"/gerador-chave/gerar",
|
|
data={"csrf_token": CSRF_TESTE, "tipo": "outracoisa", "codigo": "123"},
|
|
)
|
|
assert resposta.status_code == 400
|
|
assert "Tipo de chave" in resposta.json()["erro"]
|
|
|
|
|
|
def test_gerar_sem_csrf_bloqueia():
|
|
resposta = client.post(
|
|
"/gerador-chave/gerar",
|
|
data={"tipo": "instalacao", "codigo": "123", "modalidade": "ALUGUEL"},
|
|
)
|
|
assert resposta.status_code == 403
|