|
|
@@ -0,0 +1,107 @@
|
|
|
+package com.payment.platform.core.log;
|
|
|
+
|
|
|
+import com.fasterxml.jackson.databind.JsonNode;
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
+import org.junit.jupiter.api.Test;
|
|
|
+
|
|
|
+import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
|
+import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
|
+import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 敏感载荷脱敏器(spec §11.2 / Task 5 brief)。
|
|
|
+ *
|
|
|
+ * <p>键名集合大小写不敏感;JSON 递归;非 JSON 按 {@code key=value} 正则;
|
|
|
+ * 先截断 2000 字符再脱敏。
|
|
|
+ */
|
|
|
+class SensitivePayloadRedactorTest {
|
|
|
+
|
|
|
+ private static final ObjectMapper MAPPER = new ObjectMapper();
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void 嵌套JSON_敏感值变星号其它字段原样() throws Exception {
|
|
|
+ String out = SensitivePayloadRedactor.redact(
|
|
|
+ "{\"app_secret\":\"S1\",\"outer\":{\"auth_code\":\"123456\",\"keep\":\"ok\"}}");
|
|
|
+
|
|
|
+ JsonNode node = MAPPER.readTree(out);
|
|
|
+ assertEquals("***", node.get("app_secret").asText());
|
|
|
+ assertEquals("***", node.get("outer").get("auth_code").asText());
|
|
|
+ assertEquals("ok", node.get("outer").get("keep").asText());
|
|
|
+ assertFalse(out.contains("S1"), out);
|
|
|
+ assertFalse(out.contains("123456"), out);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void JSON字符串里再嵌JSON_整个值变星号() throws Exception {
|
|
|
+ String out = SensitivePayloadRedactor.redact(
|
|
|
+ "{\"channel_extra\":\"{\\\"openid\\\":\\\"o1\\\"}\"}");
|
|
|
+
|
|
|
+ JsonNode node = MAPPER.readTree(out);
|
|
|
+ assertEquals("***", node.get("channel_extra").asText());
|
|
|
+ assertFalse(out.contains("o1"), out);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void 非JSON表单_敏感键值变星号其它键保留() {
|
|
|
+ String out = SensitivePayloadRedactor.redact("a=1&app_secret=S1&authCode=123456&b=2");
|
|
|
+
|
|
|
+ assertTrue(out.contains("app_secret=***"), out);
|
|
|
+ assertTrue(out.contains("authCode=***"), out);
|
|
|
+ assertTrue(out.contains("a=1"), out);
|
|
|
+ assertTrue(out.contains("b=2"), out);
|
|
|
+ assertFalse(out.contains("S1"), out);
|
|
|
+ assertFalse(out.contains("123456"), out);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void 键名大小写不敏感() throws Exception {
|
|
|
+ String out = SensitivePayloadRedactor.redact(
|
|
|
+ "{\"AppSecret\":\"S1\",\"AUTH_CODE\":\"123456\",\"apiKey\":\"K1\"}");
|
|
|
+
|
|
|
+ JsonNode node = MAPPER.readTree(out);
|
|
|
+ assertEquals("***", node.get("AppSecret").asText());
|
|
|
+ assertEquals("***", node.get("AUTH_CODE").asText());
|
|
|
+ assertEquals("***", node.get("apiKey").asText());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void 表单形式的大小写不敏感() {
|
|
|
+ String out = SensitivePayloadRedactor.redact("API_KEY=K1&ChannelExtra=E1");
|
|
|
+
|
|
|
+ assertTrue(out.contains("API_KEY=***"), out);
|
|
|
+ assertTrue(out.contains("ChannelExtra=***"), out);
|
|
|
+ assertFalse(out.contains("K1"), out);
|
|
|
+ assertFalse(out.contains("E1"), out);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void 三千字符输入_输出不超过两千() {
|
|
|
+ String out = SensitivePayloadRedactor.redact("x".repeat(3000));
|
|
|
+
|
|
|
+ assertTrue(out.length() <= 2000, "实际长度 " + out.length());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void 非敏感字段原样保留() {
|
|
|
+ assertTrue(SensitivePayloadRedactor.redact("subject=测试").contains("subject=测试"));
|
|
|
+ assertTrue(SensitivePayloadRedactor.redact("{\"subject\":\"测试\"}").contains("测试"));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void 敏感键的整个子树都变星号() throws Exception {
|
|
|
+ String out = SensitivePayloadRedactor.redact(
|
|
|
+ "{\"channelExtra\":{\"auth_code\":\"123456\",\"openid\":\"o1\"},\"keep\":1}");
|
|
|
+
|
|
|
+ JsonNode node = MAPPER.readTree(out);
|
|
|
+ assertEquals("***", node.get("channelExtra").asText());
|
|
|
+ assertEquals(1, node.get("keep").asInt());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void maskApiKey_保留前六位其余星号() {
|
|
|
+ assertEquals("abcdef***", SensitivePayloadRedactor.maskApiKey("abcdef123456"));
|
|
|
+ assertEquals("abcdef***", SensitivePayloadRedactor.maskApiKey("abcdef"));
|
|
|
+ assertEquals("abc***", SensitivePayloadRedactor.maskApiKey("abc"));
|
|
|
+ assertEquals("null", SensitivePayloadRedactor.maskApiKey(null));
|
|
|
+ }
|
|
|
+}
|