AIdeaText commited on
Commit
8716cfd
verified
1 Parent(s): 96dd9d6

Update modules/auth/auth.py

Browse files
Files changed (1) hide show
  1. modules/auth/auth.py +127 -131
modules/auth/auth.py CHANGED
@@ -1,13 +1,14 @@
 
1
  import gradio as gr
2
  import os
3
  from azure.cosmos import CosmosClient, exceptions
 
4
  import bcrypt
5
  import base64
6
- import logging
7
- from datetime import datetime, timezone
8
  from ..database.sql_db import (
9
  get_user,
10
  get_student_user,
 
11
  create_student_user,
12
  update_student_user,
13
  delete_student_user,
@@ -15,16 +16,12 @@ from ..database.sql_db import (
15
  record_logout
16
  )
17
 
18
- logger = logging.getLogger(__name__)
19
 
20
- # Verificar las variables de entorno
21
- COSMOS_ENDPOINT = os.getenv("COSMOS_ENDPOINT")
22
- COSMOS_KEY = os.getenv("COSMOS_KEY")
23
 
24
- if not COSMOS_ENDPOINT or not COSMOS_KEY:
25
- raise ValueError("Las variables de entorno COSMOS_ENDPOINT y COSMOS_KEY no est谩n configuradas.")
26
 
27
- # Inicializar el cliente de Cosmos DB
28
  def clean_and_validate_key(key):
29
  """Limpia y valida la clave de CosmosDB"""
30
  key = key.strip()
@@ -33,97 +30,23 @@ def clean_and_validate_key(key):
33
  try:
34
  base64.b64decode(key)
35
  return key
36
- except Exception:
37
  raise ValueError("La clave proporcionada no es v谩lida")
38
 
39
- COSMOS_KEY = clean_and_validate_key(COSMOS_KEY)
40
- cosmos_client = CosmosClient(COSMOS_ENDPOINT, COSMOS_KEY)
41
-
42
- ########################################
43
- # Funciones de autenticaci贸n
44
- ########################################
45
-
46
- def authenticate_user(username: str, password: str) -> tuple[bool, str | None]:
47
- """
48
- Autentica un usuario utilizando la base de datos.
49
- Args:
50
- username (str): Nombre de usuario.
51
- password (str): Contrase帽a.
52
- Returns:
53
- tuple: (True, role) si la autenticaci贸n es exitosa; (False, None) en caso contrario.
54
- """
55
- try:
56
- user = get_user(username)
57
- if user and verify_password(user["password"], password):
58
- logger.info(f"Usuario autenticado: {username}, Rol: {user['role']}")
59
- return True, user["role"]
60
- logger.warning(f"Credenciales incorrectas para el usuario: {username}")
61
- return False, None
62
- except Exception as e:
63
- logger.error(f"Error autenticando al usuario {username}: {str(e)}")
64
- return False, None
65
-
66
- def register_student(username: str, password: str, additional_info=None) -> bool:
67
- """
68
- Registra un nuevo estudiante en la base de datos.
69
- Args:
70
- username (str): Nombre de usuario.
71
- password (str): Contrase帽a.
72
- additional_info (dict): Informaci贸n adicional del estudiante.
73
- Returns:
74
- bool: True si el registro es exitoso, False en caso contrario.
75
- """
76
- try:
77
- if get_student_user(username):
78
- logger.warning(f"El estudiante {username} ya existe.")
79
- return False
80
 
81
- hashed_password = hash_password(password)
82
- additional_info = additional_info or {}
83
- additional_info["role"] = "Estudiante"
 
84
 
85
- create_student_user(username, hashed_password, additional_info)
86
- logger.info(f"Estudiante registrado: {username}")
87
- return True
88
- except Exception as e:
89
- logger.error(f"Error registrando al estudiante {username}: {str(e)}")
90
- return False
91
 
92
- ########################################
93
- # Funciones para manejo de contrase帽as
94
- ########################################
95
-
96
- def hash_password(password: str) -> str:
97
- """
98
- Hashea una contrase帽a utilizando bcrypt.
99
- Args:
100
- password (str): Contrase帽a en texto plano.
101
- Returns:
102
- str: Contrase帽a hasheada.
103
- """
104
- return bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt()).decode("utf-8")
105
-
106
- def verify_password(stored_password: str, provided_password: str) -> bool:
107
- """
108
- Verifica que una contrase帽a coincida con su hash.
109
- Args:
110
- stored_password (str): Contrase帽a almacenada (hash).
111
- provided_password (str): Contrase帽a proporcionada por el usuario.
112
- Returns:
113
- bool: True si coinciden, False en caso contrario.
114
- """
115
- return bcrypt.checkpw(provided_password.encode("utf-8"), stored_password.encode("utf-8"))
116
-
117
- ########################################
118
- # Interfaz de autenticaci贸n
119
- ########################################
120
 
 
121
  def create_auth_interface():
