refatoração de segurança e logs

This commit is contained in:
Luiz Silva 2026-01-01 19:13:24 -03:00
parent 6873b87a85
commit 663a8d5bf2
12 changed files with 362 additions and 37 deletions

View file

@ -6,6 +6,8 @@ import (
"strings"
"time"
"e-li.nps/internal/db"
"github.com/jackc/pgx/v5"
)
@ -42,7 +44,10 @@ ORDER BY tablename`)
// - 78 neutros
// - 910 promotores
func (s *Store) NPSMesAMes(ctx context.Context, tabela string, meses int) ([]NPSMensal, error) {
// Segurança: tabela deve ser derivada de NormalizeProduto + prefixo.
// Segurança: a tabela é um identificador interpolado. Validamos sempre.
if !db.TableNameValido(tabela) {
return nil, fmt.Errorf("tabela invalida")
}
q := fmt.Sprintf(`
WITH base AS (
SELECT
@ -103,6 +108,11 @@ func (f *ListarRespostasFiltro) normalizar() {
// ListarRespostas retorna respostas respondidas, com paginação e filtro.
func (s *Store) ListarRespostas(ctx context.Context, tabela string, filtro ListarRespostasFiltro) ([]RespostaPainel, error) {
// Segurança: a tabela é um identificador interpolado. Validamos sempre.
if !db.TableNameValido(tabela) {
return nil, fmt.Errorf("tabela invalida")
}
filtro.normalizar()
offset := (filtro.Pagina - 1) * filtro.PorPagina
@ -111,6 +121,9 @@ func (s *Store) ListarRespostas(ctx context.Context, tabela string, filtro Lista
cond += " AND nota BETWEEN 1 AND 6"
}
// Importante (segurança): apesar do cond ser construído em string, ele NÃO usa
// entrada do usuário diretamente. O filtro "SomenteNotasBaixas" é booleano.
// A tabela também é validada por regex (TableNameValido).
q := fmt.Sprintf(`
SELECT
id,