IOI-RUN / login.py
Roudrigus's picture
Upload 82 files
0f0ef8d verified
raw
history blame
6.77 kB
# -*- coding: utf-8 -*-
import streamlit as st
from banco import SessionLocal
from models import Usuario
from utils_seguranca import verificar_senha
from utils_auditoria import registrar_log
# 🔀 Roteador de banco (Produção/Teste/Treinamento)
# Observação: este import assume que db_router.py está na raiz do projeto.
# Se ainda não existir, usamos um fallback suave (default 'prod').
try:
from db_router import set_db_choice, current_db_choice, list_banks, bank_label
_HAS_ROUTER = True
except Exception:
_HAS_ROUTER = False
def set_db_choice(choice: str):
st.session_state["__db_choice__"] = (choice or "prod").lower()
def current_db_choice() -> str:
return st.session_state.get("__db_choice__", "prod")
def list_banks():
return ["prod", "test"] # fallback básico
def bank_label(choice: str) -> str:
return {"prod": "Banco 1 (📗 Produção)", "test": "Banco 2 (📕 Teste)"}.get(choice, choice)
def _mostrar_efeito_aniversario(nome: str):
"""Exibe imediatamente efeito e mensagem central de aniversário."""
# Efeito visual (confete e balões)
st.snow()
st.balloons()
# Mensagem centralizada
st.markdown(
f"""
<div style="
display:flex;align-items:center;justify-content:center;
text-align:center;margin:40px 0 20px 0;">
<div style="
font-size: 32px; font-weight: 800; color:#A020F0;
background:linear-gradient(90deg,#FFF0F6,#F0E6FF);
padding:16px 24px;border-radius:16px;box-shadow:0 4px 10px rgba(0,0,0,.08);">
🎉 Feliz Aniversário, {nome}! 🎉
</div>
</div>
""",
unsafe_allow_html=True
)
st.caption("Desejamos a você muitas conquistas e bons embarques ao longo do ano! 💜")
def login():
st.subheader("🔐 Login")
# ✅ Seleção do banco (dinâmica) — armazenado em sessão para toda a navegação
# Mantém experiência simples e clara para o usuário.
banks = list_banks() # ex.: ['prod', 'test', 'treinamento']
labels = [bank_label(b) for b in banks] # rótulos amigáveis para UI
idx_default = banks.index("prod") if "prod" in banks else 0
banco_label = st.selectbox("Usar banco:", labels, index=idx_default)
db_choice = banks[labels.index(banco_label)]
set_db_choice(db_choice)
# (Opcional) Indicação visual do banco ativo na sidebar
# Usando ícones diferentes para cada ambiente:
ambiente = current_db_choice()
if ambiente == "prod":
badge = "🟢 Produção"
elif ambiente == "test":
badge = "🔴 Teste"
elif ambiente == "treinamento":
badge = "🔵 Treinamento"
else:
badge = ambiente
st.sidebar.caption(f"🗄️ Banco ativo: {badge}")
# Campos de credencial
usuario_input = st.text_input("Usuário")
senha_input = st.text_input("Senha", type="password")
# 🔘 Botão de entrada (mantendo seu fluxo)
if st.button("Entrar", type="primary"):
db = SessionLocal()
try:
usuario_db = (
db.query(Usuario)
.filter(
Usuario.usuario == usuario_input,
Usuario.ativo == True
)
.first()
)
if not usuario_db or not verificar_senha(senha_input, usuario_db.senha):
st.error("❌ Usuário ou senha inválidos.")
# 📝 Auditoria — registra também o ambiente atual (prod/test/treinamento)
try:
registrar_log(
usuario=usuario_input,
acao="Tentativa de login inválida",
tabela="usuarios",
ambiente=current_db_choice()
)
except Exception:
# Não quebra o fluxo se auditoria falhar
pass
return
# ✅ LOGIN OK
st.session_state.logado = True
st.session_state.usuario = usuario_db.usuario
st.session_state.perfil = usuario_db.perfil
# ✅ Armazenar e-mail e, se disponível, nome (para exibição na UI)
# Obs.: getattr evita erro caso o campo não exista ou esteja nulo.
st.session_state.email = getattr(usuario_db, "email", None)
st.session_state.nome = getattr(usuario_db, "nome", None)
# 🔁 IMPORTANTE: força revalidação do quiz
st.session_state.quiz_verificado = False
# 📝 Auditoria de sucesso — registra o ambiente
try:
registrar_log(
usuario=usuario_db.usuario,
acao="Login realizado com sucesso",
tabela="usuarios",
registro_id=usuario_db.id,
ambiente=current_db_choice()
)
except Exception:
pass
# 🎂 NOVO: checagem de data de aniversário (mês/dia), compatível com Date e ISO string
try:
from datetime import date as _date
def _to_date_safe(val):
if not val:
return None
# já é 'date'?
if isinstance(val, _date):
return val
# tenta converter de string ISO "YYYY-MM-DD"
try:
yy, mm, dd = map(int, str(val).split("-"))
return _date(yy, mm, dd)
except Exception:
return None
dn = _to_date_safe(getattr(usuario_db, "data_aniversario", None))
hoje = _date.today()
if dn and (dn.month == hoje.month and dn.day == hoje.day):
# Mostra efeito imediatamente (antes do rerun)
nome_exibir = st.session_state.get("nome") or st.session_state.get("usuario") or "Usuário"
_mostrar_efeito_aniversario(nome_exibir)
# Opcional: também sinaliza para main() caso queira reapresentar em outra área
st.session_state["__show_birthday__"] = True
except Exception:
# Não impede o login se algo falhar nessa checagem
pass
st.success("✅ Login realizado com sucesso!")
st.rerun()
finally:
db.close()