Autenticação e Permissões¶
📋 Visão Geral¶
O Motor de Pricing utiliza um sistema de autenticação próprio baseado em bcrypt para hash de senhas e BigQuery como backend de usuários. O controle de acesso é feito por rotas protegidas e níveis de permissão.
🔐 Fluxo de Autenticação¶
sequenceDiagram
participant U as Usuário
participant App as Dash App
participant BQ as BigQuery
U->>App: Email + Senha
App->>BQ: buscar_usuario_por_email(email)
BQ-->>App: Dados do usuário (com password_hash)
App->>App: verificar_senha(senha, password_hash) [bcrypt]
alt Senha válida
App-->>U: Login OK → Redirect para /command-center
App->>App: Armazenar token no dcc.Store (sessão)
App->>App: Pré-carregar 18 tabelas em paralelo
else Senha inválida
App-->>U: Erro de autenticação
end
👤 Gestão de Usuários¶
Os usuários são armazenados na tabela usuario_sistema_pricing no BigQuery, dentro do dataset gold_pricing.
Campos da Tabela¶
| Campo | Descrição |
|---|---|
id |
Identificador único do usuário |
user |
Email do usuário (usado como login) |
password_hash |
Hash bcrypt da senha |
permission_name |
Nível de permissão |
user_id |
ID do usuário para filtro de dados |
Segurança
O campo password_hash é removido dos dados retornados após autenticação bem-sucedida para evitar exposição.
🛡️ Proteção de Rotas¶
As rotas são classificadas em duas categorias:
Rotas Públicas (sem autenticação)¶
| Rota | Descrição |
|---|---|
/ |
Redirect para login |
/login |
Página de login |
Rotas Protegidas (requerem autenticação)¶
| Rota | Descrição |
|---|---|
/current-price-list |
Lista de preços atual |
/price-architecture |
Arquitetura de preços |
/price-list |
Lista de preços gerada |
/command-center |
Command Center |
/margin-impact |
Impacto na margem |
/price-decomposition |
Decomposição do preço |
O callback render_page_content em app.py verifica a autenticação em toda navegação:
- Se a rota é pública → renderiza sem sidebar
- Se o usuário não está autenticado → redireciona para login
- Se autenticado → renderiza com sidebar visível
🔑 Níveis de Permissão¶
O sistema suporta os seguintes níveis de permissão via check_permission():
| Permissão | Acesso |
|---|---|
ADMIN |
Acesso total — pode tudo |
WRITE_ALL |
Acesso de escrita em todas as áreas |
| Permissões específicas | Acesso granular por funcionalidade |
A verificação segue a hierarquia:
- Se o usuário é
ADMIN→ sempre permitido - Se a permissão requerida começa com
WRITEe o usuário temWRITE_ALL→ permitido - Se a permissão do usuário coincide com a requerida → permitido
- Caso contrário → negado (com log de warning)
🔧 Funções Principais¶
auth_utils.py¶
| Função | Finalidade |
|---|---|
autenticar_usuario(email, senha) |
Fluxo completo de autenticação |
verificar_senha(senha_texto, senha_hash) |
Compara senha com hash bcrypt |
buscar_usuario_por_email(email) |
Consulta BigQuery por email |
is_user_authenticated(user_data) |
Verifica se o token de sessão é válido |
is_public_route(pathname) |
Verifica se a rota é pública |
is_protected_route(pathname) |
Verifica se a rota requer autenticação |
check_permission(user_data, permission) |
Verifica permissão específica |
require_auth(user_data) |
Exige autenticação (lança exceção) |
log_access_attempt(pathname, user, success) |
Registra tentativa de acesso no log |
Decorator @auth_required¶
Pode ser usado em callbacks para exigir autenticação:
@auth_required
@app.callback(...)
def meu_callback(user_data, ...):
# Só executa se o usuário estiver autenticado
pass
📊 Logging de Segurança¶
Todas as tentativas de acesso são registradas via log_access_attempt():
- ✅
AUTHORIZED— acesso permitido - ❌
UNAUTHORIZED— acesso negado
Os logs incluem: rota acessada, email do usuário e status.
Última atualização: Março 2026 | Versão 1.0