限制群级插件配置仅开放群成员变更监控并增加后端白名单校验
This commit is contained in:
@@ -7,6 +7,11 @@ from .auth import login_required
|
||||
|
||||
group_plugin_config_bp = Blueprint("group_plugin_config", __name__, url_prefix="/group_plugin_config")
|
||||
|
||||
# 群级插件配置白名单:
|
||||
# 当前业务阶段仅开放“群成员变更监控”,其余插件统一在后端拦截,
|
||||
# 防止前端被绕过后写入不受控配置。
|
||||
ALLOWED_PLUGIN_NAMES = {"群成员变更监控"}
|
||||
|
||||
|
||||
def _normalize_datetime_text(value):
|
||||
if value is None:
|
||||
@@ -19,6 +24,11 @@ def _normalize_datetime_text(value):
|
||||
return text
|
||||
|
||||
|
||||
def _is_plugin_allowed(plugin_name: str) -> bool:
|
||||
"""检查插件名是否在群级配置白名单内。"""
|
||||
return str(plugin_name or "").strip() in ALLOWED_PLUGIN_NAMES
|
||||
|
||||
|
||||
@group_plugin_config_bp.route("/")
|
||||
@login_required
|
||||
def page_group_plugin_config():
|
||||
@@ -32,7 +42,18 @@ def api_list_group_plugin_config():
|
||||
service = server.group_plugin_config_service
|
||||
group_id = str(request.args.get("group_id", "") or "").strip()
|
||||
plugin_name = str(request.args.get("plugin_name", "") or "").strip()
|
||||
rows = service.list_configs(group_id=group_id, plugin_name=plugin_name)
|
||||
# 列表接口默认仅返回白名单插件,避免管理端仍出现其它插件配置。
|
||||
# 若传入了非白名单插件名,直接返回空列表。
|
||||
if plugin_name and not _is_plugin_allowed(plugin_name):
|
||||
return jsonify({"success": True, "data": []})
|
||||
if not plugin_name:
|
||||
# service.list_configs 当前仅支持单个 plugin_name 过滤参数,
|
||||
# 这里通过遍历白名单并聚合,确保结果严格受控。
|
||||
rows = []
|
||||
for allowed_name in sorted(ALLOWED_PLUGIN_NAMES):
|
||||
rows.extend(service.list_configs(group_id=group_id, plugin_name=allowed_name))
|
||||
else:
|
||||
rows = service.list_configs(group_id=group_id, plugin_name=plugin_name)
|
||||
for row in rows:
|
||||
row["created_at"] = _normalize_datetime_text(row.get("created_at"))
|
||||
row["updated_at"] = _normalize_datetime_text(row.get("updated_at"))
|
||||
@@ -42,9 +63,8 @@ def api_list_group_plugin_config():
|
||||
@group_plugin_config_bp.route("/api/plugins", methods=["GET"])
|
||||
@login_required
|
||||
def api_list_plugins():
|
||||
server = current_app.dashboard_server
|
||||
plugin_names = sorted([str(p.name) for p in server.plugin_manager.plugins.values()])
|
||||
return jsonify({"success": True, "data": plugin_names})
|
||||
# 插件下拉框只暴露白名单,前端无需自行过滤。
|
||||
return jsonify({"success": True, "data": sorted(ALLOWED_PLUGIN_NAMES)})
|
||||
|
||||
|
||||
@group_plugin_config_bp.route("/api/upsert", methods=["POST"])
|
||||
@@ -63,6 +83,8 @@ def api_upsert_group_plugin_config():
|
||||
|
||||
if not group_id or not plugin_name:
|
||||
return jsonify({"success": False, "message": "group_id 或 plugin_name 不能为空"}), 400
|
||||
if not _is_plugin_allowed(plugin_name):
|
||||
return jsonify({"success": False, "message": f"当前仅允许配置:{','.join(sorted(ALLOWED_PLUGIN_NAMES))}"}), 400
|
||||
|
||||
if isinstance(config_data, str):
|
||||
try:
|
||||
@@ -96,6 +118,8 @@ def api_delete_group_plugin_config():
|
||||
config_key = str(payload.get("config_key") or "default").strip() or "default"
|
||||
if not group_id or not plugin_name:
|
||||
return jsonify({"success": False, "message": "group_id 或 plugin_name 不能为空"}), 400
|
||||
if not _is_plugin_allowed(plugin_name):
|
||||
return jsonify({"success": False, "message": f"当前仅允许配置:{','.join(sorted(ALLOWED_PLUGIN_NAMES))}"}), 400
|
||||
|
||||
ok = service.delete_config(group_id=group_id, plugin_name=plugin_name, config_key=config_key)
|
||||
if not ok:
|
||||
|
||||
Reference in New Issue
Block a user