feat: 添加安全模块 + Dockerfile添加curl支持健康检查
主要更新: - 新增 security/ 安全模块 (风险评估、威胁检测、蜜罐等) - Dockerfile 添加 curl 以支持 Docker 健康检查 - 前端页面更新 (管理后台、用户端) - 数据库迁移和 schema 更新 - 新增 kdocs 上传服务 - 添加安全相关测试用例 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -87,19 +87,32 @@ def run_scheduled_task(skip_weekday_check: bool = False) -> None:
|
||||
cfg = database.get_system_config()
|
||||
enable_screenshot_scheduled = cfg.get("enable_screenshot", 0) == 1
|
||||
|
||||
user_accounts = {}
|
||||
account_ids = []
|
||||
for user in approved_users:
|
||||
user_id = user["id"]
|
||||
accounts = safe_get_user_accounts_snapshot(user_id)
|
||||
if not accounts:
|
||||
load_user_accounts(user_id)
|
||||
accounts = safe_get_user_accounts_snapshot(user_id)
|
||||
if accounts:
|
||||
user_accounts[user_id] = accounts
|
||||
account_ids.extend(list(accounts.keys()))
|
||||
|
||||
account_statuses = database.get_account_status_batch(account_ids)
|
||||
|
||||
for user in approved_users:
|
||||
user_id = user["id"]
|
||||
accounts = user_accounts.get(user_id, {})
|
||||
if not accounts:
|
||||
continue
|
||||
for account_id, account in accounts.items():
|
||||
total_accounts += 1
|
||||
|
||||
if account.is_running:
|
||||
continue
|
||||
|
||||
account_status_info = database.get_account_status(account_id)
|
||||
account_status_info = account_statuses.get(str(account_id))
|
||||
if account_status_info:
|
||||
status = account_status_info["status"] if "status" in account_status_info.keys() else "active"
|
||||
if status == "suspended":
|
||||
@@ -150,6 +163,16 @@ def scheduled_task_worker() -> None:
|
||||
"""定时任务工作线程"""
|
||||
import schedule
|
||||
|
||||
def decay_risk_scores():
|
||||
"""风险分衰减:每天定时执行一次"""
|
||||
try:
|
||||
from security.risk_scorer import RiskScorer
|
||||
|
||||
RiskScorer().decay_scores()
|
||||
logger.info("[定时任务] 风险分衰减已执行")
|
||||
except Exception as e:
|
||||
logger.exception(f"[定时任务] 风险分衰减执行失败: {e}")
|
||||
|
||||
def cleanup_expired_captcha():
|
||||
try:
|
||||
deleted_count = safe_cleanup_expired_captcha()
|
||||
@@ -362,7 +385,12 @@ def scheduled_task_worker() -> None:
|
||||
if schedule_time_cst != str(schedule_time_raw or "").strip():
|
||||
logger.warning(f"[定时任务] 系统定时时间格式无效,已回退到 {schedule_time_cst} (原值: {schedule_time_raw!r})")
|
||||
|
||||
signature = (schedule_enabled, schedule_time_cst)
|
||||
risk_decay_time_raw = os.environ.get("RISK_SCORE_DECAY_TIME_CST", "04:00")
|
||||
risk_decay_time_cst = _normalize_hhmm(risk_decay_time_raw, default="04:00")
|
||||
if risk_decay_time_cst != str(risk_decay_time_raw or "").strip():
|
||||
logger.warning(f"[定时任务] 风险分衰减时间格式无效,已回退到 {risk_decay_time_cst} (原值: {risk_decay_time_raw!r})")
|
||||
|
||||
signature = (schedule_enabled, schedule_time_cst, risk_decay_time_cst)
|
||||
config_changed = schedule_state.get("signature") != signature
|
||||
is_first_run = schedule_state.get("signature") is None
|
||||
if (not force) and (not config_changed):
|
||||
@@ -374,6 +402,8 @@ def scheduled_task_worker() -> None:
|
||||
cleanup_time_cst = "03:00"
|
||||
schedule.every().day.at(cleanup_time_cst).do(cleanup_old_data)
|
||||
|
||||
schedule.every().day.at(risk_decay_time_cst).do(decay_risk_scores)
|
||||
|
||||
schedule.every().hour.do(cleanup_expired_captcha)
|
||||
|
||||
quota_reset_time_cst = "00:00"
|
||||
@@ -381,6 +411,7 @@ def scheduled_task_worker() -> None:
|
||||
|
||||
if is_first_run:
|
||||
logger.info(f"[定时任务] 已设置数据清理任务: 每天 CST {cleanup_time_cst}")
|
||||
logger.info(f"[定时任务] 已设置风险分衰减: 每天 CST {risk_decay_time_cst}")
|
||||
logger.info(f"[定时任务] 已设置验证码清理任务: 每小时执行一次")
|
||||
logger.info(f"[定时任务] 已设置SMTP配额重置: 每天 CST {quota_reset_time_cst}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user