| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- #!/usr/bin/env python3
- """
- 车牌识别系统 - 用户密码重置/创建脚本
- fix24 v29 (2026-07-05)
- 用法:
- cd /opt/openAI/project/003.PlateRecAPP
- python3 reset_passwords.py
- 功能:
- - 使用 data/auth.db 认证数据库
- - 创建或更新两个用户账号
- - 普通用户 zhonjin (role=0)
- - 超级管理员 admin (role=2)
- - 同时修复 config.ini 中的 auth db_path 指向正确路径
- """
- import sqlite3
- import sys
- import os
- import configparser
- try:
- import bcrypt
- except ImportError:
- print("正在安装 bcrypt 库...")
- os.system(f"{sys.executable} -m pip install bcrypt -q")
- import bcrypt
- # ==================== 配置 ====================
- # 候选数据库路径(按优先级排列)
- DB_CANDIDATES = [
- "data/auth.db", # fix24-v29: 唯一正确的认证数据库路径
- ]
- CONFIG_FILE = "config.ini"
- USERS = [
- {
- "username": "zhonjin",
- "password": "zhonjin",
- "role": 0, # 0=普通用户
- "display": "普通用户"
- },
- {
- "username": "admin",
- "password": "zhonjin188A",
- "role": 2, # 2=超级管理员
- "display": "超级管理员"
- },
- ]
- # Bcrypt cost factor (与 config.ini 中 bcrypt_cost 一致)
- BCRYPT_COST = 12
- # ==================== 工具函数 ====================
- def hash_password(password: str) -> str:
- """使用 bcrypt 生成密码哈希"""
- salt = bcrypt.gensalt(rounds=BCRYPT_COST)
- return bcrypt.hashpw(password.encode('utf-8'), salt).decode('utf-8')
- def find_auth_db() -> str:
- """自动检测正确的认证数据库"""
- for db_path in DB_CANDIDATES:
- if os.path.exists(db_path):
- try:
- conn = sqlite3.connect(db_path)
- cursor = conn.cursor()
- cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='users'")
- if cursor.fetchone():
- conn.close()
- return db_path
- conn.close()
- except Exception:
- continue
- # 都不存在,返回第一个候选(让程序创建)
- return DB_CANDIDATES[0]
- def fix_config_ini(correct_db_path: str):
- """修复 config.ini 中的 auth db_path"""
- if not os.path.exists(CONFIG_FILE):
- print(f"⚠️ 配置文件不存在: {CONFIG_FILE},跳过配置修复")
- return
- with open(CONFIG_FILE, 'r') as f:
- content = f.read()
- # 检查 [auth] 段中的 db_path
- lines = content.split('\n')
- new_lines = []
- in_auth_section = False
- db_path_found = False
- for line in lines:
- stripped = line.strip()
- if stripped.lower() == '[auth]':
- in_auth_section = True
- new_lines.append(line)
- continue
- if in_auth_section and stripped.startswith('['):
- in_auth_section = False
- if in_auth_section and stripped.lower().startswith('db_path'):
- db_path_found = True
- new_lines.append(f'db_path={correct_db_path}')
- print(f"🔧 config.ini: db_path 已更新为 {correct_db_path}")
- else:
- new_lines.append(line)
- if not db_path_found:
- # 如果没找到 db_path,在 [auth] 段的 enabled 后面添加
- final_lines = []
- for line in new_lines:
- final_lines.append(line)
- if line.strip().lower().startswith('enabled') and in_auth_section:
- # 这里有个问题:in_auth_section 可能已经被重置了
- pass
- # 简单处理:直接在文件末尾的 [auth] 段添加
- print(f"⚠️ config.ini [auth] 段未找到 db_path,请手动添加: db_path={correct_db_path}")
- else:
- with open(CONFIG_FILE, 'w') as f:
- f.write('\n'.join(new_lines))
- # ==================== 主逻辑 ====================
- def main():
- # 自动检测正确的数据库
- db_path = find_auth_db()
- print(f"📂 认证数据库: {os.path.abspath(db_path)}")
- print(f"🔐 Bcrypt cost: {BCRYPT_COST}")
- print()
- # 确保 data/ 目录存在(如果需要创建新数据库)
- db_dir = os.path.dirname(db_path)
- if db_dir and not os.path.exists(db_dir):
- os.makedirs(db_dir, exist_ok=True)
- conn = sqlite3.connect(db_path)
- cursor = conn.cursor()
- # 确保 users 表存在
- cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='users'")
- if not cursor.fetchone():
- print("📋 创建 users 表...")
- cursor.execute("""
- CREATE TABLE users (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- username TEXT UNIQUE NOT NULL,
- password_hash TEXT NOT NULL,
- role INTEGER DEFAULT 0,
- enabled INTEGER DEFAULT 1,
- failed_attempts INTEGER DEFAULT 0,
- locked_until INTEGER DEFAULT 0,
- created_at TEXT DEFAULT CURRENT_TIMESTAMP,
- updated_at TEXT DEFAULT CURRENT_TIMESTAMP
- )
- """)
- conn.commit()
- for user in USERS:
- username = user["username"]
- password = user["password"]
- role = user["role"]
- display = user["display"]
- # 生成密码哈希
- pw_hash = hash_password(password)
- # 检查用户是否已存在
- cursor.execute("SELECT id, role FROM users WHERE username = ?", (username,))
- existing = cursor.fetchone()
- if existing:
- # 更新密码和角色
- cursor.execute(
- "UPDATE users SET password_hash = ?, role = ?, enabled = 1, "
- "failed_attempts = 0, locked_until = 0, updated_at = CURRENT_TIMESTAMP "
- "WHERE username = ?",
- (pw_hash, role, username)
- )
- print(f"✅ [{display}] {username} — 密码已更新 (role={role})")
- else:
- # 创建新用户
- cursor.execute(
- "INSERT INTO users (username, password_hash, role, enabled, "
- "failed_attempts, locked_until, created_at, updated_at) "
- "VALUES (?, ?, ?, 1, 0, 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)",
- (username, pw_hash, role)
- )
- print(f"✅ [{display}] {username} — 用户已创建 (role={role})")
- conn.commit()
- conn.close()
- # 修复 config.ini
- print()
- fix_config_ini(db_path)
- print()
- print("=" * 50)
- print("🎉 密码重置完成!")
- print()
- print("账号信息:")
- print(f" 普通用户: zhonjin / zhonjin")
- print(f" 超级管理员: admin / zhonjin188A")
- print()
- print("📌 认证数据库: " + os.path.abspath(db_path))
- print()
- print("⚠️ 请确认 config.ini [auth] 段:")
- print(f" db_path={db_path}")
- print("=" * 50)
- if __name__ == "__main__":
- main()
|