Skip to content

Commit eb9bc4f

Browse files
committed
[backend] feat(multitenancy): adding builtin connectors for new tenants (#3505)
1 parent 83210e9 commit eb9bc4f

10 files changed

Lines changed: 130 additions & 105 deletions

File tree

openaev-api/src/main/java/io/openaev/collectors/expectations_expiration_manager/ExpectationsExpirationManagerJob.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import io.openaev.collectors.expectations_expiration_manager.service.ExpectationsExpirationManagerService;
55
import io.openaev.integration.BuiltinTenantRegistrable;
66
import io.openaev.rest.collector.service.CollectorService;
7+
import io.openaev.rest.exception.ElementNotFoundException;
78
import lombok.extern.slf4j.Slf4j;
89
import org.springframework.beans.factory.annotation.Autowired;
910
import org.springframework.stereotype.Service;
@@ -41,14 +42,18 @@ public ExpectationsExpirationManagerJob(
4142

4243
@Override
4344
public void registerForTenant() throws Exception {
44-
collectorService.register(
45-
config.getId(),
46-
FAKE_DETECTOR_COLLECTOR_TYPE,
47-
FAKE_DETECTOR_COLLECTOR_NAME,
48-
false,
49-
0,
50-
null,
51-
getClass().getResourceAsStream("/img/icon-fake-detector.png"));
45+
try {
46+
collectorService.collector(config.getId());
47+
} catch (ElementNotFoundException e) {
48+
collectorService.register(
49+
config.getId(),
50+
FAKE_DETECTOR_COLLECTOR_TYPE,
51+
FAKE_DETECTOR_COLLECTOR_NAME,
52+
false,
53+
0,
54+
null,
55+
getClass().getResourceAsStream("/img/icon-fake-detector.png"));
56+
}
5257
}
5358

5459
@Override

openaev-api/src/main/java/io/openaev/collectors/expectations_vulnerability_manager/ExpectationsVulnerabilityManagerCollector.java

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import io.openaev.integration.BuiltinTenantRegistrable;
44
import io.openaev.rest.collector.service.CollectorService;
5-
import jakarta.annotation.PostConstruct;
5+
import io.openaev.rest.exception.ElementNotFoundException;
66
import lombok.RequiredArgsConstructor;
77
import lombok.extern.slf4j.Slf4j;
88
import org.springframework.stereotype.Service;
@@ -20,24 +20,19 @@ public class ExpectationsVulnerabilityManagerCollector implements BuiltinTenantR
2020
public static final String EXPECTATIONS_VULNERABILITY_COLLECTOR_NAME =
2121
"Expectations Vulnerability Manager";
2222

23-
@PostConstruct
24-
public void init() {
25-
try {
26-
registerForTenant();
27-
} catch (Exception e) {
28-
log.error("Error creating expectations vulnerability manager ", e);
29-
}
30-
}
31-
3223
@Override
3324
public void registerForTenant() throws Exception {
34-
collectorService.register(
35-
EXPECTATIONS_VULNERABILITY_COLLECTOR_ID,
36-
EXPECTATIONS_VULNERABILITY_COLLECTOR_TYPE,
37-
EXPECTATIONS_VULNERABILITY_COLLECTOR_NAME,
38-
false,
39-
0,
40-
null,
41-
getClass().getResourceAsStream("/img/icon-expectations-vulnerability-manager.png"));
25+
try {
26+
collectorService.collector(EXPECTATIONS_VULNERABILITY_COLLECTOR_ID);
27+
} catch (ElementNotFoundException e) {
28+
collectorService.register(
29+
EXPECTATIONS_VULNERABILITY_COLLECTOR_ID,
30+
EXPECTATIONS_VULNERABILITY_COLLECTOR_TYPE,
31+
EXPECTATIONS_VULNERABILITY_COLLECTOR_NAME,
32+
false,
33+
0,
34+
null,
35+
getClass().getResourceAsStream("/img/icon-expectations-vulnerability-manager.png"));
36+
}
4237
}
4338
}

openaev-api/src/main/java/io/openaev/integration/ManagerFactory.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.List;
2323
import lombok.RequiredArgsConstructor;
2424
import lombok.extern.slf4j.Slf4j;
25+
import org.hibernate.Session;
2526
import org.springframework.stereotype.Service;
2627
import org.springframework.transaction.annotation.Transactional;
2728

@@ -104,6 +105,12 @@ public void createDependencyForTenant(Tenant tenant) throws DependenciesManagerE
104105
String previousTenant = TenantContext.getCurrentTenant();
105106
try {
106107
TenantContext.setCurrentTenant(tenant.getId());
108+
// Re-enable the Hibernate filter with the correct tenant — the AOP aspect already activated
109+
// it with the previous tenant value before this method body runs.
110+
entityManager
111+
.unwrap(Session.class)
112+
.enableFilter("tenantFilter")
113+
.setParameter("tenantId", tenant.getId());
107114
for (BuiltinTenantRegistrable registrable : builtinRegistrables) {
108115
try {
109116
registrable.registerForTenant();

openaev-api/src/main/java/io/openaev/integration/impl/executors/openaev/OpenAEVExecutorIntegrationFactory.java

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import io.openaev.integration.BuiltinIntegrationFactory;
1010
import io.openaev.integration.ComponentRequestEngine;
1111
import io.openaev.integration.Integration;
12+
import io.openaev.rest.exception.ElementNotFoundException;
1213
import io.openaev.service.catalog_connectors.CatalogConnectorService;
1314
import io.openaev.service.connector_instances.ConnectorInstanceService;
1415
import java.util.List;
@@ -67,18 +68,22 @@ public Integration spawn(ConnectorInstance instance) {
6768

6869
@Override
6970
public void registerConnectorForTenant() throws Exception {
70-
executorService.register(
71-
OpenAEVExecutorIntegration.OPENAEV_EXECUTOR_ID,
72-
OpenAEVExecutorIntegration.OPENAEV_EXECUTOR_TYPE,
73-
OpenAEVExecutorIntegration.OPENAEV_EXECUTOR_NAME,
74-
OpenAEVExecutorIntegration.OPENAEV_EXECUTOR_DOCUMENTATION_LINK,
75-
OpenAEVExecutorIntegration.OPENAEV_EXECUTOR_BACKGROUND_COLOR,
76-
getClass().getResourceAsStream("/img/icon-openaev.png"),
77-
getClass().getResourceAsStream("/img/banner-openaev.png"),
78-
new String[] {
79-
Endpoint.PLATFORM_TYPE.Windows.name(),
80-
Endpoint.PLATFORM_TYPE.Linux.name(),
81-
Endpoint.PLATFORM_TYPE.MacOS.name()
82-
});
71+
try {
72+
executorService.executor(OpenAEVExecutorIntegration.OPENAEV_EXECUTOR_ID);
73+
} catch (ElementNotFoundException e) {
74+
executorService.register(
75+
OpenAEVExecutorIntegration.OPENAEV_EXECUTOR_ID,
76+
OpenAEVExecutorIntegration.OPENAEV_EXECUTOR_TYPE,
77+
OpenAEVExecutorIntegration.OPENAEV_EXECUTOR_NAME,
78+
OpenAEVExecutorIntegration.OPENAEV_EXECUTOR_DOCUMENTATION_LINK,
79+
OpenAEVExecutorIntegration.OPENAEV_EXECUTOR_BACKGROUND_COLOR,
80+
getClass().getResourceAsStream("/img/icon-openaev.png"),
81+
getClass().getResourceAsStream("/img/banner-openaev.png"),
82+
new String[] {
83+
Endpoint.PLATFORM_TYPE.Windows.name(),
84+
Endpoint.PLATFORM_TYPE.Linux.name(),
85+
Endpoint.PLATFORM_TYPE.MacOS.name()
86+
});
87+
}
8388
}
8489
}

openaev-api/src/main/java/io/openaev/integration/impl/injectors/challenge/ChallengeInjectorIntegration.java

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import io.openaev.database.model.ConnectorInstance;
44
import io.openaev.database.repository.ChallengeRepository;
55
import io.openaev.executors.InjectorContext;
6-
import io.openaev.healthcheck.enums.ExternalServiceDependency;
76
import io.openaev.injectors.challenge.ChallengeContract;
87
import io.openaev.injectors.challenge.ChallengeExecutor;
98
import io.openaev.injectors.email.service.EmailService;
@@ -13,7 +12,6 @@
1312
import io.openaev.service.InjectExpectationService;
1413
import io.openaev.service.InjectorService;
1514
import io.openaev.service.connector_instances.ConnectorInstanceService;
16-
import java.util.List;
1715

1816
public class ChallengeInjectorIntegration extends IntegrationInMemory {
1917
static final String CHALLENGE_INJECTOR_NAME = "Challenges";
@@ -51,16 +49,6 @@ public ChallengeInjectorIntegration(
5149

5250
@Override
5351
protected void innerStart() throws Exception {
54-
injectorService.registerBuiltinInjector(
55-
CHALLENGE_INJECTOR_ID,
56-
CHALLENGE_INJECTOR_NAME,
57-
challengeContract,
58-
false,
59-
"capture-the-flag",
60-
null,
61-
null,
62-
false,
63-
List.of(ExternalServiceDependency.SMTP, ExternalServiceDependency.IMAP));
6452
this.challengeExecutor =
6553
new ChallengeExecutor(
6654
injectorContext, challengeRepository, emailService, injectExpectationService);

openaev-api/src/main/java/io/openaev/integration/impl/injectors/challenge/ChallengeInjectorIntegrationFactory.java

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import io.openaev.integration.BuiltinIntegrationFactory;
1313
import io.openaev.integration.ComponentRequestEngine;
1414
import io.openaev.integration.Integration;
15+
import io.openaev.rest.exception.ElementNotFoundException;
1516
import io.openaev.service.InjectExpectationService;
1617
import io.openaev.service.InjectorService;
1718
import io.openaev.service.catalog_connectors.CatalogConnectorService;
@@ -101,15 +102,19 @@ public Integration spawn(ConnectorInstance instance)
101102

102103
@Override
103104
public void registerConnectorForTenant() throws Exception {
104-
injectorService.registerBuiltinInjector(
105-
ChallengeInjectorIntegration.CHALLENGE_INJECTOR_ID,
106-
ChallengeInjectorIntegration.CHALLENGE_INJECTOR_NAME,
107-
challengeContract,
108-
false,
109-
"capture-the-flag",
110-
null,
111-
null,
112-
false,
113-
List.of(ExternalServiceDependency.SMTP, ExternalServiceDependency.IMAP));
105+
try {
106+
injectorService.injector(ChallengeInjectorIntegration.CHALLENGE_INJECTOR_ID);
107+
} catch (ElementNotFoundException e) {
108+
injectorService.registerBuiltinInjector(
109+
ChallengeInjectorIntegration.CHALLENGE_INJECTOR_ID,
110+
ChallengeInjectorIntegration.CHALLENGE_INJECTOR_NAME,
111+
challengeContract,
112+
false,
113+
"capture-the-flag",
114+
null,
115+
null,
116+
false,
117+
List.of(ExternalServiceDependency.SMTP, ExternalServiceDependency.IMAP));
118+
}
114119
}
115120
}

openaev-api/src/main/java/io/openaev/integration/impl/injectors/channel/ChannelInjectorIntegrationFactory.java

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import io.openaev.integration.BuiltinIntegrationFactory;
1313
import io.openaev.integration.ComponentRequestEngine;
1414
import io.openaev.integration.Integration;
15+
import io.openaev.rest.exception.ElementNotFoundException;
1516
import io.openaev.service.InjectExpectationService;
1617
import io.openaev.service.InjectorService;
1718
import io.openaev.service.catalog_connectors.CatalogConnectorService;
@@ -99,15 +100,19 @@ public Integration spawn(ConnectorInstance instance)
99100

100101
@Override
101102
public void registerConnectorForTenant() throws Exception {
102-
injectorService.registerBuiltinInjector(
103-
ChannelInjectorIntegration.CHANNEL_INJECTOR_ID,
104-
ChannelInjectorIntegration.CHANNEL_INJECTOR_NAME,
105-
channelContract,
106-
false,
107-
"media-pressure",
108-
null,
109-
null,
110-
false,
111-
List.of(ExternalServiceDependency.SMTP, ExternalServiceDependency.SMTP));
103+
try {
104+
injectorService.injector(ChannelInjectorIntegration.CHANNEL_INJECTOR_ID);
105+
} catch (ElementNotFoundException e) {
106+
injectorService.registerBuiltinInjector(
107+
ChannelInjectorIntegration.CHANNEL_INJECTOR_ID,
108+
ChannelInjectorIntegration.CHANNEL_INJECTOR_NAME,
109+
channelContract,
110+
false,
111+
"media-pressure",
112+
null,
113+
null,
114+
false,
115+
List.of(ExternalServiceDependency.SMTP, ExternalServiceDependency.SMTP));
116+
}
112117
}
113118
}

openaev-api/src/main/java/io/openaev/integration/impl/injectors/email/EmailInjectorIntegrationFactory.java

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import io.openaev.integration.BuiltinIntegrationFactory;
1212
import io.openaev.integration.ComponentRequestEngine;
1313
import io.openaev.integration.Integration;
14+
import io.openaev.rest.exception.ElementNotFoundException;
1415
import io.openaev.service.InjectExpectationService;
1516
import io.openaev.service.InjectorService;
1617
import io.openaev.service.catalog_connectors.CatalogConnectorService;
@@ -95,15 +96,19 @@ public Integration spawn(ConnectorInstance instance)
9596

9697
@Override
9798
public void registerConnectorForTenant() throws Exception {
98-
injectorService.registerBuiltinInjector(
99-
EmailInjectorIntegration.EMAIL_INJECTOR_ID,
100-
EmailInjectorIntegration.EMAIL_INJECTOR_NAME,
101-
emailContract,
102-
false,
103-
"communication",
104-
null,
105-
null,
106-
false,
107-
List.of(ExternalServiceDependency.SMTP, ExternalServiceDependency.IMAP));
99+
try {
100+
injectorService.injector(EmailInjectorIntegration.EMAIL_INJECTOR_ID);
101+
} catch (ElementNotFoundException e) {
102+
injectorService.registerBuiltinInjector(
103+
EmailInjectorIntegration.EMAIL_INJECTOR_ID,
104+
EmailInjectorIntegration.EMAIL_INJECTOR_NAME,
105+
emailContract,
106+
false,
107+
"communication",
108+
null,
109+
null,
110+
false,
111+
List.of(ExternalServiceDependency.SMTP, ExternalServiceDependency.IMAP));
112+
}
108113
}
109114
}

openaev-api/src/main/java/io/openaev/integration/impl/injectors/manual/ManualInjectorIntegrationFactory.java

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import io.openaev.integration.BuiltinIntegrationFactory;
1010
import io.openaev.integration.ComponentRequestEngine;
1111
import io.openaev.integration.Integration;
12+
import io.openaev.rest.exception.ElementNotFoundException;
1213
import io.openaev.service.InjectExpectationService;
1314
import io.openaev.service.InjectorService;
1415
import io.openaev.service.catalog_connectors.CatalogConnectorService;
@@ -90,15 +91,19 @@ public Integration spawn(ConnectorInstance instance)
9091

9192
@Override
9293
public void registerConnectorForTenant() throws Exception {
93-
injectorService.registerBuiltinInjector(
94-
ManualInjectorIntegration.MANUAL_INJECTOR_ID,
95-
ManualInjectorIntegration.MANUAL_INJECTOR_NAME,
96-
manualContract,
97-
true,
98-
"generic",
99-
null,
100-
null,
101-
false,
102-
List.of());
94+
try {
95+
injectorService.injector(ManualInjectorIntegration.MANUAL_INJECTOR_ID);
96+
} catch (ElementNotFoundException e) {
97+
injectorService.registerBuiltinInjector(
98+
ManualInjectorIntegration.MANUAL_INJECTOR_ID,
99+
ManualInjectorIntegration.MANUAL_INJECTOR_NAME,
100+
manualContract,
101+
true,
102+
"generic",
103+
null,
104+
null,
105+
false,
106+
List.of());
107+
}
103108
}
104109
}

openaev-api/src/main/java/io/openaev/integration/impl/injectors/openaev/OpenaevInjectorIntegrationFactory.java

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import io.openaev.integration.BuiltinIntegrationFactory;
1111
import io.openaev.integration.ComponentRequestEngine;
1212
import io.openaev.integration.Integration;
13+
import io.openaev.rest.exception.ElementNotFoundException;
1314
import io.openaev.rest.inject.service.InjectService;
1415
import io.openaev.service.AssetGroupService;
1516
import io.openaev.service.InjectExpectationService;
@@ -104,20 +105,24 @@ public Integration spawn(ConnectorInstance instance)
104105

105106
@Override
106107
public void registerConnectorForTenant() throws Exception {
107-
Map<String, String> executorCommands =
108-
OpenaevImplantCommandBuilder.buildExecutorCommands(openAEVConfig);
109-
Map<String, String> executorClearCommands =
110-
OpenaevImplantCommandBuilder.buildExecutorClearCommands();
108+
try {
109+
injectorService.injector(OpenaevInjectorIntegration.OPENAEV_INJECTOR_ID);
110+
} catch (ElementNotFoundException e) {
111+
Map<String, String> executorCommands =
112+
OpenaevImplantCommandBuilder.buildExecutorCommands(openAEVConfig);
113+
Map<String, String> executorClearCommands =
114+
OpenaevImplantCommandBuilder.buildExecutorClearCommands();
111115

112-
injectorService.registerBuiltinInjector(
113-
OpenaevInjectorIntegration.OPENAEV_INJECTOR_ID,
114-
OpenaevInjectorIntegration.OPENAEV_INJECTOR_NAME,
115-
openAEVImplantContract,
116-
false,
117-
"simulation-implant",
118-
executorCommands,
119-
executorClearCommands,
120-
true,
121-
List.of());
116+
injectorService.registerBuiltinInjector(
117+
OpenaevInjectorIntegration.OPENAEV_INJECTOR_ID,
118+
OpenaevInjectorIntegration.OPENAEV_INJECTOR_NAME,
119+
openAEVImplantContract,
120+
false,
121+
"simulation-implant",
122+
executorCommands,
123+
executorClearCommands,
124+
true,
125+
List.of());
126+
}
122127
}
123128
}

0 commit comments

Comments
 (0)