import os import json import uuid from datetime import datetime from flask import current_app from flask_login import UserMixin from app import bcrypt from utils.file_utils import load_json_file, save_json_file from services.auth_service import ( get_user_by_username, get_user_by_id, get_all_users, create_user, update_user, delete_user, ) class User(UserMixin): """Clase de usuario para Flask-Login.""" def __init__(self, user_id, user_data): self.id = user_id self.username = user_data.get("username", "") self.nombre = user_data.get("nombre", "") self.email = user_data.get("email", "") self.nivel = user_data.get("nivel", 0) self.idioma = user_data.get("idioma", "es") self.fecha_caducidad = user_data.get("fecha_caducidad") self.empresa = user_data.get("empresa", "") self.estado = user_data.get("estado", "activo") self.ultimo_acceso = user_data.get("ultimo_acceso") def has_permission(self, required_level): """Verificar si el usuario tiene el nivel de permiso requerido.""" return self.nivel >= required_level and self.estado == "activo" def to_dict(self): """Convertir el usuario a un diccionario para almacenamiento.""" return { "username": self.username, "nombre": self.nombre, "email": self.email, "nivel": self.nivel, "idioma": self.idioma, "fecha_caducidad": self.fecha_caducidad, "empresa": self.empresa, "estado": self.estado, "ultimo_acceso": self.ultimo_acceso, } def get_users_file_path(): """Obtener la ruta al archivo de usuarios.""" storage_path = current_app.config["STORAGE_PATH"] return os.path.join(storage_path, "users", "users.json") def get_all_users(): """Obtener todos los usuarios del sistema.""" users_data = load_json_file(get_users_file_path(), {}) return users_data def get_user_by_id(user_id): """Obtener un usuario por su ID.""" if not user_id: return None users_data = load_json_file(get_users_file_path(), {}) if user_id in users_data: return User(user_id, users_data[user_id]) return None # Este archivo importa funcionalidades de auth_service.py para mantener # consistencia en la estructura del proyecto, y agrega funcionalidades específicas # de gestión de usuarios que no están relacionadas con la autenticación. def filter_users(filter_params): """ Filtrar usuarios según los parámetros proporcionados. Args: filter_params (dict): Diccionario con parámetros de filtrado - empresa: Nombre de empresa - estado: Estado del usuario ('activo', 'inactivo') - nivel_min: Nivel mínimo de permiso - nivel_max: Nivel máximo de permiso Returns: list: Lista de objetos User que cumplen los criterios """ users = get_all_users() filtered_users = [] for user in users: # Filtrar por empresa if "empresa" in filter_params and filter_params["empresa"]: if user.empresa != filter_params["empresa"]: continue # Filtrar por estado if "estado" in filter_params and filter_params["estado"]: if user.estado != filter_params["estado"]: continue # Filtrar por nivel mínimo if "nivel_min" in filter_params and filter_params["nivel_min"] is not None: if user.nivel < int(filter_params["nivel_min"]): continue # Filtrar por nivel máximo if "nivel_max" in filter_params and filter_params["nivel_max"] is not None: if user.nivel > int(filter_params["nivel_max"]): continue # Si pasó todos los filtros, agregar a la lista filtered_users.append(user) return filtered_users def get_user_stats(): """ Obtener estadísticas sobre los usuarios. Returns: dict: Diccionario con estadísticas """ users = get_all_users() # Inicializar estadísticas stats = { "total": len(users), "activos": 0, "inactivos": 0, "expirados": 0, "por_empresa": {}, "por_nivel": { "admin": 0, # Nivel 9000+ "gestor": 0, # Nivel 5000-8999 "editor": 0, # Nivel 1000-4999 "lector": 0, # Nivel 0-999 }, } # Calcular estadísticas for user in users: # Estado if user.estado == "activo": stats["activos"] += 1 else: stats["inactivos"] += 1 # Expirados if user.is_expired(): stats["expirados"] += 1 # Por empresa empresa = user.empresa or "Sin empresa" stats["por_empresa"][empresa] = stats["por_empresa"].get(empresa, 0) + 1 # Por nivel if user.nivel >= 9000: stats["por_nivel"]["admin"] += 1 elif user.nivel >= 5000: stats["por_nivel"]["gestor"] += 1 elif user.nivel >= 1000: stats["por_nivel"]["editor"] += 1 else: stats["por_nivel"]["lector"] += 1 return stats def check_username_availability(username): """ Verificar si un nombre de usuario está disponible. Args: username (str): Nombre de usuario a verificar Returns: bool: True si está disponible, False si ya existe """ user = get_user_by_username(username) return user is None