from __future__ import annotations import tkinter as tk from tkinter import messagebox, simpledialog, filedialog as fd from pathlib import Path from .user_list_view import UserListView from .controls_panel import ControlsPanel from .integrity_tools import IntegrityTools from .crypto_tools import CryptoTools class MainWindow: """ Главное окно менеджера учётных записей. """ def __init__(self, account_manager, password_hasher, audit_logger, crypto_manager, integrity_checker): self.account_manager = account_manager self.password_hasher = password_hasher self.audit_logger = audit_logger self.integrity_tools = IntegrityTools( integrity_checker, audit_logger, account_manager.db_file) self.crypto_tools = CryptoTools(crypto_manager, audit_logger) self.root = tk.Tk() self.root.title("Менеджер учётных записей") self._build_menu() self.users_view = UserListView(self.root) self.users_view.frame.pack() self.controls = ControlsPanel( self.root, on_add=self.add_user, on_update=self.update_user, on_delete=self.delete_user ) self.controls.frame.pack(pady=5) self.refresh_users() def _build_menu(self): menubar = tk.Menu(self.root) file_menu = tk.Menu(menubar, tearoff=0) file_menu.add_command( label="Открыть базу данных...", command=self.open_db) file_menu.add_command(label="Закрыть базу данных", command=self.close_db) menubar.add_cascade(label="Файл", menu=file_menu) tools = tk.Menu(menubar, tearoff=0) tools.add_command(label="Сохранить хэш БД", command=self.integrity_tools.save_db_hash) tools.add_command(label="Проверить целостность БД", command=self.integrity_tools.verify_db_hash) tools.add_separator() tools.add_command(label="Зашифровать файл...", command=self.crypto_tools.encrypt_file) tools.add_command(label="Расшифровать файл...", command=self.crypto_tools.decrypt_file) menubar.add_cascade(label="Инструменты", menu=tools) self.root.config(menu=menubar) # --- File ops --- def open_db(self): path = fd.askopenfilename( title="Открыть базу данных", filetypes=[("JSON", "*.json"), ("DB/TXT", "*.db *.txt"), ("Все файлы", "*.*")], initialdir="data" ) if not path: return self.account_manager.set_db_file(path) self.integrity_tools.set_db_path(path) self.audit_logger.log(f"Открыта база данных: {Path(path).name}") self.refresh_users() # --- Account ops --- def refresh_users(self): self.users_view.set_items(self.account_manager.list_users()) def add_user(self): username = simpledialog.askstring( "Добавить пользователя", "Введите имя пользователя:") if not username: return password = simpledialog.askstring( "Пароль", "Введите пароль:", show="*") if not password: return salt = self.password_hasher.generate_salt() password_hash = self.password_hasher.hash_password(password, salt) self.account_manager.add_user(username, password_hash, salt) self.audit_logger.log(f"Добавлен пользователь: {username}") self.refresh_users() def update_user(self): username = self.users_view.get_selected() if not username: messagebox.showwarning("Изменить", "Выберите пользователя") return password = simpledialog.askstring( "Новый пароль", f"Введите новый пароль для {username}:", show="*") if not password: return salt = self.password_hasher.generate_salt() password_hash = self.password_hasher.hash_password(password, salt) if self.account_manager.update_user(username, password_hash, salt): self.audit_logger.log(f"Обновлён пароль пользователя: {username}") self.refresh_users() def delete_user(self): username = self.users_view.get_selected() if not username: messagebox.showwarning("Удалить", "Выберите пользователя") return if self.account_manager.delete_user(username): self.audit_logger.log(f"Удалён пользователь: {username}") self.refresh_users() def run(self): self.root.mainloop() def close_db(self): self.account_manager.set_db_file(None) self.integrity_tools.set_db_path(None) self.audit_logger.log("Закрыта база данных") self.users_view.set_items([])