VeuReu commited on
Commit
91cf327
·
1 Parent(s): 701967a

Upload 11 files

Browse files
Files changed (3) hide show
  1. app.py +31 -4
  2. database.py +10 -6
  3. scripts/manage_users.py +9 -6
app.py CHANGED
@@ -68,6 +68,34 @@ os.makedirs(DATA_DIR, exist_ok=True)
68
  ensure_dirs(DATA_DIR)
69
  DB_PATH = os.path.join(DATA_DIR, "app.db")
70
  set_db_path(DB_PATH)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  init_schema()
72
 
73
  def create_default_users_if_needed():
@@ -82,8 +110,8 @@ def create_default_users_if_needed():
82
  ]
83
  for username, password, role in users_to_create:
84
  try:
85
- pw_hash = bcrypt.hash(password)
86
- create_user(username, pw_hash, role)
87
  print(f"Usuario '{username}' creado con rol '{role}'.")
88
  except Exception as e:
89
  print(f"Error al crear el usuario {username}: {e}")
@@ -150,8 +178,7 @@ if not st.session_state.user:
150
  row = get_user(username)
151
  hash_to_check = None
152
  if row:
153
- # Comprobar cualquiera de las dos columnas de hash de contraseña por compatibilidad
154
- hash_to_check = row["password_hash"] or row["pw_hash"]
155
 
156
  if row and hash_to_check and verify_password(password, hash_to_check):
157
  st.session_state.user = {"id": row["id"], "username": row["username"], "role": row["role"]}
 
68
  ensure_dirs(DATA_DIR)
69
  DB_PATH = os.path.join(DATA_DIR, "app.db")
70
  set_db_path(DB_PATH)
71
+
72
+ # Comprobación de sanidad: si la BD tiene el esquema viejo, se borra.
73
+ def force_db_recreation_if_needed():
74
+ db_file = Path(DB_PATH)
75
+ if not db_file.exists():
76
+ return # No hay BD, no hay nada que hacer
77
+
78
+ try:
79
+ conn = sqlite3.connect(DB_PATH)
80
+ cursor = conn.cursor()
81
+ # Comprobar si la columna 'pw_hash' existe
82
+ cursor.execute("PRAGMA table_info(users)")
83
+ columns = [row[1] for row in cursor.fetchall()]
84
+ conn.close()
85
+
86
+ if 'pw_hash' in columns:
87
+ print("Detectada estructura de BD obsoleta. Eliminando para forzar la recreación...")
88
+ db_file.unlink()
89
+ st.rerun() # Forzar reinicio de la app
90
+ except Exception as e:
91
+ # La tabla puede no existir, o ser un fichero corrupto. En cualquier caso, lo borramos.
92
+ print(f"Error al comprobar la BD ({e}). Se intentará borrar y recrear.")
93
+ if db_file.exists():
94
+ db_file.unlink()
95
+ st.rerun()
96
+
97
+ force_db_recreation_if_needed()
98
+
99
  init_schema()
100
 
101
  def create_default_users_if_needed():
 
110
  ]
111
  for username, password, role in users_to_create:
112
  try:
113
+ password_hash = bcrypt.hash(password)
114
+ create_user(username, password_hash, role)
115
  print(f"Usuario '{username}' creado con rol '{role}'.")
116
  except Exception as e:
117
  print(f"Error al crear el usuario {username}: {e}")
 
178
  row = get_user(username)
179
  hash_to_check = None
180
  if row:
181
+ hash_to_check = row["password_hash"]
 
182
 
183
  if row and hash_to_check and verify_password(password, hash_to_check):
184
  st.session_state.user = {"id": row["id"], "username": row["username"], "role": row["role"]}
database.py CHANGED
@@ -35,12 +35,16 @@ def init_schema():
35
  CREATE TABLE IF NOT EXISTS users (
36
  id INTEGER PRIMARY KEY AUTOINCREMENT,
37
  username TEXT UNIQUE NOT NULL,
38
- pw_hash TEXT, -- o password_hash, deja las dos si convives con ambos esquemas
39
  password_hash TEXT,
40
  role TEXT NOT NULL,
41
  created_at TEXT NOT NULL
42
  );
