|
|
""" |
|
|
M贸dulo de autenticaci贸n para la aplicaci贸n Veureu. |
|
|
Gestiona usuarios, verificaci贸n de contrase帽as y sincronizaci贸n de usuarios por defecto. |
|
|
""" |
|
|
import sys |
|
|
import streamlit as st |
|
|
from datetime import datetime |
|
|
from databases import get_user, create_user, update_user_password, get_all_users |
|
|
from mobile_verification import ( |
|
|
initialize_sms_state, |
|
|
render_mobile_verification_screen, |
|
|
get_user_permissions, |
|
|
show_verification_status_in_sidebar |
|
|
) |
|
|
|
|
|
|
|
|
def log(msg: str): |
|
|
"""Helper per logging amb timestamp""" |
|
|
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") |
|
|
sys.stderr.write(f"[{timestamp}] {msg}\n") |
|
|
sys.stderr.flush() |
|
|
|
|
|
|
|
|
def verify_password(password: str, stored_password: str) -> bool: |
|
|
"""Verifica la contrase帽a como texto plano.""" |
|
|
return password == stored_password |
|
|
|
|
|
|
|
|
def create_default_users_if_needed(): |
|
|
"""Asegura que existan los usuarios por defecto y sus contrase帽as esperadas (texto plano).""" |
|
|
log("Sincronizando usuarios por defecto...") |
|
|
users_to_create = [ |
|
|
("verd", "verd123", "verd"), |
|
|
("groc", "groc123", "groc"), |
|
|
("taronja", "taronja123", "taronja"), |
|
|
("blau", "blau123", "blau"), |
|
|
("vermell", "vermell123", "vermell"), |
|
|
] |
|
|
for username, password, role in users_to_create: |
|
|
try: |
|
|
row = get_user(username) |
|
|
if row: |
|
|
update_user_password(username, password) |
|
|
log(f"Usuario '{username}' actualizado (password reset).") |
|
|
else: |
|
|
create_user(username, password, role) |
|
|
log(f"Usuario '{username}' creado.") |
|
|
except Exception as e: |
|
|
log(f"Error sincronizando usuario {username}: {e}") |
|
|
|
|
|
|
|
|
def initialize_auth_system(db_path: str): |
|
|
"""Inicializa el sistema de autenticaci贸n y sincroniza usuarios.""" |
|
|
if 'users_synced' not in st.session_state: |
|
|
create_default_users_if_needed() |
|
|
st.session_state['users_synced'] = True |
|
|
|
|
|
|
|
|
initialize_sms_state() |
|
|
|
|
|
|
|
|
if 'diag_logged' not in st.session_state: |
|
|
log("\n--- DIAGN脫STICO DE BASE DE DATOS ---") |
|
|
log(f"Ruta de la BD en uso: {db_path}") |
|
|
try: |
|
|
all_users = get_all_users() |
|
|
if all_users: |
|
|
log("Usuarios encontrados en la BD al arrancar:") |
|
|
users_list = [dict(user) for user in all_users] |
|
|
log(str(users_list)) |
|
|
else: |
|
|
log("La tabla de usuarios est谩 vac铆a.") |
|
|
except Exception as e: |
|
|
log(f"Error al intentar leer los usuarios de la BD: {e}") |
|
|
log("--- FIN DIAGN脫STICO ---\n") |
|
|
st.session_state['diag_logged'] = True |
|
|
|
|
|
|
|
|
def require_login(login_form_func): |
|
|
"""Requiere que el usuario est茅 autenticado.""" |
|
|
if not st.session_state.user: |
|
|
st.info("Por favor, inicia sesi贸n para continuar.") |
|
|
login_form_func() |
|
|
st.stop() |
|
|
|
|
|
|
|
|
def render_login_form(): |
|
|
"""Renderiza el formulario de login con logs de depuraci贸n.""" |
|
|
st.subheader("Inici de sessi贸") |
|
|
username = st.text_input("Usuari") |
|
|
password = st.text_input("Contrasenya", type="password") |
|
|
|
|
|
if st.button("Entrar", type="primary"): |
|
|
row = get_user(username) |
|
|
|
|
|
|
|
|
log("\n--- INTENTO DE LOGIN ---") |
|
|
log(f"Usuario introducido: '{username}'") |
|
|
log(f"Contrase帽a introducida: {'S铆' if password else 'No'}") |
|
|
|
|
|
if row: |
|
|
log(f"Usuario encontrado en BD: '{row['username']}'") |
|
|
stored_pw = (row["password_hash"] or "") |
|
|
log(f"Password almacenado (longitud): {len(stored_pw)}") |
|
|
is_valid = verify_password(password, stored_pw) |
|
|
log(f"Resultado de verify_password: {is_valid}") |
|
|
else: |
|
|
log("Usuario no encontrado en la BD.") |
|
|
is_valid = False |
|
|
|
|
|
log("--- FIN INTENTO DE LOGIN ---\n") |
|
|
|
|
|
if is_valid: |
|
|
st.session_state.user = { |
|
|
"id": row["id"], |
|
|
"username": row["username"], |
|
|
"role": row["role"] |
|
|
} |
|
|
st.success(f"Benvingut/da, {row['username']}") |
|
|
st.rerun() |
|
|
else: |
|
|
st.error("Credencials inv脿lides") |
|
|
|
|
|
|
|
|
def render_sidebar(): |
|
|
"""Renderiza la barra lateral con informaci贸n de usuario y navegaci贸n.""" |
|
|
role = st.session_state.user["role"] if st.session_state.user else None |
|
|
|
|
|
with st.sidebar: |
|
|
st.title("Veureu") |
|
|
if st.session_state.user: |
|
|
st.write(f"Usuari: **{st.session_state.user['username']}** (rol: {st.session_state.user['role']})") |
|
|
|
|
|
|
|
|
show_verification_status_in_sidebar() |
|
|
|
|
|
if st.button("Tancar sessi贸"): |
|
|
st.session_state.user = None |
|
|
st.session_state.sms_verified = None |
|
|
st.rerun() |
|
|
|
|
|
if st.session_state.user: |
|
|
|
|
|
permissions = get_user_permissions( |
|
|
role, |
|
|
st.session_state.get('sms_verified') |
|
|
) |
|
|
|
|
|
|
|
|
page_options = [] |
|
|
|
|
|
if permissions["analizar"]: |
|
|
page_options.append("Analitzar video-transcripcions") |
|
|
|
|
|
if permissions["procesar_videos"]: |
|
|
page_options.append("Processar v铆deo nou") |
|
|
|
|
|
if permissions["estadisticas"]: |
|
|
page_options.append("Estad铆stiques") |
|
|
|
|
|
if permissions["validar"]: |
|
|
page_options.append("Validaci贸") |
|
|
|
|
|
|
|
|
if not page_options: |
|
|
page_options = ["Analitzar video-transcripcions"] |
|
|
|
|
|
page = st.radio( |
|
|
"Navegaci贸", |
|
|
page_options, |
|
|
index=0 |
|
|
) |
|
|
else: |
|
|
page = None |
|
|
|
|
|
return page, role |
|
|
|