122
- """
123
- Crea la interfaz de autenticaci贸n utilizando Gradio.
124
- Returns:
125
- gr.Blocks: Interfaz Gradio para el login.
126
- """
127
  with gr.Blocks() as auth_interface:
128
  gr.Markdown("# Login")
129
  username = gr.Textbox(label="Usuario")
@@ -133,52 +56,125 @@ def create_auth_interface():
133
 
134
  def handle_login(user, pwd):
135
  success, role = authenticate_user(user, pwd)
136
- if success:
137
- return f"Bienvenido, {user} ({role})"
138
- return "Credenciales incorrectas."
139
 
140
  login_btn.click(fn=handle_login, inputs=[username, password], outputs=message)
141
  return auth_interface
142
 
143
- ########################################
144
- # P谩gina de usuario
145
- ########################################
146
-
147
- def create_user_page():
148
- """
149
- Crea una p谩gina de usuario para mostrar informaci贸n b谩sica tras el login.
150
- Returns:
151
- gr.Blocks: Interfaz Gradio para la p谩gina del usuario.
152
- """
153
- with gr.Blocks() as user_page:
154
- gr.Markdown("# Bienvenido a la User Page")
155
- gr.Markdown("Esta p谩gina est谩 disponible solo despu茅s de un inicio de sesi贸n exitoso.")
156
-
157
- username = gr.Textbox(label="Usuario", interactive=False)
158
- role = gr.Textbox(label="Rol", interactive=False)
 
 
 
 
 
159
 
160
- def load_user_info():
161
- # Aqu铆 puedes utilizar un sistema de gesti贸n de sesi贸n (Gradio no tiene uno nativo)
162
- return "UsuarioPrueba", "Estudiante"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
 
164
- user_page.load(fn=load_user_info, inputs=[], outputs=[username, role])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
 
166
- gr.Button("Cerrar Sesi贸n").click(
167
- fn=lambda: "Sesi贸n cerrada",
168
- inputs=[],
169
- outputs=[user_page]
170
- )
171
- return user_page
 
 
 
 
 
 
 
 
172
 
173
- ########################################
174
- # Exportar funciones relevantes
175
- ########################################
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
 
177
  __all__ = [
178
- "create_auth_interface",
179
- "create_user_page",
180
- "register_student",
181
- "hash_password",
182
- "verify_password",
183
- "authenticate_user"
 
 
 
184
  ]
 
1
+ #/modules/auth/auth.py
2
  import gradio as gr
3
  import os
4
  from azure.cosmos import CosmosClient, exceptions
5
+ from azure.cosmos.exceptions import CosmosHttpResponseError
6
  import bcrypt
7
  import base64
 
 
8
  from ..database.sql_db import (
9
  get_user,
10
  get_student_user,
11
+ get_admin_user,
12
  create_student_user,
13
  update_student_user,
14
  delete_student_user,
 
16
  record_logout
17
  )
18
 
19
+ import logging
20
 
21
+ from datetime import datetime, timezone
 
 
22
 
23
+ logger = logging.getLogger(__name__)
 
24
 
 
25
  def clean_and_validate_key(key):
26
  """Limpia y valida la clave de CosmosDB"""
27
  key = key.strip()
 
30
  try:
31
  base64.b64decode(key)
32
  return key
33
+ except:
34
  raise ValueError("La clave proporcionada no es v谩lida")
35
 
36
+ # Verificar las variables de entorno
37
+ endpoint = os.getenv("COSMOS_ENDPOINT")
38
+ key = os.getenv("COSMOS_KEY")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
+ if not endpoint or not key:
41
+ raise ValueError("Las variables de entorno COSMOS_ENDPOINT y COSMOS_KEY deben estar configuradas")
42
+
43
+ key = clean_and_validate_key(key)
44
 
 
 
 
 
 
 
45
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
+ ##################################################################
48
  def create_auth_interface():
49
+ """Crea la interfaz de autenticaci贸n."""
 
 
 
 
50
  with gr.Blocks() as auth_interface:
51
  gr.Markdown("# Login")
