/
O.S.Prog
/
InstrumentProtocol
Обзор
Документация
Войти
/
O.S.Prog
/
InstrumentProtocol
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
core/auth_manager.py
200 строк
8 KB
O.S.Prog
Initial commit: InstrumentProtocol v2.0
17 июл 2026, 15:11
17 июл 2026, 15:11
1e845bd
Код
Авторство
О чём код?
import os import json import hashlib import base64 from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad from utils.file_utils import get_config_folder, ensure_folder class AuthManager: def __init__(self): self.config_folder = get_config_folder() ensure_folder(self.config_folder) self.users_file = os.path.join(self.config_folder, "users.json") self.users = {} self.admin_password_hash = None self.load() def load(self): """Загружает пользователей из файла""" if os.path.exists(self.users_file): try: with open(self.users_file, 'r', encoding='utf-8') as f: data = json.load(f) self.admin_password_hash = data.get("admin_password_hash", None) self.users = data.get("users", {}) except: self.users = {} self.admin_password_hash = None def save(self): """Сохраняет пользователей в файл""" data = { "admin_password_hash": self.admin_password_hash, "users": self.users } with open(self.users_file, 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=4) def is_first_run(self): """Проверяет, первый ли это запуск (нет users.json)""" return not os.path.exists(self.users_file) def _get_cipher(self): """Создаёт шифр на основе пароля администратора""" if not self.admin_password_hash: return None key = hashlib.sha256(self.admin_password_hash.encode()).digest() return AES.new(key, AES.MODE_ECB) def _encrypt_password(self, password): """Шифрует пароль (обратимо)""" cipher = self._get_cipher() if not cipher: return password padded = pad(password.encode('utf-8'), 16) encrypted = cipher.encrypt(padded) return base64.b64encode(encrypted).decode('utf-8') def _decrypt_password(self, encrypted): """Расшифровывает пароль""" cipher = self._get_cipher() if not cipher: return encrypted try: encrypted_bytes = base64.b64decode(encrypted.encode('utf-8')) decrypted = cipher.decrypt(encrypted_bytes) return unpad(decrypted, 16).decode('utf-8') except: return None def set_admin_password(self, password): """Устанавливает или меняет пароль администратора с перешифровкой всех данных""" old_key = None # Сохраняем старый ключ шифрования протоколов (если есть) key_file = os.path.join(self.config_folder, "encryption_key.enc") if os.path.exists(key_file): old_key = self.get_encryption_key() # Расшифровываем пароли врачей старым ключом old_passwords = {} for login in self.users: decrypted = self.get_user_password(login) if decrypted: old_passwords[login] = decrypted # Устанавливаем новый пароль администратора self.admin_password_hash = hashlib.sha256(password.encode('utf-8')).hexdigest() # Перешифровываем ключ протоколов новым паролем if old_key: self.set_encryption_key(old_key) else: import os as _os self.set_encryption_key(_os.urandom(32)) # Перешифровываем пароли врачей новым паролем for login, pwd in old_passwords.items(): self.users[login]["password_hash"] = self._encrypt_password(pwd) self.save() def check_admin_password(self, password): """Проверяет пароль администратора""" if not self.admin_password_hash: return False return hashlib.sha256(password.encode('utf-8')).hexdigest() == self.admin_password_hash def add_user(self, login, full_name, password): """Добавляет нового врача""" self.users[login] = { "full_name": full_name, "password_hash": self._encrypt_password(password), "created": "", "active": True } self.save() def remove_user(self, login): """Удаляет врача""" if login in self.users: del self.users[login] self.save() return True return False def check_password(self, login, password): """Проверяет пароль врача""" if login not in self.users: return False user = self.users[login] if not user.get("active", True): return False stored = user["password_hash"] # Старый формат (хеш с солью) — для обратной совместимости if ":" in stored and len(stored.split(":")[0]) == 32: salt, hash_value = stored.split(":") return self._hash(password, salt) == hash_value # Новый формат (шифрованный) decrypted = self._decrypt_password(stored) return decrypted == password def get_full_name(self, login): """Возвращает ФИО врача по логину""" user = self.users.get(login, {}) return user.get("full_name", login) def get_all_users(self): """Возвращает список всех врачей""" return [ {"login": login, "full_name": data["full_name"]} for login, data in self.users.items() ] def get_user_password(self, login): """Возвращает расшифрованный пароль пользователя (только для админа)""" if login not in self.users: return None return self._decrypt_password(self.users[login]["password_hash"]) def _hash(self, password, salt): """Хеширует пароль с солью (старый метод, для совместимости)""" return hashlib.sha256((salt + password).encode('utf-8')).hexdigest() def get_encryption_key(self): """Возвращает ключ шифрования протоколов (если есть)""" import base64 key_b64 = None # Пробуем загрузить из файла key_file = os.path.join(self.config_folder, "encryption_key.enc") if os.path.exists(key_file): try: with open(key_file, 'rb') as f: encrypted_key = f.read() cipher = self._get_cipher() if cipher: decrypted = cipher.decrypt(encrypted_key) key_b64 = unpad(decrypted, 16) except: pass if key_b64: return base64.b64decode(key_b64) return None def set_encryption_key(self, key): """Сохраняет ключ шифрования протоколов (шифрует паролем админа)""" import base64 key_b64 = base64.b64encode(key) cipher = self._get_cipher() if cipher: padded = pad(key_b64, 16) encrypted = cipher.encrypt(padded) key_file = os.path.join(self.config_folder, "encryption_key.enc") with open(key_file, 'wb') as f: f.write(encrypted)