'''用户认证登录模块''' import json import os import datetime from pathlib import Path from typing import Tuple, Optional class SimpleAuth: """用户认证管理器""" def __init__(self, config_path: str = None): """ 初始化认证管理器 Args: config_path: 用户配置文件路径 """ self.config_path = config_path self.users = {} # 初始化时加载用户数据 if config_path: self.load_users() def load_users(self) -> bool: """加载用户数据""" try: if not self.config_path: print("未设置配置文件路径") return False # 如果文件不存在,创建空文件 if not os.path.exists(self.config_path): print(f"配置文件不存在,创建空文件: {self.config_path}") return self.create_empty_file() # 读取文件内容 with open(self.config_path, 'r', encoding='utf-8') as f: content = f.read().strip() if not content: # 空文件 self.users = {} return True # 解析JSON self.users = json.loads(content) print(f"已加载 {len(self.users)} 个用户") return True except json.JSONDecodeError: print("配置文件格式错误,重置为空文件") return self.create_empty_file() except Exception as e: print(f"加载用户数据失败: {e}") return False def create_empty_file(self) -> bool: """创建空的配置文件""" try: if not self.config_path: return False os.makedirs(os.path.dirname(self.config_path), exist_ok=True) self.users = {} with open(self.config_path, 'w', encoding='utf-8') as f: json.dump({}, f, indent=2, ensure_ascii=False) print(f"已创建空白配置文件: {self.config_path}") return True except Exception as e: print(f"创建配置文件失败: {e}") return False def save_users(self) -> bool: """保存用户数据""" try: if not self.config_path: return False os.makedirs(os.path.dirname(self.config_path), exist_ok=True) with open(self.config_path, 'w', encoding='utf-8') as f: json.dump(self.users, f, indent=2, ensure_ascii=False) return True except Exception as e: print(f"保存用户数据失败: {e}") return False def authenticate(self, username: str, password: str) -> Tuple[bool, str]: """ 验证用户凭据 重要:如果用户不存在,则创建用户(首次登录即注册) """ if not username or not password: return False, "用户名和密码不能为空" # 加载用户数据 if not self.load_users(): return False, "加载用户数据失败" # 检查用户名是否存在(作为字典键) if username not in self.users: # 首次登录,自动创建用户 print(f"用户 '{username}' 不存在,首次登录将自动创建用户") return self.create_first_user(username, password) # 检查密码是否正确 user_info = self.users[username] if user_info.get("password") != password: return False, "密码错误" # 更新最后登录时间 user_info["last_login"] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") self.save_users() return True, "登录成功" def create_first_user(self, username: str, password: str) -> Tuple[bool, str]: """创建第一个用户(首次登录)""" try: current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") # 创建用户信息 self.users[username] = { "username": username, "password": password, "secondary_password": "", # 二级密码初始为空,首次登录后设置 "created_at": current_time, "last_login": current_time, "is_first_user": True } # 保存用户数据 if self.save_users(): print(f"已创建用户 '{username}' 并登录") return True, f"首次登录成功,已创建用户 '{username}'" else: return False, "创建用户失败" except Exception as e: print(f"创建用户失败: {e}") return False, f"创建用户失败: {str(e)}" def set_secondary_password(self, username: str, secondary_password: str) -> Tuple[bool, str]: """设置二级密码""" try: if not self.load_users(): return False, "加载用户数据失败" if username not in self.users: return False, "用户不存在" if not secondary_password: return False, "二级密码不能为空" # 更新二级密码 self.users[username]["secondary_password"] = secondary_password self.users[username]["secondary_password_updated_at"] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") if self.save_users(): return True, "二级密码设置成功" else: return False, "保存二级密码失败" except Exception as e: return False, f"设置二级密码失败: {str(e)}" def verify_secondary_password(self, username: str, secondary_password: str) -> Tuple[bool, str]: """验证二级密码""" try: if not self.load_users(): return False, "加载用户数据失败" if username not in self.users: return False, "用户不存在" user_info = self.users[username] # 检查用户是否设置了二级密码 if not user_info.get("secondary_password"): return False, "未设置二级密码,请先设置" # 验证二级密码 if user_info.get("secondary_password") != secondary_password: return False, "二级密码错误" return True, "二级密码验证成功" except Exception as e: return False, f"验证二级密码失败: {str(e)}" def get_secondary_password_status(self, username: str) -> Tuple[bool, str]: """获取二级密码设置状态""" try: if not self.load_users(): return False, "加载用户数据失败" if username not in self.users: return False, "用户不存在" user_info = self.users[username] if user_info.get("secondary_password"): return True, f"已设置二级密码(更新于: {user_info.get('secondary_password_updated_at', '未知时间')})" else: return False, "未设置二级密码" except Exception as e: return False, f"获取二级密码状态失败: {str(e)}" def get_default_config_path(self) -> str: """获取默认配置文件路径""" return str(Path.home() / ".config_editor" / "users.json") @staticmethod def validate_config_path(config_path: str) -> bool: """验证配置文件路径是否有效""" try: # 检查路径是否包含有效的目录 dir_path = os.path.dirname(config_path) if not dir_path: return False # 检查是否是绝对路径 if not os.path.isabs(config_path): return False # 检查文件扩展名(可选) if not config_path.endswith(('.json', '.txt', '.dat')): return False return True except Exception: return False