From b9edba7f696b2175cc74f111891d9051ce5e9c31 Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期一, 28 九月 2026 15:21:21 +0800
Subject: [PATCH] 拒绝把全权限账号写进厂商数据源配置

---
 battery-device-neware/src/main/java/com/battery/device/neware/NewareMysqlAdapterFactory.java |   20 +++++++++++++++++++-
 1 files changed, 19 insertions(+), 1 deletions(-)

diff --git a/battery-device-neware/src/main/java/com/battery/device/neware/NewareMysqlAdapterFactory.java b/battery-device-neware/src/main/java/com/battery/device/neware/NewareMysqlAdapterFactory.java
index 34da3c6..8e074a2 100644
--- a/battery-device-neware/src/main/java/com/battery/device/neware/NewareMysqlAdapterFactory.java
+++ b/battery-device-neware/src/main/java/com/battery/device/neware/NewareMysqlAdapterFactory.java
@@ -1,5 +1,7 @@
 package com.battery.device.neware;
 
+import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import com.battery.device.api.DeviceAdapter;
 import com.battery.device.api.DeviceAdapterException;
@@ -21,6 +23,8 @@
     public static final String PASSWORD_ENV_OPTION = "passwordEnv";
     private static final String DEFAULT_DATABASE = "bts63";
     private static final String READ_ONLY_USER = "visitor";
+    /** 现场已知的全权限账号;写进交付配置就等于把误写风险带进现场。 */
+    private static final List<String> FULL_PRIVILEGE_USERS = List.of("btsserver", "root");
 
     @Override
     public String adapterType()
@@ -32,7 +36,7 @@
     public DeviceAdapter create(AdapterInstanceConfig config)
     {
         String database = option(config.sourceConfig(), DATABASE_OPTION, DEFAULT_DATABASE);
-        String user = option(config.sourceConfig(), USER_OPTION, READ_ONLY_USER);
+        String user = readOnlyUser(config.sourceConfig());
         String password = credential(option(config.sourceConfig(), PASSWORD_ENV_OPTION,
                 NewareMysqlAdapter.DEFAULT_PASSWORD_ENV));
         SingleConnectionVendorDataSource source = new SingleConnectionVendorDataSource(
@@ -40,6 +44,20 @@
         return NewareMysqlAdapter.create(config, source);
     }
 
+    /**
+     * 解析厂商库账号:默认取现场取得的服务端只读账号,已知的全权限账号一律拒绝。
+     *
+     * <p>准入只按账号名拦已知的全权限账号(那不是"写一次就回不去"的能力),
+     * 真正的只读边界仍是服务端授权与语句白名单两层;这一层只是不把误配写进交付配置。
+     */
+    static String readOnlyUser(Map<String, String> sourceConfig)
+    {
+        String user = option(sourceConfig, USER_OPTION, READ_ONLY_USER);
+        if (FULL_PRIVILEGE_USERS.contains(user.toLowerCase(Locale.ROOT)))
+            throw new DeviceAdapterException("厂商数据源只允许只读账号,拒绝全权限账号:" + user);
+        return user;
+    }
+
     /** 只读账号口令;启动参数优先于环境变量,便于本机排查而不必改环境。 */
     static String credential(String variableName)
     {

--
Gitblit v1.7.1