43
  """)
 
 
 
 
 
44
  # (opcional: tus otras tablas)
45
 
46
  # >>> NUEVA TABLA PARA FEEDBACK DE AD (no depende de videos)
@@ -108,11 +112,11 @@ def now_str():
108
  return datetime.utcnow().isoformat(timespec="seconds") + "Z"
109
 
110
  # Users
111
- def create_user(username: str, pw_hash: str, role: str):
112
  with get_conn() as conn:
113
  conn.execute(
114
  "INSERT INTO users(username, password_hash, role, created_at) VALUES (?,?,?,?)",
115
- (username, pw_hash, role, now_str()),
116
  )
117
 
118
  def get_user(username: str):
@@ -125,11 +129,11 @@ def get_all_users() -> List[Dict[str, Any]]:
125
  cur = conn.execute("SELECT id, username, role FROM users ORDER BY username")
126
  return cur.fetchall()
127
 
128
- def update_user_password(username: str, pw_hash: str):
129
  with get_conn() as conn:
130
  conn.execute(
131
- "UPDATE users SET pw_hash = ? WHERE username = ?",
132
- (pw_hash, username)
133
  )
134
 
135
  # Videos
 
35
  CREATE TABLE IF NOT EXISTS users (
36
  id INTEGER PRIMARY KEY AUTOINCREMENT,
37
  username TEXT UNIQUE NOT NULL,
 
38
  password_hash TEXT,
39
  role TEXT NOT NULL,
40
  created_at TEXT NOT NULL
41
  );
42
  """)
43
+ # Migración: eliminar la columna antigua si existe
44
+ try:
45
+ c.execute("ALTER TABLE users DROP COLUMN pw_hash;")
46
+ except sqlite3.OperationalError:
47
+ pass # La columna no existía, no hay nada que hacer.
48
  # (opcional: tus otras tablas)
49
 
50
  # >>> NUEVA TABLA PARA FEEDBACK DE AD (no depende de videos)
 
112
  return datetime.utcnow().isoformat(timespec="seconds") + "Z"
113
 
114
  # Users
115
+ def create_user(username: str, password_hash: str, role: str):
116
  with get_conn() as conn:
117
  conn.execute(
118
  "INSERT INTO users(username, password_hash, role, created_at) VALUES (?,?,?,?)",
119
+ (username, password_hash, role, now_str()),
120
  )
121
 
122
  def get_user(username: str):
 
129
  cur = conn.execute("SELECT id, username, role FROM users ORDER BY username")
130
  return cur.fetchall()
131
 
132
+ def update_user_password(username: str, password_hash: str):
133
  with get_conn() as conn:
134
  conn.execute(
135
+ "UPDATE users SET password_hash = ? WHERE username = ?",
136
+ (password_hash, username)
137
  )
138
 
139
  # Videos
scripts/manage_users.py CHANGED
@@ -2,8 +2,11 @@ import argparse
2
  from passlib.hash import bcrypt
3
  from database import set_db_path, init_schema, get_all_users, create_user, get_user, update_user_password
4
 
5
- # Apuntar a la base de datos de origen para que los cambios persistan en el build
6
- DB_PATH = "init_data/veureu.db"
 
 
 
7
 
8
  def hash_password(password: str) -> str:
9
  return bcrypt.hash(password)
@@ -44,16 +47,16 @@ def main():
44
  if get_user(args.username):
45
  print(f"Error: El usuario '{args.username}' ya existe.")
46
  return
47
- pw_hash = hash_password(args.password)
48
- create_user(args.username, pw_hash, args.role)
49
  print(f"Usuario '{args.username}' creado con éxito.")
50
 
51
  elif args.command == "reset-password":
52
  if not get_user(args.username):
53
  print(f"Error: El usuario '{args.username}' no existe.")
54
  return
55
- pw_hash = hash_password(args.new_password)
56
- update_user_password(args.username, pw_hash)
57
  print(f"Contraseña del usuario '{args.username}' actualizada con éxito.")
58
 
59
  if __name__ == "__main__":
 
2
  from passlib.hash import bcrypt
3
  from database import set_db_path, init_schema, get_all_users, create_user, get_user, update_user_password
4
 
5
+ # Apuntar a la base de datos de ejecución en el entorno de HF Spaces
6
+ import os
7
+ # La ruta debe coincidir con la configurada en config.yaml y app.py
8
+ DATA_DIR = os.getenv("DATA_DIR_OVERRIDE", "/tmp/data")
9
+ DB_PATH = os.path.join(DATA_DIR, "app.db")
10
 
11
  def hash_password(password: str) -> str:
12
  return bcrypt.hash(password)
 
47
  if get_user(args.username):
48
  print(f"Error: El usuario '{args.username}' ya existe.")
49
  return
50
+ password_hash = hash_password(args.password)
51
+ create_user(args.username, password_hash, args.role)
52
  print(f"Usuario '{args.username}' creado con éxito.")
53
 
54
  elif args.command == "reset-password":
55
  if not get_user(args.username):
56
  print(f"Error: El usuario '{args.username}' no existe.")
57
  return
58
+ password_hash = hash_password(args.new_password)
59
+ update_user_password(args.username, password_hash)
60
  print(f"Contraseña del usuario '{args.username}' actualizada con éxito.")
61
 
62
  if __name__ == "__main__":