#!/usr/bin/env python3 """ CLI utility to safely reset a user password directly in the database. Usage: python3 scripts/reset_password.py python3 scripts/reset_password.py """ import sys from pathlib import Path # Add project root to sys.path BASE_DIR = Path(__file__).resolve().parent.parent sys.path.insert(0, str(BASE_DIR)) from app.database import init_db, get_db from app.auth import hash_password, verify_password, _login_failures def reset_password(username: str, new_password: str): if not new_password or len(new_password) < 6: print("❌ Ошибка: Пароль должен содержать минимум 6 символов.") sys.exit(1) init_db() clean_user = username.strip() pwd_hash, salt = hash_password(new_password) with get_db() as conn: row = conn.execute( "SELECT id, username FROM users WHERE username = ? COLLATE NOCASE", (clean_user,) ).fetchone() if not row: # If user does not exist, create it cursor = conn.execute( "INSERT INTO users (username, password_hash, salt) VALUES (?, ?, ?)", (clean_user, pwd_hash, salt) ) print(f"✅ Создан новый пользователь '{clean_user}' (ID: {cursor.lastrowid}).") else: conn.execute( "UPDATE users SET password_hash = ?, salt = ? WHERE id = ?", (pwd_hash, salt, row["id"]) ) print(f"✅ Пароль для пользователя '{row['username']}' (ID: {row['id']}) успешно обновлен.") # Clear login failures rate limit _login_failures.clear() # Verification check check = conn.execute( "SELECT password_hash, salt FROM users WHERE username = ? COLLATE NOCASE", (clean_user,) ).fetchone() if check and verify_password(new_password, check["password_hash"], check["salt"]): print("🔒 Проверка хэша PBKDF2-HMAC-SHA256: УСПЕШНО.") else: print("⚠️ Предупреждение: Не удалось верифицировать хэш пароля.") if __name__ == "__main__": args = sys.argv[1:] if len(args) == 1: # Default to user kopri reset_password("kopri", args[0]) elif len(args) == 2: reset_password(args[0], args[1]) else: print("Использование:") print(" python3 scripts/reset_password.py <новый_пароль>") print(" python3 scripts/reset_password.py <имя_пользователя> <новый_пароль>") sys.exit(1)