52
  username = gr.Textbox(label="Usuario")
 
56
 
57
  def handle_login(user, pwd):
58
  success, role = authenticate_user(user, pwd)
59
+ return f"Bienvenido, {user} ({role})" if success else "Credenciales incorrectas."
 
 
60
 
61
  login_btn.click(fn=handle_login, inputs=[username, password], outputs=message)
62
  return auth_interface
63
 
64
+ ######################################################################################
65
+ def authenticate_student(username, password):
66
+ """Autentica un estudiante"""
67
+ success, role = authenticate_user(username, password)
68
+ if success and role == 'Estudiante':
69
+ return True, role
70
+ return False, None
71
+
72
+ def authenticate_admin(username, password):
73
+ """Autentica un administrador"""
74
+ success, role = authenticate_user(username, password)
75
+ if success and role == 'Administrador':
76
+ return True, role
77
+ return False, None
78
+
79
+ def register_student(username, password, additional_info=None):
80
+ """Registra un nuevo estudiante"""
81
+ try:
82
+ if get_student_user(username):
83
+ logger.warning(f"Estudiante ya existe: {username}")
84
+ return False
85
 
86
+ hashed_password = hash_password(password)
87
+
88
+ # Asegurarse que additional_info tenga el rol correcto
89
+ if not additional_info:
90
+ additional_info = {}
91
+ additional_info['role'] = 'Estudiante'
92
+
93
+ success = create_student_user(username, hashed_password, additional_info)
94
+ if success:
95
+ logger.info(f"Nuevo estudiante registrado: {username}")
96
+ return True
97
+
98
+ logger.error(f"Error al crear estudiante: {username}")
99
+ return False
100
+
101
+ except Exception as e:
102
+ logger.error(f"Error al registrar estudiante: {str(e)}")
103
+ return False
104
 
105
+ def update_student_info(username, new_info):
106
+ """Actualiza la informaci贸n de un estudiante"""
107
+ try:
108
+ if 'password' in new_info:
109
+ new_info['password'] = hash_password(new_info['password'])
110
+
111
+ success = update_student_user(username, new_info)
112
+ if success:
113
+ logger.info(f"Informaci贸n actualizada: {username}")
114
+ return True
115
+
116
+ logger.error(f"Error al actualizar: {username}")
117
+ return False
118
+
119
+ except Exception as e:
120
+ logger.error(f"Error en actualizaci贸n: {str(e)}")
121
+ return False
122
 
123
+ def delete_student(username):
124
+ """Elimina un estudiante"""
125
+ try:
126
+ success = delete_student_user(username)
127
+ if success:
128
+ logger.info(f"Estudiante eliminado: {username}")
129
+ return True
130
+
131
+ logger.error(f"Error al eliminar: {username}")
132
+ return False
133
+
134
+ except Exception as e:
135
+ logger.error(f"Error en eliminaci贸n: {str(e)}")
136
+ return False
137
 
138
+ def logout():
139
+ """Cierra la sesi贸n del usuario"""
140
+ try:
141
+ if 'session_id' in st.session_state and 'username' in st.session_state:
142
+ success = record_logout(
143
+ st.session_state.username,
144
+ st.session_state.session_id
145
+ )
146
+ if success:
147
+ logger.info(f"Sesi贸n cerrada: {st.session_state.username}")
148
+ else:
149
+ logger.warning(f"Error al registrar cierre de sesi贸n: {st.session_state.username}")
150
+
151
+ except Exception as e:
152
+ logger.error(f"Error en logout: {str(e)}")
153
+ finally:
154
+ st.session_state.clear()
155
+
156
+ def hash_password(password):
157
+ """Hashea una contrase帽a"""
158
+ return bcrypt.hashpw(
159
+ password.encode('utf-8'),
160
+ bcrypt.gensalt()
161
+ ).decode('utf-8')
162
+
163
+ def verify_password(stored_password, provided_password):
164
+ """Verifica una contrase帽a"""
165
+ return bcrypt.checkpw(
166
+ provided_password.encode('utf-8'),
167
+ stored_password.encode('utf-8')
168
+ )
169
 
170
  __all__ = [
171
+ 'create_auth_interface', # por 'authenticate_user',
172
+ 'authenticate_admin',
173
+ 'authenticate_student',
174
+ 'register_student',
175
+ 'update_student_info',
176
+ 'delete_student',
177
+ 'logout',
178
+ 'hash_password',
179
+ 'verify_password'
180
  ]