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,107 @@
|
|
|
1
|
+
package com.union.control;
|
|
2
|
+
|
|
3
|
+
import org.junit.Test;
|
|
4
|
+
|
|
5
|
+
import java.nio.charset.StandardCharsets;
|
|
6
|
+
import java.nio.file.Files;
|
|
7
|
+
import java.nio.file.Path;
|
|
8
|
+
import java.nio.file.Paths;
|
|
9
|
+
import java.util.Arrays;
|
|
10
|
+
import java.util.List;
|
|
11
|
+
import java.util.stream.Collectors;
|
|
12
|
+
|
|
13
|
+
import static org.assertj.core.api.Assertions.assertThat;
|
|
14
|
+
|
|
15
|
+
public class ArkControlStructureContractTest {
|
|
16
|
+
|
|
17
|
+
private static final Path JAVA_ROOT = Paths.get("src/main/java");
|
|
18
|
+
|
|
19
|
+
@Test
|
|
20
|
+
public void applicationStartsAHeadlessDubboProvider() throws Exception {
|
|
21
|
+
String application = source("com/union/control/ArkControlApplication.java");
|
|
22
|
+
String config = resource("application.yml");
|
|
23
|
+
|
|
24
|
+
assertThat(application)
|
|
25
|
+
.contains("class ArkControlApplication")
|
|
26
|
+
.contains("@MapperScan(\"com.union.control.mapper\")")
|
|
27
|
+
.contains("@EnableScheduling")
|
|
28
|
+
.contains("@ImportResource(\"classpath:dubbo-provider.xml\")");
|
|
29
|
+
assertThat(config).contains("web-environment: false");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@Test
|
|
33
|
+
public void providerPublishesEveryFacadeService() throws Exception {
|
|
34
|
+
String dubbo = resource("dubbo-provider.xml");
|
|
35
|
+
assertThat(dubbo).contains("<dubbo:provider filter=\"providerAccessLog\"");
|
|
36
|
+
for (String service : Arrays.asList(
|
|
37
|
+
"AgentExecutionService",
|
|
38
|
+
"AgentProxyService",
|
|
39
|
+
"ConversationService",
|
|
40
|
+
"MemoryStoreService",
|
|
41
|
+
"RunningAnalysisMockService",
|
|
42
|
+
"ScheduledTaskService",
|
|
43
|
+
"SensitiveDataDemoService")) {
|
|
44
|
+
assertThat(dubbo).contains(
|
|
45
|
+
"interface=\"com.union.control.service." + service + "\"");
|
|
46
|
+
}
|
|
47
|
+
assertThat(dubbo).contains(
|
|
48
|
+
"interface=\"com.union.control.service.sensitive.SensitiveRevealService\"");
|
|
49
|
+
|
|
50
|
+
assertThat(resource("META-INF/dubbo/com.alibaba.dubbo.rpc.Filter"))
|
|
51
|
+
.contains("providerAccessLog=com.union.control.dubbo.ProviderAccessLogFilter");
|
|
52
|
+
assertThat(source("com/union/control/dubbo/ProviderAccessLogFilter.java"))
|
|
53
|
+
.contains("Dubbo provider request started")
|
|
54
|
+
.contains("Dubbo provider request completed")
|
|
55
|
+
.doesNotContain("getArguments()");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@Test
|
|
59
|
+
public void providerDoesNotExposeTheWebOnlyStream() throws Exception {
|
|
60
|
+
String dubbo = resource("dubbo-provider.xml");
|
|
61
|
+
String facade = new String(Files.readAllBytes(Paths.get(
|
|
62
|
+
"../ark-control-facade/src/main/java/com/union/control/service/AgentProxyService.java")),
|
|
63
|
+
StandardCharsets.UTF_8);
|
|
64
|
+
|
|
65
|
+
assertThat(dubbo)
|
|
66
|
+
.doesNotContain("name=\"stream\"")
|
|
67
|
+
.doesNotContain("callback=\"true\"");
|
|
68
|
+
assertThat(facade).doesNotContain("stream(").doesNotContain("AgentStreamCallback");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@Test
|
|
72
|
+
public void providerContainsNoWebControllerOrShiroBoundary() throws Exception {
|
|
73
|
+
List<Path> javaFiles = Files.walk(JAVA_ROOT)
|
|
74
|
+
.filter(Files::isRegularFile)
|
|
75
|
+
.collect(Collectors.toList());
|
|
76
|
+
String source = javaFiles.stream()
|
|
77
|
+
.map(path -> {
|
|
78
|
+
try {
|
|
79
|
+
return new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
|
|
80
|
+
} catch (Exception error) {
|
|
81
|
+
throw new IllegalStateException(error);
|
|
82
|
+
}
|
|
83
|
+
})
|
|
84
|
+
.collect(Collectors.joining("\n"));
|
|
85
|
+
|
|
86
|
+
assertThat(javaFiles.stream()
|
|
87
|
+
.map(path -> path.getFileName().toString())
|
|
88
|
+
.filter(name -> name.endsWith("Controller.java"))
|
|
89
|
+
.collect(Collectors.toList())).isEmpty();
|
|
90
|
+
assertThat(source)
|
|
91
|
+
.doesNotContain("org.apache.shiro")
|
|
92
|
+
.doesNotContain("HttpServletRequest")
|
|
93
|
+
.doesNotContain("HttpServletResponse");
|
|
94
|
+
assertThat(JAVA_ROOT.resolve("com/union/control/schedule/ScheduledTaskScheduler.java")).exists();
|
|
95
|
+
assertThat(JAVA_ROOT.resolve("com/union/control/schedule/ScheduledExecutionToken.java")).exists();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
private static String source(String relative) throws Exception {
|
|
99
|
+
return new String(Files.readAllBytes(JAVA_ROOT.resolve(relative)), StandardCharsets.UTF_8);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private static String resource(String relative) throws Exception {
|
|
103
|
+
return new String(Files.readAllBytes(Paths.get("src/main/resources").resolve(relative)),
|
|
104
|
+
StandardCharsets.UTF_8);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
package com.union.control;
|
|
2
|
+
|
|
3
|
+
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
4
|
+
import com.union.control.mapper.AgentExecutionMapper;
|
|
5
|
+
import com.union.control.mapper.ConversationMapper;
|
|
6
|
+
import com.union.control.mapper.ScheduledTaskMapper;
|
|
7
|
+
import com.union.control.service.impl.ConversationServiceImpl;
|
|
8
|
+
import org.junit.Test;
|
|
9
|
+
|
|
10
|
+
import java.nio.charset.StandardCharsets;
|
|
11
|
+
import java.nio.file.Files;
|
|
12
|
+
import java.nio.file.Paths;
|
|
13
|
+
import java.util.Collections;
|
|
14
|
+
|
|
15
|
+
import static org.junit.Assert.assertFalse;
|
|
16
|
+
import static org.junit.Assert.assertTrue;
|
|
17
|
+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
|
18
|
+
import static org.mockito.Mockito.mock;
|
|
19
|
+
import static org.mockito.Mockito.verify;
|
|
20
|
+
import static org.mockito.Mockito.when;
|
|
21
|
+
|
|
22
|
+
public class ConversationServiceTest {
|
|
23
|
+
@Test
|
|
24
|
+
public void parsesAuthenticatedUserFromJsonBeforeCallingMapper() {
|
|
25
|
+
ConversationMapper conversations = mock(ConversationMapper.class);
|
|
26
|
+
AgentExecutionMapper executions = mock(AgentExecutionMapper.class);
|
|
27
|
+
ScheduledTaskMapper scheduledTasks = mock(ScheduledTaskMapper.class);
|
|
28
|
+
ConversationServiceImpl service = new ConversationServiceImpl(
|
|
29
|
+
conversations, executions, scheduledTasks, new ObjectMapper());
|
|
30
|
+
when(conversations.findConversations(TestJson.USER_ID, 20))
|
|
31
|
+
.thenReturn(Collections.emptyList());
|
|
32
|
+
|
|
33
|
+
service.conversations(TestJson.request("limit", 20));
|
|
34
|
+
|
|
35
|
+
verify(conversations).findConversations(TestJson.USER_ID, 20);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@Test
|
|
39
|
+
public void conversationDetailsLoadsExecutionsOnce() {
|
|
40
|
+
ConversationMapper conversations = mock(ConversationMapper.class);
|
|
41
|
+
AgentExecutionMapper executions = mock(AgentExecutionMapper.class);
|
|
42
|
+
when(conversations.findConversation(TestJson.USER_ID, "thread-1"))
|
|
43
|
+
.thenReturn(new java.util.LinkedHashMap<>());
|
|
44
|
+
when(executions.findExecutions(TestJson.USER_ID, "thread-1"))
|
|
45
|
+
.thenReturn(Collections.emptyList());
|
|
46
|
+
new ConversationServiceImpl(conversations, executions,
|
|
47
|
+
mock(ScheduledTaskMapper.class), new ObjectMapper())
|
|
48
|
+
.conversation(TestJson.request("conversationId", "thread-1"));
|
|
49
|
+
verify(executions).findExecutions(TestJson.USER_ID, "thread-1");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@Test
|
|
53
|
+
public void deletingConversationAlsoDeletesItsClaimedScheduledRun() {
|
|
54
|
+
ConversationMapper conversations = mock(ConversationMapper.class);
|
|
55
|
+
AgentExecutionMapper executions = mock(AgentExecutionMapper.class);
|
|
56
|
+
ScheduledTaskMapper scheduledTasks = mock(ScheduledTaskMapper.class);
|
|
57
|
+
ConversationServiceImpl service = new ConversationServiceImpl(
|
|
58
|
+
conversations, executions, scheduledTasks, new ObjectMapper());
|
|
59
|
+
when(conversations.softDeleteConversation("scheduled-7", TestJson.USER_ID))
|
|
60
|
+
.thenReturn(1);
|
|
61
|
+
|
|
62
|
+
service.deleteConversation(TestJson.request("conversationId", "scheduled-7"));
|
|
63
|
+
|
|
64
|
+
verify(scheduledTasks).softDeleteByConversation("scheduled-7", TestJson.USER_ID);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@Test
|
|
68
|
+
public void conversationMessagesRejectMissingOwnership() {
|
|
69
|
+
ConversationMapper conversations = mock(ConversationMapper.class);
|
|
70
|
+
ConversationServiceImpl service = new ConversationServiceImpl(
|
|
71
|
+
conversations, mock(AgentExecutionMapper.class),
|
|
72
|
+
mock(ScheduledTaskMapper.class), new ObjectMapper());
|
|
73
|
+
when(conversations.requireOwned("foreign-thread", TestJson.USER_ID, false))
|
|
74
|
+
.thenReturn(null);
|
|
75
|
+
|
|
76
|
+
assertThatThrownBy(() -> service.conversationMessages(
|
|
77
|
+
TestJson.request("conversationId", "foreign-thread")))
|
|
78
|
+
.isInstanceOf(java.util.NoSuchElementException.class);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@Test
|
|
82
|
+
public void claimedScheduledRunCleanupIsALogicalDelete() throws Exception {
|
|
83
|
+
String mapper = new String(Files.readAllBytes(Paths.get(
|
|
84
|
+
"src/main/resources/mapper/ScheduledTaskMapper.xml")), StandardCharsets.UTF_8);
|
|
85
|
+
|
|
86
|
+
assertTrue(mapper.contains("SET r.delete_flag=0"));
|
|
87
|
+
assertFalse(mapper.contains("DELETE FROM agent_scheduled_task_run"));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
package com.union.control;
|
|
2
|
+
|
|
3
|
+
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
4
|
+
import com.union.control.mapper.MemoryStoreMapper;
|
|
5
|
+
import com.union.control.service.impl.MemoryStoreServiceImpl;
|
|
6
|
+
import org.junit.Test;
|
|
7
|
+
|
|
8
|
+
import java.util.Collections;
|
|
9
|
+
|
|
10
|
+
import static org.mockito.Mockito.mock;
|
|
11
|
+
import static org.mockito.Mockito.verify;
|
|
12
|
+
import static org.mockito.Mockito.when;
|
|
13
|
+
|
|
14
|
+
public class MemoryStoreServiceTest {
|
|
15
|
+
@Test
|
|
16
|
+
public void parsesAuthenticatedUserFromJsonBeforeCallingMapper() {
|
|
17
|
+
MemoryStoreMapper mapper = mock(MemoryStoreMapper.class);
|
|
18
|
+
MemoryStoreServiceImpl service = new MemoryStoreServiceImpl(mapper, new ObjectMapper());
|
|
19
|
+
String path = TestJson.USER_ID + "/personal/notes.md";
|
|
20
|
+
when(mapper.readMemory(TestJson.USER_ID, path)).thenReturn(Collections.emptyList());
|
|
21
|
+
|
|
22
|
+
service.memoryRead(TestJson.request("path", path, "maxChars", 100));
|
|
23
|
+
|
|
24
|
+
verify(mapper).readMemory(TestJson.USER_ID, path);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
package com.union.control;
|
|
2
|
+
|
|
3
|
+
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
4
|
+
import com.union.control.service.impl.RunningAnalysisMockServiceImpl;
|
|
5
|
+
import org.junit.Test;
|
|
6
|
+
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
|
|
7
|
+
|
|
8
|
+
import java.nio.charset.StandardCharsets;
|
|
9
|
+
import java.nio.file.Files;
|
|
10
|
+
import java.nio.file.Path;
|
|
11
|
+
import java.nio.file.Paths;
|
|
12
|
+
|
|
13
|
+
import static org.assertj.core.api.Assertions.assertThat;
|
|
14
|
+
|
|
15
|
+
public class PydanticAiControlContractTest {
|
|
16
|
+
@Test
|
|
17
|
+
public void springSelectsTheRunningAnalysisProductionConstructor() {
|
|
18
|
+
java.lang.reflect.Constructor<?>[] constructors = new AutowiredAnnotationBeanPostProcessor()
|
|
19
|
+
.determineCandidateConstructors(RunningAnalysisMockServiceImpl.class,
|
|
20
|
+
"runningAnalysisMockService");
|
|
21
|
+
|
|
22
|
+
assertThat(constructors).hasSize(1);
|
|
23
|
+
assertThat(constructors[0].getParameterTypes()).containsExactly(ObjectMapper.class);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@Test
|
|
27
|
+
public void sharedRequestUtilitiesStayOutsideTheServicePackage() {
|
|
28
|
+
Path root = Paths.get("src/main/java/com/union/control");
|
|
29
|
+
|
|
30
|
+
assertThat(root.resolve("utils/AgentSupport.java")).exists();
|
|
31
|
+
assertThat(root.resolve("service/AgentSupport.java")).doesNotExist();
|
|
32
|
+
assertThat(root.resolve("service/ServiceExceptions.java")).doesNotExist();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@Test
|
|
36
|
+
public void serviceModuleHasNoAuthenticationRuntime() throws Exception {
|
|
37
|
+
Path root = Paths.get("src/main/java");
|
|
38
|
+
StringBuilder sources = new StringBuilder();
|
|
39
|
+
Files.walk(root).filter(path -> path.toString().endsWith(".java")).forEach(path -> {
|
|
40
|
+
try {
|
|
41
|
+
sources.append(new String(Files.readAllBytes(path), StandardCharsets.UTF_8));
|
|
42
|
+
} catch (Exception error) {
|
|
43
|
+
throw new RuntimeException(error);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
assertThat(sources.toString())
|
|
47
|
+
.doesNotContain("org.apache.shiro")
|
|
48
|
+
.doesNotContain("AuthContextHolder")
|
|
49
|
+
.doesNotContain("currentUserId()")
|
|
50
|
+
.doesNotContain("@RequiresPermissions");
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
package com.union.control;
|
|
2
|
+
|
|
3
|
+
import com.fasterxml.jackson.core.type.TypeReference;
|
|
4
|
+
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
5
|
+
|
|
6
|
+
import java.util.LinkedHashMap;
|
|
7
|
+
import java.util.Map;
|
|
8
|
+
|
|
9
|
+
public final class TestJson {
|
|
10
|
+
public static final String USER_ID = "local-user";
|
|
11
|
+
public static final String ORG_CODE = "local-org";
|
|
12
|
+
public static final String ROLE_ID = "local-role";
|
|
13
|
+
private static final ObjectMapper JSON = new ObjectMapper();
|
|
14
|
+
|
|
15
|
+
private TestJson() {}
|
|
16
|
+
|
|
17
|
+
public static String request(String raw) {
|
|
18
|
+
try {
|
|
19
|
+
Map<String, Object> parsed = JSON.readValue(
|
|
20
|
+
raw, new TypeReference<Map<String, Object>>() {});
|
|
21
|
+
return request(parsed);
|
|
22
|
+
} catch (Exception error) {
|
|
23
|
+
throw new AssertionError(error);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
public static String request(Map<String, Object> values) {
|
|
28
|
+
Map<String, Object> input = new LinkedHashMap<>(values);
|
|
29
|
+
input.put("userId", USER_ID);
|
|
30
|
+
input.put("orgCode", ORG_CODE);
|
|
31
|
+
input.put("roleId", ROLE_ID);
|
|
32
|
+
try {
|
|
33
|
+
return JSON.writeValueAsString(input);
|
|
34
|
+
} catch (Exception error) {
|
|
35
|
+
throw new AssertionError(error);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public static String request(Object... entries) {
|
|
40
|
+
Map<String, Object> input = new LinkedHashMap<>();
|
|
41
|
+
for (int index = 0; index < entries.length; index += 2)
|
|
42
|
+
input.put(String.valueOf(entries[index]), entries[index + 1]);
|
|
43
|
+
return request(input);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
package com.union.control.dubbo;
|
|
2
|
+
|
|
3
|
+
import ch.qos.logback.classic.Logger;
|
|
4
|
+
import ch.qos.logback.classic.spi.ILoggingEvent;
|
|
5
|
+
import ch.qos.logback.core.read.ListAppender;
|
|
6
|
+
import com.alibaba.dubbo.rpc.Invocation;
|
|
7
|
+
import com.alibaba.dubbo.rpc.Invoker;
|
|
8
|
+
import com.alibaba.dubbo.rpc.Result;
|
|
9
|
+
import com.union.control.service.ConversationService;
|
|
10
|
+
import org.junit.Test;
|
|
11
|
+
import org.slf4j.LoggerFactory;
|
|
12
|
+
|
|
13
|
+
import java.util.List;
|
|
14
|
+
import java.util.stream.Collectors;
|
|
15
|
+
|
|
16
|
+
import static org.assertj.core.api.Assertions.assertThat;
|
|
17
|
+
import static org.mockito.Mockito.mock;
|
|
18
|
+
import static org.mockito.Mockito.never;
|
|
19
|
+
import static org.mockito.Mockito.verify;
|
|
20
|
+
import static org.mockito.Mockito.when;
|
|
21
|
+
|
|
22
|
+
public class ProviderAccessLogFilterTest {
|
|
23
|
+
|
|
24
|
+
@SuppressWarnings("unchecked")
|
|
25
|
+
@Test
|
|
26
|
+
public void logsOnlyTheRpcBoundaryAndDelegatesTheCall() {
|
|
27
|
+
Invoker<ConversationService> invoker = mock(Invoker.class);
|
|
28
|
+
Invocation invocation = mock(Invocation.class);
|
|
29
|
+
Result result = mock(Result.class);
|
|
30
|
+
when(invoker.getInterface()).thenReturn(ConversationService.class);
|
|
31
|
+
when(invocation.getMethodName()).thenReturn("conversations");
|
|
32
|
+
when(invoker.invoke(invocation)).thenReturn(result);
|
|
33
|
+
|
|
34
|
+
Logger logger = (Logger) LoggerFactory.getLogger(ProviderAccessLogFilter.class);
|
|
35
|
+
ListAppender<ILoggingEvent> appender = new ListAppender<>();
|
|
36
|
+
appender.start();
|
|
37
|
+
logger.addAppender(appender);
|
|
38
|
+
try {
|
|
39
|
+
assertThat(new ProviderAccessLogFilter().invoke(invoker, invocation)).isSameAs(result);
|
|
40
|
+
} finally {
|
|
41
|
+
logger.detachAppender(appender);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
List<String> messages = appender.list.stream()
|
|
45
|
+
.map(ILoggingEvent::getFormattedMessage)
|
|
46
|
+
.collect(Collectors.toList());
|
|
47
|
+
assertThat(messages.toString())
|
|
48
|
+
.contains("request started: service=ConversationService, method=conversations")
|
|
49
|
+
.contains("request completed: service=ConversationService, method=conversations");
|
|
50
|
+
verify(invoker).invoke(invocation);
|
|
51
|
+
verify(invocation, never()).getArguments();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
package com.union.control.local.sensitive;
|
|
2
|
+
|
|
3
|
+
import com.epcc.commons.securityproxy.api.SymmetricalSecurityService;
|
|
4
|
+
import org.junit.Test;
|
|
5
|
+
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
|
6
|
+
|
|
7
|
+
import static org.assertj.core.api.Assertions.assertThat;
|
|
8
|
+
|
|
9
|
+
public class LocalSensitiveProxyConfigurationTest {
|
|
10
|
+
|
|
11
|
+
@Test
|
|
12
|
+
public void defaultProfileProvidesTheLocalSensitiveProxy() {
|
|
13
|
+
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
|
14
|
+
context.register(LocalSensitiveProxyConfiguration.class);
|
|
15
|
+
context.refresh();
|
|
16
|
+
try {
|
|
17
|
+
assertThat(context.getBean("sensitiveProxy"))
|
|
18
|
+
.isInstanceOf(SymmetricalSecurityService.class);
|
|
19
|
+
} finally {
|
|
20
|
+
context.close();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|