union-ark-web 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/PROJECT_OVERVIEW.md +405 -0
- package/README.md +177 -0
- package/ark-control/pom.xml +142 -0
- package/ark-control/src/local-mock/java/com/epcc/commons/securityproxy/api/SecurityResult.java +14 -0
- package/ark-control/src/local-mock/java/com/epcc/commons/securityproxy/api/SymmetricalSecurityService.java +11 -0
- package/ark-control/src/local-mock/java/com/epcc/dubbo/result/Result.java +29 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/annotation/EnDecryptField.java +16 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/annotation/EnDecryptFieldLong.java +17 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/annotation/EnDecryptFieldWithTag.java +16 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/exception/BaseDataErrorCode.java +26 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/exception/CheckException.java +33 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/exception/ErrorCode.java +9 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/redis/RedisCacheService.java +131 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/util/Constant.java +24 -0
- package/ark-control/src/local-mock/java/com/nucc/channel/ark/common/util/ResultUtil.java +9 -0
- package/ark-control/src/local-mock/java/com/union/control/local/sensitive/LocalMockSensitiveProxy.java +40 -0
- package/ark-control/src/local-mock/java/com/union/control/local/sensitive/LocalRedisCacheService.java +45 -0
- package/ark-control/src/local-mock/java/com/union/control/local/sensitive/LocalSensitiveHostConfiguration.java +27 -0
- package/ark-control/src/local-mock/java/com/union/control/local/sensitive/LocalSensitiveProxyConfiguration.java +16 -0
- package/ark-control/src/main/java/com/union/control/ArkControlApplication.java +17 -0
- package/ark-control/src/main/java/com/union/control/dubbo/ProviderAccessLogFilter.java +45 -0
- package/ark-control/src/main/java/com/union/control/mapper/AgentExecutionMapper.java +35 -0
- package/ark-control/src/main/java/com/union/control/mapper/ConversationMapper.java +44 -0
- package/ark-control/src/main/java/com/union/control/mapper/MemoryStoreMapper.java +41 -0
- package/ark-control/src/main/java/com/union/control/mapper/ScheduledTaskMapper.java +96 -0
- package/ark-control/src/main/java/com/union/control/mapper/SensitiveAddressBookDemo.java +31 -0
- package/ark-control/src/main/java/com/union/control/mapper/SensitiveDataDemoMapper.java +24 -0
- package/ark-control/src/main/java/com/union/control/mapper/interceptor/AESInterceptor.java +265 -0
- package/ark-control/src/main/java/com/union/control/mapper/interceptor/AddressBookHandler.java +105 -0
- package/ark-control/src/main/java/com/union/control/schedule/ScheduledExecutionToken.java +55 -0
- package/ark-control/src/main/java/com/union/control/schedule/ScheduledTaskScheduler.java +206 -0
- package/ark-control/src/main/java/com/union/control/service/impl/AgentExecutionServiceImpl.java +212 -0
- package/ark-control/src/main/java/com/union/control/service/impl/AgentProxyServiceImpl.java +143 -0
- package/ark-control/src/main/java/com/union/control/service/impl/ConversationServiceImpl.java +245 -0
- package/ark-control/src/main/java/com/union/control/service/impl/MemoryStoreServiceImpl.java +252 -0
- package/ark-control/src/main/java/com/union/control/service/impl/RunningAnalysisMockServiceImpl.java +301 -0
- package/ark-control/src/main/java/com/union/control/service/impl/ScheduledTaskServiceImpl.java +576 -0
- package/ark-control/src/main/java/com/union/control/service/impl/SensitiveDataDemoServiceImpl.java +144 -0
- package/ark-control/src/main/java/com/union/control/service/sensitive/RedisRevealTokenStore.java +90 -0
- package/ark-control/src/main/java/com/union/control/service/sensitive/SensitiveRevealProcessor.java +319 -0
- package/ark-control/src/main/java/com/union/control/service/sensitive/SensitiveRevealServiceImpl.java +72 -0
- package/ark-control/src/main/java/com/union/control/utils/AgentSupport.java +103 -0
- package/ark-control/src/main/java/com/union/control/utils/security/SymmetricalSecurityUtils.java +160 -0
- package/ark-control/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter +1 -0
- package/ark-control/src/main/resources/application.properties +4 -0
- package/ark-control/src/main/resources/application.yml +32 -0
- package/ark-control/src/main/resources/dubbo-provider.xml +20 -0
- package/ark-control/src/main/resources/mapper/AgentExecutionMapper.xml +75 -0
- package/ark-control/src/main/resources/mapper/ConversationMapper.xml +110 -0
- package/ark-control/src/main/resources/mapper/MemoryStoreMapper.xml +74 -0
- package/ark-control/src/main/resources/mapper/ScheduledTaskMapper.xml +286 -0
- package/ark-control/src/main/resources/mapper/SensitiveDataDemoMapper.xml +55 -0
- package/ark-control/src/main/resources/schema.sql +146 -0
- package/ark-control/src/test/java/com/union/control/AgentExecutionServiceTest.java +170 -0
- package/ark-control/src/test/java/com/union/control/ArkControlStructureContractTest.java +107 -0
- package/ark-control/src/test/java/com/union/control/ConversationServiceTest.java +89 -0
- package/ark-control/src/test/java/com/union/control/MemoryStoreServiceTest.java +26 -0
- package/ark-control/src/test/java/com/union/control/PydanticAiControlContractTest.java +52 -0
- package/ark-control/src/test/java/com/union/control/TestJson.java +45 -0
- package/ark-control/src/test/java/com/union/control/dubbo/ProviderAccessLogFilterTest.java +53 -0
- package/ark-control/src/test/java/com/union/control/local/sensitive/LocalSensitiveProxyConfigurationTest.java +23 -0
- package/ark-control/src/test/java/com/union/control/mapper/interceptor/AESInterceptorCompatibilityTest.java +505 -0
- package/ark-control/src/test/java/com/union/control/schedule/ScheduledExecutionTokenTest.java +27 -0
- package/ark-control/src/test/java/com/union/control/schedule/ScheduledTaskSchedulerTest.java +51 -0
- package/ark-control/src/test/java/com/union/control/service/AgentProxyServiceTest.java +111 -0
- package/ark-control/src/test/java/com/union/control/service/ScheduledTaskServiceTest.java +483 -0
- package/ark-control/src/test/java/com/union/control/service/impl/SensitiveDataDemoServiceImplTest.java +104 -0
- package/ark-control/src/test/java/com/union/control/service/sensitive/RedisRevealTokenStoreTest.java +65 -0
- package/ark-control/src/test/java/com/union/control/service/sensitive/SensitiveRevealBoundaryTest.java +99 -0
- package/ark-control/src/test/java/com/union/control/service/sensitive/SensitiveRevealProcessorCodecTest.java +111 -0
- package/ark-control/src/test/java/com/union/control/service/sensitive/SensitiveRevealProcessorTest.java +111 -0
- package/ark-control/src/test/java/com/union/control/utils/security/SymmetricalSecurityUtilsCompatibilityTest.java +87 -0
- package/ark-control-facade/pom.xml +16 -0
- package/ark-control-facade/src/main/java/com/union/control/service/AgentExecutionService.java +8 -0
- package/ark-control-facade/src/main/java/com/union/control/service/AgentProxyService.java +7 -0
- package/ark-control-facade/src/main/java/com/union/control/service/AgentResponse.java +22 -0
- package/ark-control-facade/src/main/java/com/union/control/service/ConversationService.java +12 -0
- package/ark-control-facade/src/main/java/com/union/control/service/MemoryStoreService.java +12 -0
- package/ark-control-facade/src/main/java/com/union/control/service/RunningAnalysisMockService.java +10 -0
- package/ark-control-facade/src/main/java/com/union/control/service/ScheduledTaskService.java +40 -0
- package/ark-control-facade/src/main/java/com/union/control/service/SensitiveDataDemoService.java +13 -0
- package/ark-control-facade/src/main/java/com/union/control/service/sensitive/SensitiveRevealService.java +18 -0
- package/ark-web/README.md +80 -0
- package/ark-web/pom.xml +105 -0
- package/ark-web/src/local-mock/java/com/epcc/arkweb/mock/ArkAuthServiceMock.java +105 -0
- package/ark-web/src/local-mock/java/com/epcc/arkweb/mock/LocalKaptchaConfiguration.java +26 -0
- package/ark-web/src/main/java/com/epcc/arkweb/Application.java +13 -0
- package/ark-web/src/main/java/com/epcc/arkweb/config/InterceptorConfig.java +20 -0
- package/ark-web/src/main/java/com/epcc/arkweb/config/Realm.java +64 -0
- package/ark-web/src/main/java/com/epcc/arkweb/config/ShiroConfig.java +129 -0
- package/ark-web/src/main/java/com/epcc/arkweb/filter/LoginFormFilter.java +43 -0
- package/ark-web/src/main/java/com/epcc/arkweb/helper/AuthContextHolder.java +39 -0
- package/ark-web/src/main/java/com/epcc/arkweb/helper/AuthenticatedRequest.java +91 -0
- package/ark-web/src/main/java/com/epcc/arkweb/model/ShiroUser.java +21 -0
- package/ark-web/src/main/java/com/epcc/arkweb/utils/ResultMsg.java +19 -0
- package/ark-web/src/main/java/com/epcc/arkweb/vo/llm/ScheduledTaskCommandVO.java +30 -0
- package/ark-web/src/main/java/com/epcc/arkweb/vo/llm/ScheduledTaskQueryVO.java +20 -0
- package/ark-web/src/main/java/com/epcc/arkweb/web/CommonController.java +25 -0
- package/ark-web/src/main/java/com/epcc/arkweb/web/llm/AgentAuthorizationInterceptor.java +229 -0
- package/ark-web/src/main/java/com/epcc/arkweb/web/llm/AgentController.java +165 -0
- package/ark-web/src/main/java/com/epcc/arkweb/web/llm/AgentPermission.java +13 -0
- package/ark-web/src/main/java/com/epcc/arkweb/web/llm/LlmController.java +209 -0
- package/ark-web/src/main/java/com/epcc/arkweb/web/llm/ScheduledTaskController.java +160 -0
- package/ark-web/src/main/java/com/epcc/arkweb/web/sensitive/reveal/SensitiveCaptchaService.java +146 -0
- package/ark-web/src/main/java/com/epcc/arkweb/web/sensitive/reveal/SensitiveRevealController.java +163 -0
- package/ark-web/src/main/resources/application.properties +1 -0
- package/ark-web/src/main/resources/application.yml +23 -0
- package/ark-web/src/main/resources/dubbo-consumer.xml +19 -0
- package/ark-web/src/production-overlay/java/com/epcc/arkweb/config/CasShiroConfig.java +229 -0
- package/ark-web/src/production-overlay/java/com/epcc/arkweb/config/InterceptorConfig.java +35 -0
- package/ark-web/src/production-overlay/java/com/epcc/arkweb/config/ShiroConfig.java +161 -0
- package/ark-web/src/test/java/com/epcc/arkweb/ArkWebStructureContractTest.java +290 -0
- package/ark-web/src/test/java/com/epcc/arkweb/ShiroTestSupport.java +32 -0
- package/ark-web/src/test/java/com/epcc/arkweb/config/LocalShiroIntegrationTest.java +121 -0
- package/ark-web/src/test/java/com/epcc/arkweb/helper/AuthenticatedRequestTest.java +131 -0
- package/ark-web/src/test/java/com/epcc/arkweb/local/LocalArkAuthServiceMockTest.java +17 -0
- package/ark-web/src/test/java/com/epcc/arkweb/web/llm/AgentAuthorizationInterceptorTest.java +134 -0
- package/ark-web/src/test/java/com/epcc/arkweb/web/llm/AgentControllerAuthorizationTest.java +97 -0
- package/ark-web/src/test/java/com/epcc/arkweb/web/llm/LlmControllerTest.java +113 -0
- package/ark-web/src/test/java/com/epcc/arkweb/web/sensitive/reveal/SensitiveRevealControllerTest.java +273 -0
- package/package.json +18 -0
- package/pom.xml +16 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
package com.union.control.service.impl;
|
|
2
|
+
|
|
3
|
+
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
4
|
+
import com.union.control.mapper.SensitiveAddressBookDemo;
|
|
5
|
+
import com.union.control.mapper.SensitiveDataDemoMapper;
|
|
6
|
+
import com.union.control.service.sensitive.SensitiveRevealService;
|
|
7
|
+
import org.junit.Test;
|
|
8
|
+
import org.mockito.ArgumentCaptor;
|
|
9
|
+
|
|
10
|
+
import java.util.LinkedHashMap;
|
|
11
|
+
import java.util.Map;
|
|
12
|
+
|
|
13
|
+
import static org.junit.Assert.*;
|
|
14
|
+
import static org.mockito.Matchers.*;
|
|
15
|
+
import static org.mockito.Mockito.*;
|
|
16
|
+
|
|
17
|
+
public class SensitiveDataDemoServiceImplTest {
|
|
18
|
+
private static final String TOKEN = "rt_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
|
|
19
|
+
private static final String MASK = "[#138****8000#VIEW:" + TOKEN + "]";
|
|
20
|
+
private final ObjectMapper json = new ObjectMapper();
|
|
21
|
+
private final SensitiveDataDemoMapper mapper = mock(SensitiveDataDemoMapper.class);
|
|
22
|
+
private final SensitiveRevealService reveal = mock(SensitiveRevealService.class);
|
|
23
|
+
private final SensitiveDataDemoServiceImpl service = new SensitiveDataDemoServiceImpl(mapper, json, reveal);
|
|
24
|
+
|
|
25
|
+
@Test
|
|
26
|
+
public void saveResolvesUnopenedFragmentsPreservesNewlinesAndReturnsOnlyQueriedRow() throws Exception {
|
|
27
|
+
Map<String, Object> input = row("phoneNumber", " 新备注\n" + MASK + " ");
|
|
28
|
+
input.put("id", 7);
|
|
29
|
+
Map<String, Object> saved = row("phoneNumber", " 新备注\n" + MASK + " ");
|
|
30
|
+
saved.put("id", 7L);
|
|
31
|
+
when(reveal.reveal(anyString())).thenReturn("13800138000");
|
|
32
|
+
when(mapper.update(anyMap())).thenReturn(1);
|
|
33
|
+
when(mapper.queryById(7L)).thenReturn(saved);
|
|
34
|
+
|
|
35
|
+
assertSame(saved, service.save(json.writeValueAsString(input)));
|
|
36
|
+
|
|
37
|
+
ArgumentCaptor<Map> persisted = ArgumentCaptor.forClass(Map.class);
|
|
38
|
+
verify(mapper).update(persisted.capture());
|
|
39
|
+
assertEquals(" 新备注\n13800138000 ", persisted.getValue().get("phoneNumber"));
|
|
40
|
+
ArgumentCaptor<String> tokenInput = ArgumentCaptor.forClass(String.class);
|
|
41
|
+
verify(reveal).reveal(tokenInput.capture());
|
|
42
|
+
Map parsed = json.readValue(tokenInput.getValue(), Map.class);
|
|
43
|
+
assertEquals("user-1", parsed.get("userId"));
|
|
44
|
+
assertEquals(TOKEN, parsed.get("token"));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@Test
|
|
48
|
+
public void insertReturnsTheGeneratedIdRatherThanTheLatestRow() throws Exception {
|
|
49
|
+
doAnswer(call -> { ((Map) call.getArguments()[0]).put("id", 9L); return 1; })
|
|
50
|
+
.when(mapper).insertSaved(anyMap());
|
|
51
|
+
Map<String, Object> saved = row("phoneNumber", MASK);
|
|
52
|
+
when(mapper.queryById(9L)).thenReturn(saved);
|
|
53
|
+
Map<String, Object> input = row("phoneNumber", "13800138000");
|
|
54
|
+
input.put("id", null);
|
|
55
|
+
assertSame(saved, service.save(json.writeValueAsString(input)));
|
|
56
|
+
verify(mapper, never()).query();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@Test
|
|
60
|
+
public void addressBookEditResolvesOnlySensitiveValuesAndReturnsBypassResult() throws Exception {
|
|
61
|
+
Map<String, Object> input = row("name", "新联系人");
|
|
62
|
+
input.put("id", 3); input.put("role", "003"); input.put("email", "demo@example.com");
|
|
63
|
+
input.put("telephone", "010-12345678"); input.put("mobileNumber", MASK);
|
|
64
|
+
when(reveal.reveal(anyString())).thenReturn("13800138000");
|
|
65
|
+
when(mapper.updateAddressBook(any(SensitiveAddressBookDemo.class))).thenReturn(1);
|
|
66
|
+
SensitiveAddressBookDemo saved = new SensitiveAddressBookDemo();
|
|
67
|
+
saved.setId(3L); saved.setRole("003"); saved.setMobileNumber(MASK);
|
|
68
|
+
when(mapper.queryAddressBookById(3L)).thenReturn(saved);
|
|
69
|
+
|
|
70
|
+
assertEquals(MASK, service.saveAddressBook(json.writeValueAsString(input)).get("mobileNumber"));
|
|
71
|
+
ArgumentCaptor<SensitiveAddressBookDemo> persisted = ArgumentCaptor.forClass(SensitiveAddressBookDemo.class);
|
|
72
|
+
verify(mapper).updateAddressBook(persisted.capture());
|
|
73
|
+
assertEquals("13800138000", persisted.getValue().getMobileNumber());
|
|
74
|
+
assertEquals("新联系人", persisted.getValue().getName());
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@Test
|
|
78
|
+
public void expiredOrDamagedFragmentsNeverPersist() throws Exception {
|
|
79
|
+
when(reveal.reveal(anyString())).thenThrow(new SensitiveRevealService.ExpiredTokenException());
|
|
80
|
+
try { service.save(json.writeValueAsString(row("phoneNumber", MASK))); fail(); }
|
|
81
|
+
catch (SensitiveRevealService.ExpiredTokenException expected) { }
|
|
82
|
+
try { service.save(json.writeValueAsString(row("phoneNumber", "[#138****8000]"))); fail(); }
|
|
83
|
+
catch (IllegalArgumentException expected) { }
|
|
84
|
+
verifyZeroInteractions(mapper);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@Test
|
|
88
|
+
public void rejectsInvalidIdsAndOverlongResolvedContent() throws Exception {
|
|
89
|
+
for (Object id : new Object[]{0, -1, 1.5, "1"}) {
|
|
90
|
+
Map<String, Object> input = row("phoneNumber", "13800138000"); input.put("id", id);
|
|
91
|
+
try { service.save(json.writeValueAsString(input)); fail("accepted invalid id"); }
|
|
92
|
+
catch (IllegalArgumentException expected) { }
|
|
93
|
+
}
|
|
94
|
+
when(reveal.reveal(anyString())).thenReturn(new String(new char[65]).replace('\0', '1'));
|
|
95
|
+
try { service.save(json.writeValueAsString(row("phoneNumber", MASK))); fail(); }
|
|
96
|
+
catch (IllegalArgumentException expected) { }
|
|
97
|
+
verifyZeroInteractions(mapper);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
private Map<String, Object> row(String key, String value) {
|
|
101
|
+
Map<String, Object> result = new LinkedHashMap<>();
|
|
102
|
+
result.put("userId", "user-1"); result.put(key, value); return result;
|
|
103
|
+
}
|
|
104
|
+
}
|
package/ark-control/src/test/java/com/union/control/service/sensitive/RedisRevealTokenStoreTest.java
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
package com.union.control.service.sensitive;
|
|
2
|
+
|
|
3
|
+
import com.nucc.channel.ark.common.redis.RedisCacheService;
|
|
4
|
+
import com.nucc.channel.ark.common.util.ResultUtil;
|
|
5
|
+
import org.junit.Test;
|
|
6
|
+
|
|
7
|
+
import java.util.Arrays;
|
|
8
|
+
import java.util.HashMap;
|
|
9
|
+
import java.util.Map;
|
|
10
|
+
|
|
11
|
+
import static org.junit.Assert.assertEquals;
|
|
12
|
+
import static org.junit.Assert.assertFalse;
|
|
13
|
+
import static org.junit.Assert.assertTrue;
|
|
14
|
+
|
|
15
|
+
public class RedisRevealTokenStoreTest {
|
|
16
|
+
@Test
|
|
17
|
+
public void storesCiphertextThroughProductionRedisContract() {
|
|
18
|
+
RecordingRedis redis = new RecordingRedis();
|
|
19
|
+
RedisRevealTokenStore store = new RedisRevealTokenStore(redis, 300);
|
|
20
|
+
|
|
21
|
+
assertTrue(store.putAll(Arrays.asList(
|
|
22
|
+
new RedisRevealTokenStore.Entry("rt_A", "cipher-a"),
|
|
23
|
+
new RedisRevealTokenStore.Entry("rt_B", "cipher-b"))));
|
|
24
|
+
assertEquals(2, redis.values.size());
|
|
25
|
+
assertEquals(Integer.valueOf(300), redis.ttls.get(RedisRevealTokenStore.key("rt_A")));
|
|
26
|
+
assertEquals("cipher-a", store.get("rt_A"));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@Test
|
|
30
|
+
public void redisFailureDoesNotPublishRevealTokens() {
|
|
31
|
+
RecordingRedis redis = new RecordingRedis();
|
|
32
|
+
redis.failWrites = true;
|
|
33
|
+
|
|
34
|
+
assertFalse(new RedisRevealTokenStore(redis, 300).putAll(Arrays.asList(
|
|
35
|
+
new RedisRevealTokenStore.Entry("rt_A", "cipher-a"))));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@Test(expected = RedisRevealTokenStore.StoreUnavailableException.class)
|
|
39
|
+
public void redisReadFailureIsNotReportedAsAnExpiredToken() {
|
|
40
|
+
RecordingRedis redis = new RecordingRedis();
|
|
41
|
+
redis.failReads = true;
|
|
42
|
+
|
|
43
|
+
new RedisRevealTokenStore(redis, 300).get("rt_A");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
static final class RecordingRedis extends RedisCacheService {
|
|
47
|
+
final Map<String, String> values = new HashMap<>();
|
|
48
|
+
final Map<String, Integer> ttls = new HashMap<>();
|
|
49
|
+
boolean failWrites;
|
|
50
|
+
boolean failReads;
|
|
51
|
+
|
|
52
|
+
@Override
|
|
53
|
+
public String setex(String key, int time, String value) {
|
|
54
|
+
if (failWrites) return ResultUtil.FAIL_RESULT;
|
|
55
|
+
values.put(key, value);
|
|
56
|
+
ttls.put(key, time);
|
|
57
|
+
return ResultUtil.SUCCESS_RESULT;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@Override
|
|
61
|
+
public String get(String key) {
|
|
62
|
+
return failReads ? ResultUtil.FAIL_RESULT : values.get(key);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
package com.union.control.service.sensitive;
|
|
2
|
+
|
|
3
|
+
import com.epcc.commons.securityproxy.api.SecurityResult;
|
|
4
|
+
import com.epcc.commons.securityproxy.api.SymmetricalSecurityService;
|
|
5
|
+
import com.epcc.dubbo.result.Result;
|
|
6
|
+
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
7
|
+
import com.nucc.channel.ark.common.exception.BaseDataErrorCode;
|
|
8
|
+
import com.nucc.channel.ark.common.exception.CheckException;
|
|
9
|
+
import com.nucc.channel.ark.common.redis.RedisCacheService;
|
|
10
|
+
import com.union.control.mapper.interceptor.AESInterceptor;
|
|
11
|
+
import com.union.control.utils.security.SymmetricalSecurityUtils;
|
|
12
|
+
import org.junit.Test;
|
|
13
|
+
import org.springframework.beans.factory.annotation.Autowired;
|
|
14
|
+
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
|
|
15
|
+
|
|
16
|
+
import java.nio.charset.StandardCharsets;
|
|
17
|
+
|
|
18
|
+
import static org.junit.Assert.assertEquals;
|
|
19
|
+
import static org.junit.Assert.assertFalse;
|
|
20
|
+
import static org.junit.Assert.assertNotNull;
|
|
21
|
+
import static org.junit.Assert.assertTrue;
|
|
22
|
+
|
|
23
|
+
public class SensitiveRevealBoundaryTest {
|
|
24
|
+
@Test
|
|
25
|
+
public void springSelectsTheSensitiveRevealProcessorProductionConstructor() {
|
|
26
|
+
java.lang.reflect.Constructor<?>[] constructors =
|
|
27
|
+
new AutowiredAnnotationBeanPostProcessor().determineCandidateConstructors(
|
|
28
|
+
SensitiveRevealProcessor.class, "sensitiveRevealProcessor");
|
|
29
|
+
|
|
30
|
+
assertNotNull(constructors);
|
|
31
|
+
assertEquals(1, constructors.length);
|
|
32
|
+
assertEquals(2, constructors[0].getParameterTypes().length);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@Test
|
|
36
|
+
public void sensitiveInterceptorDependenciesAreRequired() throws Exception {
|
|
37
|
+
assertTrue(AESInterceptor.class.getDeclaredField("processor")
|
|
38
|
+
.getAnnotation(Autowired.class).required());
|
|
39
|
+
assertTrue(AESInterceptor.class.getDeclaredField("addressBook")
|
|
40
|
+
.getAnnotation(Autowired.class).required());
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@Test
|
|
44
|
+
public void redisKeyContainsOnlyTheTokenHash() {
|
|
45
|
+
String token = "rt_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
|
|
46
|
+
String key = RedisRevealTokenStore.key(token);
|
|
47
|
+
assertTrue(key.matches("sensitive:reveal:[0-9a-f]{64}"));
|
|
48
|
+
assertFalse(key.contains(token));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@Test
|
|
52
|
+
public void revealReturnsOnlyTheEncryptedFragment() throws Exception {
|
|
53
|
+
SymmetricalSecurityUtils crypto = new SymmetricalSecurityUtils(new PrefixGateway());
|
|
54
|
+
final String ciphertext = crypto.encryptWithCheck("13800138000");
|
|
55
|
+
RedisRevealTokenStore store = new RedisRevealTokenStore(new RedisCacheService() {
|
|
56
|
+
@Override
|
|
57
|
+
public String get(String key) {
|
|
58
|
+
return ciphertext;
|
|
59
|
+
}
|
|
60
|
+
}, 300);
|
|
61
|
+
String token = "rt_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
|
|
62
|
+
|
|
63
|
+
assertEquals("13800138000", new SensitiveRevealServiceImpl(store, crypto, new ObjectMapper())
|
|
64
|
+
.reveal("{\"userId\":\"ignored-by-first-version\",\"token\":\"" + token + "\"}"));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@Test(expected = SensitiveRevealService.InvalidTokenException.class)
|
|
68
|
+
public void malformedTokenNeverReachesTheStore() {
|
|
69
|
+
RedisRevealTokenStore store = new RedisRevealTokenStore(new RedisCacheService() {
|
|
70
|
+
@Override
|
|
71
|
+
public String get(String key) {
|
|
72
|
+
throw new AssertionError("store must not be called");
|
|
73
|
+
}
|
|
74
|
+
}, 300);
|
|
75
|
+
new SensitiveRevealServiceImpl(store,
|
|
76
|
+
new SymmetricalSecurityUtils(new PrefixGateway()), new ObjectMapper())
|
|
77
|
+
.reveal("{\"userId\":\"user-1\",\"token\":\"bad\"}");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
static class PrefixGateway implements SymmetricalSecurityService {
|
|
81
|
+
@Override
|
|
82
|
+
public Result<SecurityResult> encryptByFixedKey(Algorithm algorithm, byte[] plaintext) {
|
|
83
|
+
byte[] prefix = "enc:".getBytes(StandardCharsets.UTF_8);
|
|
84
|
+
byte[] result = new byte[prefix.length + plaintext.length];
|
|
85
|
+
System.arraycopy(prefix, 0, result, 0, prefix.length);
|
|
86
|
+
System.arraycopy(plaintext, 0, result, prefix.length, plaintext.length);
|
|
87
|
+
return Result.success(new SecurityResult(result));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@Override
|
|
91
|
+
public Result<SecurityResult> decryptByFixedKey(Algorithm algorithm, byte[] ciphertext) {
|
|
92
|
+
if (ciphertext.length < 4) {
|
|
93
|
+
return Result.failure(BaseDataErrorCode.SYSTEM_INNER_ERROR.getCode(), "invalid");
|
|
94
|
+
}
|
|
95
|
+
return Result.success(new SecurityResult(
|
|
96
|
+
java.util.Arrays.copyOfRange(ciphertext, 4, ciphertext.length)));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
package com.union.control.service.sensitive;
|
|
2
|
+
|
|
3
|
+
import com.epcc.commons.securityproxy.api.SecurityResult;
|
|
4
|
+
import com.epcc.commons.securityproxy.api.SymmetricalSecurityService;
|
|
5
|
+
import com.epcc.dubbo.result.Result;
|
|
6
|
+
import com.nucc.channel.ark.common.annotation.EnDecryptField;
|
|
7
|
+
import com.nucc.channel.ark.common.exception.BaseDataErrorCode;
|
|
8
|
+
import com.nucc.channel.ark.common.exception.CheckException;
|
|
9
|
+
import com.union.control.utils.security.SymmetricalSecurityUtils;
|
|
10
|
+
import org.junit.Test;
|
|
11
|
+
|
|
12
|
+
import java.nio.charset.StandardCharsets;
|
|
13
|
+
import java.util.ArrayList;
|
|
14
|
+
import java.util.Base64;
|
|
15
|
+
import java.util.HashMap;
|
|
16
|
+
import java.util.List;
|
|
17
|
+
import java.util.Map;
|
|
18
|
+
|
|
19
|
+
import static org.junit.Assert.assertEquals;
|
|
20
|
+
|
|
21
|
+
public class SensitiveRevealProcessorCodecTest {
|
|
22
|
+
@Test
|
|
23
|
+
public void encryptsEveryElementOfADirectListParameter() throws Exception {
|
|
24
|
+
SensitiveRevealProcessor codec = processor(new PrefixGateway());
|
|
25
|
+
List<Contact> contacts = new ArrayList<>();
|
|
26
|
+
contacts.add(new Contact("13800138000"));
|
|
27
|
+
contacts.add(new Contact("13900139000"));
|
|
28
|
+
|
|
29
|
+
codec.encrypt(contacts);
|
|
30
|
+
|
|
31
|
+
assertEquals(ciphertext("13800138000"), contacts.get(0).mobile);
|
|
32
|
+
assertEquals(ciphertext("13900139000"), contacts.get(1).mobile);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@Test
|
|
36
|
+
public void encryptsSensitiveKeysInAPlainMapParameter() throws Exception {
|
|
37
|
+
SensitiveRevealProcessor codec = processor(new PrefixGateway());
|
|
38
|
+
Map<String, Object> parameter = new HashMap<>();
|
|
39
|
+
parameter.put("email", "demo@example.com");
|
|
40
|
+
parameter.put("role", "001");
|
|
41
|
+
|
|
42
|
+
codec.encrypt(parameter);
|
|
43
|
+
|
|
44
|
+
assertEquals(ciphertext("demo@example.com"), parameter.get("email"));
|
|
45
|
+
assertEquals("001", parameter.get("role"));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@Test
|
|
49
|
+
public void keepsMyBatisScalarAliasesOnTheSameCiphertext() throws Exception {
|
|
50
|
+
SensitiveRevealProcessor codec = processor(new PrefixGateway());
|
|
51
|
+
Map<String, Object> parameter = new HashMap<>();
|
|
52
|
+
String email = new String("demo@example.com");
|
|
53
|
+
parameter.put("email", email);
|
|
54
|
+
parameter.put("param1", email);
|
|
55
|
+
|
|
56
|
+
codec.encrypt(parameter);
|
|
57
|
+
|
|
58
|
+
assertEquals(ciphertext("demo@example.com"), parameter.get("email"));
|
|
59
|
+
assertEquals(parameter.get("email"), parameter.get("param1"));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@Test(expected = CheckException.class)
|
|
63
|
+
public void encryptionFailureIsNotSwallowed() throws Exception {
|
|
64
|
+
SensitiveRevealProcessor codec = processor(new FailingGateway());
|
|
65
|
+
codec.encrypt(new Contact("13800138000"));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private static SensitiveRevealProcessor processor(SymmetricalSecurityService gateway) {
|
|
69
|
+
return new SensitiveRevealProcessor(new SymmetricalSecurityUtils(gateway), null);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private static String ciphertext(String plaintext) {
|
|
73
|
+
return Base64.getEncoder().encodeToString(
|
|
74
|
+
("enc:" + plaintext).getBytes(StandardCharsets.UTF_8));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
static class Contact {
|
|
78
|
+
@EnDecryptField
|
|
79
|
+
String mobile;
|
|
80
|
+
|
|
81
|
+
Contact(String mobile) {
|
|
82
|
+
this.mobile = mobile;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
static class PrefixGateway implements SymmetricalSecurityService {
|
|
87
|
+
@Override
|
|
88
|
+
public Result<SecurityResult> encryptByFixedKey(Algorithm algorithm, byte[] plaintext) {
|
|
89
|
+
return Result.success(new SecurityResult(
|
|
90
|
+
("enc:" + new String(plaintext, StandardCharsets.UTF_8))
|
|
91
|
+
.getBytes(StandardCharsets.UTF_8)));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@Override
|
|
95
|
+
public Result<SecurityResult> decryptByFixedKey(Algorithm algorithm, byte[] ciphertext) {
|
|
96
|
+
return Result.success(new SecurityResult(ciphertext));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
static class FailingGateway implements SymmetricalSecurityService {
|
|
101
|
+
@Override
|
|
102
|
+
public Result<SecurityResult> encryptByFixedKey(Algorithm algorithm, byte[] plaintext) {
|
|
103
|
+
return Result.failure(BaseDataErrorCode.SYSTEM_INNER_ERROR.getCode(), "unavailable");
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
@Override
|
|
107
|
+
public Result<SecurityResult> decryptByFixedKey(Algorithm algorithm, byte[] ciphertext) {
|
|
108
|
+
return Result.failure(BaseDataErrorCode.SYSTEM_INNER_ERROR.getCode(), "unavailable");
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
package com.union.control.service.sensitive;
|
|
2
|
+
|
|
3
|
+
import com.epcc.commons.securityproxy.api.SecurityResult;
|
|
4
|
+
import com.epcc.commons.securityproxy.api.SymmetricalSecurityService;
|
|
5
|
+
import com.epcc.dubbo.result.Result;
|
|
6
|
+
import com.nucc.channel.ark.common.exception.BaseDataErrorCode;
|
|
7
|
+
import com.nucc.channel.ark.common.redis.RedisCacheService;
|
|
8
|
+
import com.nucc.channel.ark.common.util.ResultUtil;
|
|
9
|
+
import com.union.control.utils.security.SymmetricalSecurityUtils;
|
|
10
|
+
import org.junit.Test;
|
|
11
|
+
|
|
12
|
+
import java.nio.charset.StandardCharsets;
|
|
13
|
+
import java.util.ArrayList;
|
|
14
|
+
import java.util.Base64;
|
|
15
|
+
import java.util.HashMap;
|
|
16
|
+
import java.util.List;
|
|
17
|
+
import java.util.Map;
|
|
18
|
+
|
|
19
|
+
import static org.junit.Assert.assertEquals;
|
|
20
|
+
import static org.junit.Assert.assertFalse;
|
|
21
|
+
import static org.junit.Assert.assertTrue;
|
|
22
|
+
|
|
23
|
+
public class SensitiveRevealProcessorTest {
|
|
24
|
+
@Test
|
|
25
|
+
public void masksEachMatchAndWritesOneCiphertextBatch() throws Exception {
|
|
26
|
+
RecordingRedis redis = new RecordingRedis();
|
|
27
|
+
SymmetricalSecurityUtils crypto = new SymmetricalSecurityUtils(new PrefixGateway());
|
|
28
|
+
SensitiveRevealProcessor processor = new SensitiveRevealProcessor(
|
|
29
|
+
crypto, new RedisRevealTokenStore(redis, 300));
|
|
30
|
+
Map<String, Object> row = row(crypto, "手机13800138000,邮箱demo@example.com");
|
|
31
|
+
|
|
32
|
+
processor.process(row);
|
|
33
|
+
|
|
34
|
+
String value = (String) row.get("phoneNumber");
|
|
35
|
+
assertTrue(value, value.matches("手机\\[#138\\*{4}8000#VIEW:rt_[A-Za-z0-9_-]{43}\\],"
|
|
36
|
+
+ "邮箱\\[#d\\*{3}@example\\.com#VIEW:rt_[A-Za-z0-9_-]{43}\\]"));
|
|
37
|
+
assertEquals(2, redis.values.size());
|
|
38
|
+
assertTrue(redis.values.get(0).startsWith("ZW5j"));
|
|
39
|
+
assertFalse(redis.values.get(0).contains("13800138000"));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@Test
|
|
43
|
+
public void storeFailureReturnsMaskedValuesWithoutTokens() throws Exception {
|
|
44
|
+
RecordingRedis redis = new RecordingRedis();
|
|
45
|
+
redis.succeed = false;
|
|
46
|
+
SymmetricalSecurityUtils crypto = new SymmetricalSecurityUtils(new PrefixGateway());
|
|
47
|
+
SensitiveRevealProcessor processor = new SensitiveRevealProcessor(
|
|
48
|
+
crypto, new RedisRevealTokenStore(redis, 300));
|
|
49
|
+
Map<String, Object> row = row(crypto, "手机13800138000");
|
|
50
|
+
|
|
51
|
+
processor.process(row);
|
|
52
|
+
|
|
53
|
+
assertEquals("手机[#138****8000]", row.get("phoneNumber"));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@Test
|
|
57
|
+
public void fragmentEncryptionFailureNeverPublishesAnUnstoredToken() {
|
|
58
|
+
RecordingRedis redis = new RecordingRedis();
|
|
59
|
+
SensitiveRevealProcessor processor = new SensitiveRevealProcessor(
|
|
60
|
+
new SymmetricalSecurityUtils(new FailingEncryptGateway()),
|
|
61
|
+
new RedisRevealTokenStore(redis, 300));
|
|
62
|
+
Map<String, Object> row = new HashMap<>();
|
|
63
|
+
row.put("phoneNumber", Base64.getEncoder().encodeToString(
|
|
64
|
+
"enc:13800138000".getBytes(StandardCharsets.UTF_8)));
|
|
65
|
+
|
|
66
|
+
processor.process(row);
|
|
67
|
+
|
|
68
|
+
assertEquals("[#138****8000]", row.get("phoneNumber"));
|
|
69
|
+
assertTrue(redis.values.isEmpty());
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private static Map<String, Object> row(SymmetricalSecurityUtils crypto, String plaintext)
|
|
73
|
+
throws Exception {
|
|
74
|
+
Map<String, Object> row = new HashMap<>();
|
|
75
|
+
row.put("phoneNumber", crypto.encryptWithCheck(plaintext));
|
|
76
|
+
return row;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
static class RecordingRedis extends RedisCacheService {
|
|
80
|
+
boolean succeed = true;
|
|
81
|
+
final List<String> values = new ArrayList<>();
|
|
82
|
+
|
|
83
|
+
@Override
|
|
84
|
+
public String setex(String key, int time, String value) {
|
|
85
|
+
values.add(value);
|
|
86
|
+
return succeed ? ResultUtil.SUCCESS_RESULT : ResultUtil.FAIL_RESULT;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
static class PrefixGateway implements SymmetricalSecurityService {
|
|
91
|
+
@Override
|
|
92
|
+
public Result<SecurityResult> encryptByFixedKey(Algorithm algorithm, byte[] plaintext) {
|
|
93
|
+
return Result.success(new SecurityResult(
|
|
94
|
+
("enc:" + new String(plaintext, StandardCharsets.UTF_8))
|
|
95
|
+
.getBytes(StandardCharsets.UTF_8)));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
@Override
|
|
99
|
+
public Result<SecurityResult> decryptByFixedKey(Algorithm algorithm, byte[] ciphertext) {
|
|
100
|
+
return Result.success(new SecurityResult(
|
|
101
|
+
java.util.Arrays.copyOfRange(ciphertext, 4, ciphertext.length)));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
static class FailingEncryptGateway extends PrefixGateway {
|
|
106
|
+
@Override
|
|
107
|
+
public Result<SecurityResult> encryptByFixedKey(Algorithm algorithm, byte[] plaintext) {
|
|
108
|
+
return Result.failure(BaseDataErrorCode.SYSTEM_INNER_ERROR.getCode(), "unavailable");
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
package com.union.control.utils.security;
|
|
2
|
+
|
|
3
|
+
import com.epcc.commons.securityproxy.api.SecurityResult;
|
|
4
|
+
import com.epcc.commons.securityproxy.api.SymmetricalSecurityService;
|
|
5
|
+
import com.epcc.dubbo.result.Result;
|
|
6
|
+
import com.nucc.channel.ark.common.exception.CheckException;
|
|
7
|
+
import org.junit.Test;
|
|
8
|
+
|
|
9
|
+
import java.nio.charset.StandardCharsets;
|
|
10
|
+
import java.util.ArrayList;
|
|
11
|
+
import java.util.List;
|
|
12
|
+
|
|
13
|
+
import static org.junit.Assert.assertEquals;
|
|
14
|
+
import static org.junit.Assert.assertTrue;
|
|
15
|
+
|
|
16
|
+
public class SymmetricalSecurityUtilsCompatibilityTest {
|
|
17
|
+
@Test
|
|
18
|
+
public void longValuesUseTheConfiguredChunkSizeAndRoundTrip() throws Exception {
|
|
19
|
+
RecordingProxy proxy = new RecordingProxy();
|
|
20
|
+
SymmetricalSecurityUtils crypto = new SymmetricalSecurityUtils(proxy);
|
|
21
|
+
|
|
22
|
+
String ciphertext = crypto.encryptLongString("abcdefgh", 3);
|
|
23
|
+
|
|
24
|
+
assertEquals(3, proxy.encrypted.size());
|
|
25
|
+
assertEquals("abc", proxy.encrypted.get(0));
|
|
26
|
+
assertEquals("def", proxy.encrypted.get(1));
|
|
27
|
+
assertEquals("gh", proxy.encrypted.get(2));
|
|
28
|
+
assertEquals("abcdefgh", crypto.decryptLongString(ciphertext));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@Test
|
|
32
|
+
public void taggedValuesKeepTheProductionDatabaseMarkerDirection() throws Exception {
|
|
33
|
+
RecordingProxy proxy = new RecordingProxy();
|
|
34
|
+
SymmetricalSecurityUtils crypto = new SymmetricalSecurityUtils(proxy);
|
|
35
|
+
String plaintext = "手机13800138000 邮箱demo@example.com 电话010-12345678";
|
|
36
|
+
|
|
37
|
+
String ciphertext = crypto.encryptWithTag(plaintext);
|
|
38
|
+
|
|
39
|
+
assertTrue(ciphertext.contains("#["));
|
|
40
|
+
assertEquals(3, occurrences(ciphertext, "#["));
|
|
41
|
+
assertEquals(plaintext, crypto.decryptWithTag(ciphertext));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@Test
|
|
45
|
+
public void proxyFailureKeepsTheProductionCheckedErrorContract() {
|
|
46
|
+
SymmetricalSecurityUtils crypto = new SymmetricalSecurityUtils(new RecordingProxy() {
|
|
47
|
+
@Override
|
|
48
|
+
public Result<SecurityResult> encryptByFixedKey(Algorithm algorithm, byte[] plaintext) {
|
|
49
|
+
return Result.failure("REMOTE_ERROR", "unavailable");
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
crypto.encryptWithCheck("13800138000");
|
|
55
|
+
throw new AssertionError("expected CheckException");
|
|
56
|
+
} catch (CheckException error) {
|
|
57
|
+
assertEquals("SYSTEM_INNER_ERROR", error.getCode());
|
|
58
|
+
assertTrue(error.getMessage().contains("REMOTE_ERROR"));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
private static int occurrences(String value, String needle) {
|
|
63
|
+
return (value.length() - value.replace(needle, "").length()) / needle.length();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static class RecordingProxy implements SymmetricalSecurityService {
|
|
67
|
+
final List<String> encrypted = new ArrayList<>();
|
|
68
|
+
|
|
69
|
+
@Override
|
|
70
|
+
public Result<SecurityResult> encryptByFixedKey(Algorithm algorithm, byte[] plaintext) {
|
|
71
|
+
assertEquals(Algorithm.AES256, algorithm);
|
|
72
|
+
encrypted.add(new String(plaintext, StandardCharsets.UTF_8));
|
|
73
|
+
byte[] result = new byte[plaintext.length + 1];
|
|
74
|
+
result[0] = 42;
|
|
75
|
+
System.arraycopy(plaintext, 0, result, 1, plaintext.length);
|
|
76
|
+
return Result.success(new SecurityResult(result));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@Override
|
|
80
|
+
public Result<SecurityResult> decryptByFixedKey(Algorithm algorithm, byte[] ciphertext) {
|
|
81
|
+
assertEquals(Algorithm.AES256, algorithm);
|
|
82
|
+
byte[] result = new byte[ciphertext.length - 1];
|
|
83
|
+
System.arraycopy(ciphertext, 1, result, 0, result.length);
|
|
84
|
+
return Result.success(new SecurityResult(result));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
3
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
4
|
+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
5
|
+
<modelVersion>4.0.0</modelVersion>
|
|
6
|
+
<groupId>com.union</groupId>
|
|
7
|
+
<artifactId>ark-control-facade</artifactId>
|
|
8
|
+
<version>1.0.0</version>
|
|
9
|
+
<packaging>jar</packaging>
|
|
10
|
+
|
|
11
|
+
<properties>
|
|
12
|
+
<maven.compiler.source>1.8</maven.compiler.source>
|
|
13
|
+
<maven.compiler.target>1.8</maven.compiler.target>
|
|
14
|
+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
15
|
+
</properties>
|
|
16
|
+
</project>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
package com.union.control.service;
|
|
2
|
+
|
|
3
|
+
import java.io.Serializable;
|
|
4
|
+
|
|
5
|
+
/** Serializable HTTP result carried by non-stream Agent Dubbo methods. */
|
|
6
|
+
public final class AgentResponse implements Serializable {
|
|
7
|
+
private static final long serialVersionUID = 1L;
|
|
8
|
+
private int status;
|
|
9
|
+
private String body;
|
|
10
|
+
|
|
11
|
+
public AgentResponse() {}
|
|
12
|
+
|
|
13
|
+
public AgentResponse(int status, String body) {
|
|
14
|
+
this.status = status;
|
|
15
|
+
this.body = body;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public int getStatus() { return status; }
|
|
19
|
+
public void setStatus(int status) { this.status = status; }
|
|
20
|
+
public String getBody() { return body; }
|
|
21
|
+
public void setBody(String body) { this.body = body; }
|
|
22
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
package com.union.control.service;
|
|
2
|
+
|
|
3
|
+
import java.util.Map;
|
|
4
|
+
|
|
5
|
+
public interface ConversationService {
|
|
6
|
+
Map<String, Object> userInfo(String input);
|
|
7
|
+
Map<String, Object> conversations(String input);
|
|
8
|
+
Map<String, Object> conversation(String input);
|
|
9
|
+
Map<String, Object> conversationMessages(String input);
|
|
10
|
+
Map<String, Object> rename(String input);
|
|
11
|
+
Map<String, Object> deleteConversation(String input);
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
package com.union.control.service;
|
|
2
|
+
|
|
3
|
+
import java.util.Map;
|
|
4
|
+
|
|
5
|
+
public interface MemoryStoreService {
|
|
6
|
+
Map<String, Object> memoryRead(String input);
|
|
7
|
+
Map<String, Object> memoryList(String input);
|
|
8
|
+
Map<String, Object> memoryOperation(String input);
|
|
9
|
+
Map<String, Object> memoryWrite(String input);
|
|
10
|
+
Map<String, Object> memoryDelete(String input);
|
|
11
|
+
Map<String, Object> memorySearch(String input);
|
|
12
|
+
}
|
package/ark-control-facade/src/main/java/com/union/control/service/RunningAnalysisMockService.java
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
package com.union.control.service;
|
|
2
|
+
|
|
3
|
+
import java.util.Map;
|
|
4
|
+
|
|
5
|
+
public interface RunningAnalysisMockService {
|
|
6
|
+
Map<String, Object> getOrgInfo(String input);
|
|
7
|
+
Map<String, Object> queryBigData(String input);
|
|
8
|
+
Map<String, Object> announceList(String input);
|
|
9
|
+
Map<String, Object> getJiraInfo(String input);
|
|
10
|
+
}
|