修复物联安全:持久化撤权恢复并统一真实外发门禁

This commit is contained in:
wangzhibiao committed 2026-10-14 10:52:05 +08:00
1 parent 373921447f
commit 0c1d97a6f0
70 files changed
+1817 -1459

No files matched your search

@@ -26,13 +26,16 @@ import com.ruoyi.iot.service.IMqttService;
*/
@RestController
@RequestMapping("/qa/mock")
@ConditionalOnProperty(name = "iot.mqtt.mock", havingValue = "true")
@ConditionalOnProperty(name = {"iot.mqtt.mock", "iot.qa-api-enabled"}, havingValue = "true")
@PreAuthorize("@ss.hasRole('admin') or @ss.hasPermi('iot:command:edit')")
public class QaMockMqttApiController
{
@Autowired
private IMqttService mqttService;
@Autowired
private com.ruoyi.iot.lock.service.ILockCommandService commandService;
/**
* 获取所有拦截到的下行指令
*/
@@ -83,7 +86,14 @@ public class QaMockMqttApiController
YdlinkFrameDTO frame = new YdlinkFrameDTO();
frame.setDevId(groupCode);
frame.setSeq(commandNo);
frame.setOp(op);
com.ruoyi.iot.lock.domain.LockCommand command = commandService.selectCommandList(new com.ruoyi.iot.lock.domain.LockCommand())
.stream().filter(c -> commandNo.equals(c.getCommandNo())).findFirst().orElseThrow();
com.ruoyi.iot.lock.protocol.YdlinkFrameDTO original = com.ruoyi.iot.lock.protocol.YdlinkCodec.fromJson(command.getPayload());
if (original == null) return AjaxResult.error("Command payload is invalid");
groupCode = original.getDevId(); deviceSn = command.getDeviceSn();
op = String.valueOf(original.getParams().get(0));
topic = command.getTopic() + "_report";
frame.setDevId(groupCode); frame.setOp(original.getOp());
frame.setAt(String.valueOf(System.currentTimeMillis() / 1000L));
List<Object> records = new ArrayList<>();
@@ -25,14 +25,15 @@ import io.swagger.v3.oas.annotations.tags.Tag;
* @author ruoyi
*/
@Tag(name = "用户信息管理")
@org.springframework.boot.autoconfigure.condition.ConditionalOnProperty(name = "iot.qa-api-enabled", havingValue = "true")
@org.springframework.security.access.prepost.PreAuthorize("@ss.hasRole('admin')")
@RestController
@RequestMapping("/test/user")
public class TestController extends BaseController
{
private final static Map<Integer, UserEntity> users = new LinkedHashMap<Integer, UserEntity>();
{
users.put(1, new UserEntity(1, "admin", "admin123", "15888888888"));
users.put(2, new UserEntity(2, "ry", "admin123", "15666666666"));
users.put(1, new UserEntity(1, "synthetic-user", "", ""));
}
@Operation(summary = "获取用户列表")
@@ -48,13 +48,13 @@ spring:
webStatFilter:
enabled: true
statViewServlet:
enabled: true
enabled: ${DRUID_CONSOLE_ENABLED:false}
# 设置白名单,不填则允许所有访问
allow:
url-pattern: /druid/*
# 控制台管理用户名和密码
login-username: ruoyi
login-password: 123456
login-username: ${DRUID_CONSOLE_USERNAME:}
login-password: ${DRUID_CONSOLE_PASSWORD:}
filter:
stat:
enabled: true
@@ -66,4 +66,4 @@ spring:
# 若 Druid 无法自动识别 KingbaseES,取消下一行注释显式指定数据库类型
# db-type: kingbase
config:
multi-statement-allow: true
multi-statement-allow: true
@@ -107,7 +107,7 @@ token:
# 令牌自定义标识
header: Authorization
# 令牌密钥
secret: abcdefghijklmnopqrstuvwxyz
secret: ${TOKEN_SECRET:}
# 令牌有效期(默认30分钟)
expireTime: 30
@@ -160,14 +160,19 @@ xss:
# IOT设备接入(Mock 模式,拦截外部真实硬件)
iot:
# 人脸特征提取服务 (Mock 拦截,绝不向外部真实接口发请求)
qa-api-enabled: ${IOT_QA_API_ENABLED:false}
face:
endpoint: mock://face-feature-extract
mock: true
endpoint: ${IOT_FACE_ENDPOINT:}
mock: ${IOT_FACE_MOCK:true}
enabled: ${IOT_FACE_ENABLED:false}
real-http-enabled: ${IOT_FACE_REAL_HTTP_ENABLED:false}
environment-id: ${IOT_ENVIRONMENT_ID:local-mock}
allowed-endpoints: []
timeout: 3000
# 第三方开放接口:关闭时接口返回 404;启用后调用方需带请求头 X-API-Key
openapi:
enabled: true
api-key: qa-fusion-test-api-key
enabled: ${IOT_OPENAPI_ENABLED:false}
api-key: ${IOT_OPENAPI_KEY:}
path-prefix: /openapi/iot
mqtt:
# 彻底禁用真实 MQTT 连接,启用 Mock 替身模式
@@ -180,7 +185,9 @@ iot:
# 历史指令防重放保护(禁止向真实硬件重放系统启动前遗留的历史待发送指令)
replay-protection-enabled: true
# 定时补偿任务开关
retry-task-enabled: true
retry-task-enabled: ${IOT_RETRY_TASK_ENABLED:false}
environment-id: ${IOT_ENVIRONMENT_ID:local-mock}
protocol-verified: false
broker-url: ${IOT_MQTT_BROKER_URL:tcp://127.0.0.1:1883}
# 客户端ID,同一服务器下必须唯一;为空时自动生成
client-id:
@@ -191,7 +198,7 @@ iot:
connection-timeout: 30
keep-alive-interval: 60
# 断线自动重连
automatic-reconnect: true
automatic-reconnect: false
max-reconnect-delay: 30000
# 连接健康检查周期(毫秒),0 表示不做定时重连
health-check-interval: 30000