class Autenticacion(metaclass=Singleton): def __init__(self, servicio_db): self.__autenticacion_log = Applogging("Autenticacion") self.servicio_db = servicio_db self.__sesion = servicio_db.sesion self.usuario_autenticado = False self.ultima_autenticacion = None def crear_usuario(self, nombre_form, email_form, contrasenia_form) -> bool: try: self.__sesion = self.servicio_db.crear_nueva_conexion_si_ha_caducado( ) if (self.__sesion.query( exists().where(Usuario.nombre == nombre_form)).scalar()): self.__autenticacion_log.warning_log( f"El usuario con nombre {nombre_form} ya existe") return False else: nuevo_usuario = Usuario(nombre_form, email_form, contrasenia_form) self.__sesion.add(nuevo_usuario) self.__sesion.commit() return True except: self.__autenticacion_log.error_log( "Ha habido un problema para crear usuario") return False def comprobar_autenticacion(self, nombre_form, contrasenia_form) -> bool: try: self.__sesion = self.servicio_db.crear_nueva_conexion_si_ha_caducado( ) if (self.__sesion.query( exists().where(Usuario.nombre == nombre_form)).scalar()): usuario = self.__sesion.query(Usuario).filter_by( nombre=nombre_form).first() self.__sesion.commit() if (usuario.get_contrasenia() != contrasenia_form): self.__autenticacion_log.warning_log( f"El usuario con nombre {nombre_form} existe pero las credenciales no son correctas" ) return self.usuario_autenticado elif (usuario.get_contrasenia() == contrasenia_form): self.usuario_autenticado = True self.__autenticacion_log.info_log("Usuario autenticado") self.ultima_autenticacion = time.time() return self.usuario_autenticado else: self.__autenticacion_log.warning_log( f"El usuario con nombre {nombre_form} no existe") return self.usuario_autenticado except: self.__autenticacion_log.error_log( "Ha habido un problema con la autenticacion")
class MysqlDB(metaclass=Singleton): def __init__(self, app, _app_ctx_stack): self.__app = app self.__mysql_log = Applogging("MysqlDB") self.__server_ssh = None self.engine = None self.sesion = None self.__iniciar_instancias_conexiones(_app_ctx_stack) def crear_nueva_conexion_si_ha_caducado(self): try: self.sesion.rollback() id = self.engine.execute( "SELECT id FROM domotoyawsdatabase.usuario").first() return self.sesion except Exception: self.__mysql_log.warning_log( "La sesion ha caducado o ha habido un problema inesperado") self.__server_ssh = self.__crear_tunel_ssh() self.__crear_conexion_demotoy_database() self.__mysql_log.info_log("Se ha establecido una nueva conexion") return self.sesion def __iniciar_instancias_conexiones(self, _app_ctx_stack): try: puerto_socket_ssh = self.__iniciar_ssh() self.__iniciar_mysql(puerto_socket_ssh) except Exception: self.__mysql_log.error_log( "No se han podido iniciar las instancias de la conexion") self.__mysql_log.info_log( "Inciando conexion con una base de datos local") self.__iniciar_mysql("3306") except Exception: self.__mysql_log.error_log( "No se han podido iniciar las instancias de la conexion") def __iniciar_ssh(self) -> str: self.__obtener_direccion_remota_ssh() self.__server_ssh = self.__crear_tunel_ssh() puerto_socket_ssh = str(self.__server_ssh.local_bind_port) return puerto_socket_ssh def __obtener_direccion_remota_ssh(self) -> str: global SSH_IP_REMOTA, SSH_PUERTO, SSH_NOMBRE_USUARIO, SSH_PRIVATE_KEY_PATH try: with open("awsserversettings.json") as server_settings_json: datos = json.load(server_settings_json) for configuracion in datos['ssh-settings']: SSH_IP_REMOTA = configuracion['host-remote'] SSH_PUERTO = configuracion['port'] SSH_NOMBRE_USUARIO = configuracion['server-user'] SSH_PRIVATE_KEY_PATH = configuracion['private-key'] except Exception: self.__mysql_log.error_log( "No se ha podido obtener las credenciales de servidor remoto") def __crear_tunel_ssh(self) -> SSHTunnelForwarder: try: server = SSHTunnelForwarder( (SSH_IP_REMOTA, SSH_PUERTO), ssh_username=SSH_NOMBRE_USUARIO, ssh_pkey=SSH_PRIVATE_KEY_PATH, remote_bind_address=(MYSQL_IP_LOCAL, MYSQl_PUERTO), ) self.__mysql_log.info_log( f"Utilizando la direccion remota {SSH_IP_REMOTA}:{SSH_PUERTO} con IP host servidor {MYSQL_IP_LOCAL}:{MYSQl_PUERTO}" ) server.start() return server except Exception: self.__mysql_log.error_log( "No se han podido establecer la conexion ssh") def __iniciar_mysql(self, puerto_socket_ssh): self.__cadena_conexion = self.__obtener_direcion_remota_mysql( puerto_socket_ssh) self.__mysql_log.info_log( f"Utilizando direccion mysql mediante ssh: {self.__cadena_conexion}" ) self.engine = create_engine(self.__cadena_conexion, pool_pre_ping=True) self.__crear_conexion_demotoy_database() def __obtener_direcion_remota_mysql(self, puerto_socket_ssh) -> str: global MYSQL_IP_LOCAL, MYSQL_USER, MYSQL_CONTRASENIA, MYSQl_PUERTO, MYSQL_NOMBRE_DB, PUERTO_SOCKET_LOCAL try: PUERTO_SOCKET_LOCAL = puerto_socket_ssh cadena_conexion = None with open("awsserversettings.json") as server_settings_json: datos = json.load(server_settings_json) self.__mysql_log.info_log(datos) for configuracion in datos['mysql-server-settings']: MYSQL_IP_LOCAL = configuracion['host-local'] MYSQL_USER = configuracion['admin-user'] MYSQL_CONTRASENIA = configuracion['password'] MYSQl_PUERTO = configuracion['mysql-port'] MYSQL_NOMBRE_DB = configuracion['db'] cadena_conexion = self.__crear_cadena_conexion( MYSQL_USER, MYSQL_CONTRASENIA, MYSQL_IP_LOCAL, PUERTO_SOCKET_LOCAL, MYSQL_NOMBRE_DB) return cadena_conexion except Exception: self.__mysql_log.error_log( "No se ha podido obtener las credenciales de servidor remoto") def __crear_cadena_conexion(self, usuario, contrasenia, ip_local, puerto_socket, base_de_datos): return f"mysql+mysqldb://{usuario}:{contrasenia}@{ip_local}:{puerto_socket}/{base_de_datos}" def __crear_conexion_demotoy_database(self): global MYSQL_NOMBRE_DB try: self.engine.connect() Session = sessionmaker(autocommit=False, autoflush=False, bind=self.engine) self.sesion = Session() except Exception: self.__mysql_log.error_log( "Error al intentar crear la conexión con la base de datos: {MYSQL_NOMBRE_DB}" )
class Autenticacion(metaclass=Singleton): def __init__(self, servicio_db): self.__autenticacion_log = Applogging("Autenticacion") self.servicio_db = servicio_db self.__sesion = servicio_db.sesion self.usuario_autenticado = False self.ultima_autenticacion = None self.usuario = None def crear_usuario(self, modelo_nuevo_usuario: CrearModeloUsuario) -> bool: try: self.__sesion = self.servicio_db.crear_nueva_conexion_si_ha_caducado( ) if (self.__usuario_existe(modelo_nuevo_usuario.nombre)): return False else: modelo_nuevo_usuario = Usuario( nombre=modelo_nuevo_usuario.nombre, email=modelo_nuevo_usuario.email, contrasenia=modelo_nuevo_usuario.contrasenia, nombre_completo=modelo_nuevo_usuario.nombre_completo, numero_telefono=modelo_nuevo_usuario.numero_telefono, direccion=modelo_nuevo_usuario.direccion) self.__sesion.add(modelo_nuevo_usuario) self.__sesion.commit() return True except: self.__autenticacion_log.error_log( "Ha habido un problema para crear usuario") return False def comprobar_autenticacion(self, modelo_auth: ComprobarModeloUsuario) -> bool: try: self.__sesion = self.servicio_db.crear_nueva_conexion_si_ha_caducado( ) if (self.__usuario_existe(modelo_auth.nombre)): usuario_existente = self.__obtener_usuario(modelo_auth.nombre) self.__sesion.commit() self.__comprobar_credenciales(usuario_existente, modelo_auth.nombre, modelo_auth.contrasenia) return self.usuario_autenticado else: self.__autenticacion_log.warning_log( f"El usuario con nombre {modelo_auth.nombre} no existe") return self.usuario_autenticado except: self.__autenticacion_log.error_log( "Ha habido un problema con la autenticacion") def __usuario_existe(self, nombre_form) -> bool: if (self.__sesion.query( exists().where(Usuario.nombre == nombre_form)).scalar()): self.__autenticacion_log.info_log( f"El usuario con nombre {nombre_form} existe") return True else: return False def __obtener_usuario(self, nombre_form: str): usuario = self.__sesion.query(Usuario).filter_by( nombre=nombre_form).first() return usuario def __comprobar_credenciales(self, usuario_existente: Usuario, nombre_form: str, contrasenia_form: str): if (usuario_existente.get_contrasenia() != contrasenia_form): self.__autenticacion_log.warning_log( f"El usuario con nombre {nombre_form} existe pero las credenciales no son correctas" ) elif (usuario_existente.get_contrasenia() == contrasenia_form): self.__estado_autenticado_true(usuario_existente) def __estado_autenticado_true(self, usuario_existente: Usuario): self.usuario_autenticado = True self.usuario = usuario_existente self.__autenticacion_log.info_log("Usuario autenticado") self.ultima_autenticacion = time.time()
class RepositorioUsuario(RepositorioBase[Usuario]): def __init__(self, servicio_db, sesion): super().__init__(servicio_db, sesion) self.__repositorio_log = Applogging("UsuarioRepo") def obtener_usuario(self, nombre: str) -> CrudResultT[Usuario]: try: self.sesion = self.servicio_db.crear_nueva_conexion_si_ha_caducado( ) usuario = self.sesion.query(Usuario).filter_by( Usuario.nombre == nombre).first() self.sesion.commit() if (usuario == None): self.__repositorio_log.warning_log( f"El suaurio con nombre:{nombre} no fue encontrado") return crudResultT.not_found() else: self.__repositorio_log.info_log( f"El suaurio con nombre:{nombre} no fue encontrado") return crudResultT.success(usuario) except Exception: self.__repositorio_log.error_log( f"No se han podido obtener la entidad con nombre:{nombre}") return crudResultT.error() def obtener_usuarios(self) -> list: usuarios = self.obtener_todo() if (usuarios == None): self.__repositorio_log.error_log("No se han encontrado usuarios") return crudResultT.not_found() else: self.__repositorio_log.error_log("Obteniendo todos los suarios") return crudResultT.success(usuarios) async def task_crear_usuario(self, usuario: Usuario) -> CrudResult: if (await self.sesion.query( exists().where(Usuario.nombre == usuario.nombre)).scalar()): self.__repositorio_log.warning_log( f"El suaurio {usuario.nombre} ya existe") return crudResult.error() else: self.__repositorio_log.info_log( f"El suaurio {usuario.nombre} no existe") resultado = await self.task_insertar_entidad(usuario) if (resultado): crudResult.success() else: return crudResult.error() def eliminar_usuario(self, usuario: Usuario) -> CrudResult: try: self.sesion = self.servicio_db.crear_nueva_conexion_si_ha_caducado( ) if (self.sesion.query( exists().where(Usuario.id == usuario.id)).scalar()): self.sesion.query(Usuario).filter_by( Usuario.id == usuario.id).delete( synchronize_session='evaluate') self.sesion.commit() return crudResult.success() else: return crudResult.not_found() except Exception: self.__repositorio_log.error_log( f"No se han podido eliminar la entidad {usuario}") return crudResult.error()