"""User storage and auth for Alpine 5G Web GUI. Uses SQLite (db.py).""" import json from pathlib import Path from werkzeug.security import check_password_hash, generate_password_hash from db import ( init_db, user_add as db_user_add, user_delete as db_user_delete, user_get as db_user_get, user_list as db_user_list, user_set_password as db_user_set_password, user_verify as db_user_verify, ) DATA_DIR = Path(__file__).resolve().parent / "data" USERS_FILE = DATA_DIR / "users.json" ROLES = ("admin", "support") def can_access_config(role): return role == "admin" def can_access_firewall(role): return role == "admin" def can_access_routes(role): return role == "admin" def can_manage_users(role): return role == "admin" def can_restart_5g(role): return role in ("admin", "support") def can_view_logs(role): return role in ("admin", "support") def can_view_status(role): return role in ("admin", "support") def _migrate_users_from_json(): """One-time: copy users from users.json into SQLite if DB has no users.""" if not USERS_FILE.exists(): return try: data = json.loads(USERS_FILE.read_text()) users = data.get("users", []) except (json.JSONDecodeError, IOError): return for u in users: username = u.get("username") password_hash = u.get("password_hash") role = u.get("role", "support") if not username or not password_hash: continue existing = db_user_get(username) if not existing: db_user_add(username, password_hash, role) # Optionally rename so we don't migrate again try: USERS_FILE.rename(USERS_FILE.with_suffix(".json.bak")) except OSError: pass def init_default_users(): """Ensure DB exists and has at least default admin/support if empty.""" init_db() if db_user_list(): return _migrate_users_from_json() if db_user_list(): return db_user_add("admin", generate_password_hash("admin"), "admin") db_user_add("support", generate_password_hash("support"), "support") def verify_user(username: str, password: str): def check(ph): return check_password_hash(ph, password) return db_user_verify(username, check) def get_user(username: str): return db_user_get(username) def list_users(): return db_user_list() def set_password(username: str, new_password: str): return db_user_set_password(username, generate_password_hash(new_password)) def add_user(username: str, password: str, role: str): if role not in ROLES: return False, "Invalid role" ok, err = db_user_add(username, generate_password_hash(password), role) return ok, err def delete_user(username: str): if username == "admin": return False, "Cannot delete admin" if not db_user_get(username): return False, "User not found" db_user_delete(username) return True, None