diff --git a/config/plugins/commands.yaml b/config/plugins/commands.yaml index fb274fb..9148ba4 100644 --- a/config/plugins/commands.yaml +++ b/config/plugins/commands.yaml @@ -9,6 +9,10 @@ commands: permissions: - framework.scaffold.plugin source: internal + echo: &id001 + description: echo input + permissions: [] + source: plugin.example_plugin help: description: 显示帮助信息 permissions: @@ -19,6 +23,11 @@ commands: permissions: - framework.command.history.read source: internal + install: + description: '从在线索引安装插件: install 或 install --list' + permissions: + - framework.plugin.install + source: internal netdiag: description: 网络服务诊断 permissions: @@ -29,6 +38,10 @@ commands: permissions: - framework.permission.read source: internal + plugin_status: &id002 + description: show status + permissions: [] + source: plugin.example_plugin pm_plugin_status: description: '权限管理: 查看插件权限状态' permissions: @@ -84,6 +97,9 @@ commands: permissions: - framework.command.test source: internal -last_updated: 1742.472300949 -plugin_commands: {} -total_commands: 17 +last_updated: 11552.003166269 +plugin_commands: + example_plugin: + echo: *id001 + plugin_status: *id002 +total_commands: 20 diff --git a/config/services/network_routes.yaml b/config/services/network_routes.yaml index 85887ef..f6affbd 100644 --- a/config/services/network_routes.yaml +++ b/config/services/network_routes.yaml @@ -1,9 +1,17 @@ http_port: 4200 -last_updated: 316707.287225746 +last_updated: 11552.015952154 plugin_routes: example_plugin: - methods: - GET path: /example_plugin/api/example/info require_auth: false + - methods: + - POST + path: /example_plugin/api/plugin/echo + require_auth: true + - methods: + - POST + path: /example_plugin/api/plugin/plugin_status + require_auth: true websocket_port: 4240 diff --git a/services/web_panel/routes/auth.py b/services/web_panel/routes/auth.py index 1cbfafa..cf97d6b 100644 --- a/services/web_panel/routes/auth.py +++ b/services/web_panel/routes/auth.py @@ -24,20 +24,24 @@ def _check_rate_limit(ip: str) -> bool: entry = _LOGIN_FAILS.get(ip) if entry: fail_count, lock_until = entry - if now < lock_until: + if lock_until and now < lock_until: return False # still locked - if now >= lock_until + _LOCK_SECONDS: - _LOGIN_FAILS.pop(ip, None) # expired, reset + if lock_until and now >= lock_until: + _LOGIN_FAILS.pop(ip, None) # lock expired, reset return True def _record_fail(ip: str): now = time.time() - entry = _LOGIN_FAILS.get(ip, [0, 0]) + entry = _LOGIN_FAILS.get(ip) + if entry is None: + entry = [0, None] entry[0] += 1 if entry[0] >= _MAX_FAILS: entry[1] = now + _LOCK_SECONDS logger.warning(f"🔒 IP {ip} 登录锁定 {_LOCK_SECONDS}s ({_MAX_FAILS} 次失败)") + else: + logger.debug(f"IP {ip} 登录失败计数: {entry[0]}/{_MAX_FAILS}") _LOGIN_FAILS[ip] = entry