P1: 功能修复

- v2 三处 self.format_file_size -> format_file_size(3 个端点不再必崩)
- requirements 加 bcrypt、移除未使用的 aiohttp
- verify_user 改用 bcrypt.checkpw(DB basic 登录恢复);SHA256 回退改自描述 PBKDF2,去掉明文接受
- config.py token 模式只在缺失时生成(不再每次 update 失效)
- docker/npm/go/apt/yum 镜像补 cache_enabled/cache_ttl 初始化(不再必 500)
- docker 镜像兼容 upstream_url 配置键
- 定时同步链路: 回调委托 sync_starter 并注入 _sync_manager;cron 逗号列表修复;星期偏移修复
- v2 同步方法与 v1 签名兼容;MirrorSyncManager 补 get_source_status/stop_all_tasks_for_source
This commit is contained in:
HYC Fixer
2026-08-30 12:22:27 +08:00
parent 2a899c411e
commit 084164296d
13 changed files with 2089 additions and 2018 deletions
+28 -20
View File
@@ -1220,8 +1220,8 @@ class DatabaseManager:
return True
return False
def verify_user(self, username: str, password_hash: str) -> dict:
"""验证用户登录"""
def verify_user(self, username: str, password: str) -> dict:
"""验证用户登录(password 为明文密码,用 bcrypt 校验)"""
with self.session() as session:
user = session.query(UserRecord).filter_by(username=username).first()
@@ -1236,8 +1236,8 @@ class DatabaseManager:
if not user.enabled:
return {'valid': False, 'reason': '账号已被禁用'}
# 验证密码
if user.password_hash == password_hash:
# 验证密码(bcrypt.checkpw,恒定时间比较)
if self.verify_password(password, user.password_hash):
# 登录成功
user.last_login = time.time()
user.login_count = (user.login_count or 0) + 1
@@ -1291,16 +1291,22 @@ class DatabaseManager:
print(f"[数据库] 已创建默认用户: {username}")
def hash_password(self, password: str) -> str:
"""使用 bcrypt 加密密码"""
"""使用 bcrypt 加密密码(回退: 自描述格式 PBKDF2-HMAC-SHA256)"""
try:
import bcrypt
salt = bcrypt.gensalt(rounds=12)
return bcrypt.hashpw(password.encode('utf-8'), salt).decode('utf-8')
except ImportError:
# 如果 bcrypt 不可用,回退到 SHA256
# 如果 bcrypt 不可用,回退到 PBKDF2-HMAC-SHA256
# 格式: $pbkdf2-sha256$<iterations>$<salt_b64>$<hash_b64>
import hashlib
salt = hashlib.sha256(str(time.time()).encode()).hexdigest()[:16]
return hashlib.sha256((password + salt).encode()).hexdigest()
import os as _os
import base64
iterations = 100_000
salt = _os.urandom(16)
dk = hashlib.pbkdf2_hmac('sha256', password.encode('utf-8'), salt, iterations)
return (f"$pbkdf2-sha256${iterations}${base64.b64encode(salt).decode()}"
f"${base64.b64encode(dk).decode()}")
def verify_password(self, password: str, password_hash: str) -> bool:
"""验证密码是否正确"""
@@ -1308,19 +1314,21 @@ class DatabaseManager:
import bcrypt
return bcrypt.checkpw(password.encode('utf-8'), password_hash.encode('utf-8'))
except ImportError:
# 如果 bcrypt 不可用,回退到 SHA256 验证
# 回退: 只接受自描述 PBKDF2 格式,绝不接受明文
import hashlib
# 尝试直接比较(可能是旧格式)
if password_hash == password:
return True
# 尝试带 salt 验证
for salt_len in range(1, 17):
salt = password_hash[:salt_len] if len(password_hash) > salt_len else ""
if len(salt) >= 4:
test_hash = hashlib.sha256((password + salt).encode()).hexdigest()
if test_hash == password_hash:
return True
return False
import base64
import hmac
if not password_hash.startswith('$pbkdf2-sha256$'):
return False
try:
_, algo, iters_s, salt_b64, hash_b64 = password_hash.split('$')
iterations = int(iters_s)
salt = base64.b64decode(salt_b64)
expected = base64.b64decode(hash_b64)
dk = hashlib.pbkdf2_hmac('sha256', password.encode('utf-8'), salt, iterations)
return hmac.compare_digest(dk, expected)
except Exception:
return False
def get_user_by_token(self, token: str) -> dict:
"""通过 token 获取用户信息"""