Skip to content

Commit b6c9acd

Browse files
committed
Closes #25.
Create demo environment for #14. Closes #4 by resolving some issues with loading configuration at deployment.
1 parent 1fed8ed commit b6c9acd

File tree

24 files changed

+458
-19
lines changed

24 files changed

+458
-19
lines changed

.gcp.env

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
SENTRIUS_VERSION=1.0.18
1+
SENTRIUS_VERSION=1.0.23
22
SENTRIUS_SSH_VERSION=1.0.2
33
SENTRIUS_KEYCLOAK_VERSION=1.0.4
4-
SENTRIUS_AGENT_VERSION=1.0.13
4+
SENTRIUS_AGENT_VERSION=1.0.14

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ WORKDIR /app
77
# Copy the pre-built API JAR into the container
88
COPY api/target/sentrius-api-1.0.0-SNAPSHOT.jar /app/sentrius.jar
99
COPY docker/sentrius/exampleInstallWithTypes.yml /app/exampleInstallWithTypes.yml
10+
COPY docker/sentrius/demoInstaller.yml /app/demoInstaller.yml
1011

1112
# Expose the port the app runs on
1213
EXPOSE 8080

analyagents/src/main/java/io/sentrius/agent/analysis/agents/sessions/SessionAnalyticsAgent.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,37 @@
44
import java.util.ArrayList;
55
import java.util.Arrays;
66
import java.util.List;
7+
import java.util.Map;
78
import java.util.Set;
89
import java.util.regex.Matcher;
910
import java.util.regex.Pattern;
1011
import java.util.stream.Collectors;
12+
import com.fasterxml.jackson.core.JsonProcessingException;
1113
import io.sentrius.sso.core.model.metadata.AnalyticsTracking;
1214
import io.sentrius.sso.core.model.metadata.TerminalBehaviorMetrics;
1315
import io.sentrius.sso.core.model.metadata.TerminalCommand;
1416
import io.sentrius.sso.core.model.metadata.TerminalRiskIndicator;
1517
import io.sentrius.sso.core.model.metadata.TerminalSessionMetadata;
1618
import io.sentrius.sso.core.model.metadata.UserExperienceMetrics;
19+
import io.sentrius.sso.core.model.security.IntegrationSecurityToken;
1720
import io.sentrius.sso.core.model.sessions.TerminalLogs;
1821
import io.sentrius.sso.core.repository.AnalyticsTrackingRepository;
22+
import io.sentrius.sso.core.services.IntegrationSecurityTokenService;
23+
import io.sentrius.sso.core.services.PluggableServices;
1924
import io.sentrius.sso.core.services.SessionService;
2025
import io.sentrius.sso.core.services.metadata.TerminalBehaviorMetricsService;
2126
import io.sentrius.sso.core.services.metadata.TerminalCommandService;
2227
import io.sentrius.sso.core.services.metadata.TerminalRiskIndicatorService;
2328
import io.sentrius.sso.core.services.metadata.TerminalSessionMetadataService;
2429
import io.sentrius.sso.core.services.metadata.UserExperienceMetricsService;
30+
import io.sentrius.sso.core.utils.JsonUtil;
31+
import io.sentrius.sso.integrations.external.ExternalIntegrationDTO;
32+
import io.sentrius.sso.security.ApiKey;
2533
import jakarta.transaction.Transactional;
2634
import lombok.RequiredArgsConstructor;
2735
import lombok.extern.slf4j.Slf4j;
2836
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
37+
import org.springframework.context.ApplicationContext;
2938
import org.springframework.scheduling.annotation.Scheduled;
3039
import org.springframework.stereotype.Component;
3140

@@ -42,6 +51,8 @@ public class SessionAnalyticsAgent {
4251
private final UserExperienceMetricsService experienceMetricsService;
4352
private final AnalyticsTrackingRepository trackingRepository;
4453
private final SessionService sessionService;
54+
final IntegrationSecurityTokenService integrationSecurityTokenService;
55+
4556

4657
@Scheduled(fixedDelay = 60000) // Waits 60 seconds after the previous run completes
4758
@Transactional
@@ -66,7 +77,35 @@ public void processSessions() {
6677
// session.setSessionStatus("PROCESSED");
6778
// sessionMetadataService.saveSession(session);
6879
}
80+
81+
log.info("Finished processing sessions");
6982
}
83+
/* TODO - Implement this
84+
@Scheduled(fixedDelay = 60000) // Waits 60 seconds after the previous run completes
85+
@Transactional
86+
public void processTerminalCommands() {
87+
log.info("Processing terminal commands...");
88+
89+
var openaiService = integrationSecurityTokenService.findByConnectionType("openai").stream().findFirst().orElse(null);
90+
91+
if (null != openaiService){
92+
log.info("OpenAI service is available");
93+
ExternalIntegrationDTO externalIntegrationDTO = null;
94+
try {
95+
externalIntegrationDTO = JsonUtil.MAPPER.readValue(openAiToken.getConnectionInfo(),
96+
ExternalIntegrationDTO.class);
97+
} catch (JsonProcessingException e) {
98+
throw new RuntimeException(e);
99+
}
100+
ApiKey key =
101+
ApiKey.builder().apiKey(externalIntegrationDTO.getApiToken()).principal(externalIntegrationDTO.getUsername()).build();
102+
103+
} else {
104+
log.info("OpenAI service is not enabled");
105+
}
106+
107+
log.info("Finished processing terminal commands");
108+
}*/
70109

71110
private void processSession(TerminalSessionMetadata session) {
72111

api/dynamic.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ enableInternalAudit=true
2222
twopartyapproval.require.explanation.LOCKING_SYSTEMS=false
2323
canApproveOwnJITs=false
2424
allowUploadSystemConfiguration = true
25-
yamlConfigurationPath=/mnt/ExtraDrive/repos/Sentrius/docker/sentrius/exampleInstallWithTypes.yml
25+
yamlConfigurationPath=/mnt/ExtraDrive/repos/Sentrius/docker/sentrius/demoInstaller.yml

api/src/main/java/io/sentrius/sso/startup/ConfigurationApplicationTask.java

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.concurrent.atomic.AtomicBoolean;
2020
import java.util.concurrent.atomic.AtomicReference;
2121
import com.jcraft.jsch.JSchException;
22+
import io.sentrius.sso.automation.auditing.RuleFactory;
2223
import io.sentrius.sso.automation.sideeffects.SideEffect;
2324
import io.sentrius.sso.automation.sideeffects.SideEffectType;
2425
import io.sentrius.sso.core.config.SystemOptions;
@@ -28,6 +29,7 @@
2829
import io.sentrius.sso.core.model.dto.HostSystemDTO;
2930
import io.sentrius.sso.core.model.dto.UserTypeDTO;
3031
import io.sentrius.sso.core.model.hostgroup.HostGroup;
32+
import io.sentrius.sso.core.model.hostgroup.ProfileRule;
3133
import io.sentrius.sso.core.model.security.UserType;
3234
import io.sentrius.sso.core.model.security.enums.ApplicationAccessEnum;
3335
import io.sentrius.sso.core.model.security.enums.AutomationAccessEnum;
@@ -43,9 +45,12 @@
4345
import io.sentrius.sso.core.repository.UserTypeRepository;
4446
import io.sentrius.sso.core.security.service.CryptoService;
4547
import io.sentrius.sso.core.services.HostGroupService;
48+
import io.sentrius.sso.core.services.RuleService;
4649
import io.sentrius.sso.core.services.UserService;
4750
import io.sentrius.sso.install.configuration.InstallConfiguration;
4851
import io.sentrius.sso.install.configuration.dtos.HostGroupConfigurationDTO;
52+
import io.sentrius.sso.install.configuration.dtos.RuleDTO;
53+
import jakarta.transaction.Transactional;
4954
import lombok.RequiredArgsConstructor;
5055
import lombok.extern.slf4j.Slf4j;
5156
import org.springframework.boot.context.event.ApplicationReadyEvent;
@@ -70,12 +75,15 @@ public class ConfigurationApplicationTask {
7075

7176
final UserTypeRepository userTypeRepository;
7277

78+
final RuleService ruleService;
79+
7380
final UserService userService;
7481
private final HostGroupService hostGroupService;
7582

7683
final CryptoService cryptoService;
7784

7885
@EventListener(ApplicationReadyEvent.class)
86+
@Transactional
7987
public void afterStartup() throws IOException, GeneralSecurityException, JSchException, SQLException {
8088
// Your logic here
8189

@@ -131,7 +139,7 @@ public void afterStartup() throws IOException, GeneralSecurityException, JSchExc
131139
log.info("No configuration file found");
132140
}
133141
}
134-
142+
@Transactional
135143
public List<SideEffect> createStaticType(UserType type, boolean action) throws SQLException,
136144
GeneralSecurityException {
137145

@@ -160,7 +168,7 @@ public List<SideEffect> createStaticType(UserType type, boolean action) throws S
160168
return sideEffects;
161169
}
162170

163-
171+
@Transactional
164172
public List<SideEffect> initialize(InstallConfiguration installConfiguration, boolean action)
165173
throws SQLException,
166174
GeneralSecurityException,
@@ -188,19 +196,38 @@ public List<SideEffect> initialize(InstallConfiguration installConfiguration, bo
188196

189197
// create profiles and assign systems
190198

191-
var profiles = createHostGroups(sideEffects, installConfiguration, action);
199+
var rules = createRules(sideEffects, installConfiguration, action);
200+
201+
var profiles = createHostGroups(sideEffects, rules, installConfiguration, action);
192202

193203
createUsers(sideEffects, installConfiguration, userTypes, profiles, action);
194-
204+
205+
206+
195207
// create automation assignments
196208

197209
//AppConfig.encryptProperty("initialized", Instant.now().toString());
198210

199211
return sideEffects;
200212
}
213+
@Transactional
214+
protected Map<String,ProfileRule> createRules(
215+
List<SideEffect> sideEffects, InstallConfiguration installConfiguration,
216+
boolean action
217+
) {
218+
Map<String,ProfileRule> rules = new HashMap<>();
219+
var configuredRules = installConfiguration.getRules();
220+
for(RuleDTO rule : configuredRules) {
221+
ProfileRule newRule =
222+
ProfileRule.builder().ruleClass(rule.getRuleClass()).ruleName(rule.getDisplayName()).ruleConfig(rule.getConfiguration()).build();
223+
newRule = ruleService.saveRule(newRule);
224+
rules.put(rule.getDisplayName(), newRule);
225+
}
226+
return rules;
227+
}
201228

202-
203-
private List<HostGroup> createHostGroups(List<SideEffect> sideEffects, InstallConfiguration installConfiguration,
229+
@Transactional
230+
protected List<HostGroup> createHostGroups(List<SideEffect> sideEffects, Map<String,ProfileRule> rules, InstallConfiguration installConfiguration,
204231
boolean action)
205232
throws JSchException, GeneralSecurityException, IOException {
206233
List<HostGroup> profiles = new ArrayList<>();
@@ -235,12 +262,21 @@ private List<HostGroup> createHostGroups(List<SideEffect> sideEffects, InstallCo
235262
if (!systems.isEmpty()) {
236263
hostGroup.setHostSystems(systems);
237264
}
265+
266+
for( var assignedRule : hostGroupDto.getAssignedRules() ) {
267+
if (rules.containsKey(assignedRule)) {
268+
var rule = rules.get(assignedRule);
269+
hostGroup.getRules().add(rule);
270+
rule.getHostGroups().add(hostGroup);
271+
}
272+
};
238273
}
239274
var hostGroups = hostGroupService.getHostGroupsByName(hostGroup.getName());
240275
if (hostGroups.isEmpty()) {
241276
if (action) {
242277

243278
hostGroup = hostGroupRepository.save(hostGroup);
279+
log.info("Creating Host Group {} with {}", hostGroup.getId(), hostGroupDto.getDisplayName());
244280
profiles.add(hostGroup);
245281
for(var hs : hostGroup.getHostSystems()) {
246282
if (null == hs.getHostGroups()){
@@ -284,7 +320,8 @@ private List<HostGroup> createHostGroups(List<SideEffect> sideEffects, InstallCo
284320
return profiles;
285321
}
286322

287-
private List<SideEffect> createSystems(InstallConfiguration installConfiguration, boolean action) throws SQLException,
323+
@Transactional
324+
protected List<SideEffect> createSystems(InstallConfiguration installConfiguration, boolean action) throws SQLException,
288325
GeneralSecurityException {
289326
List<SideEffect> sideEffects = new ArrayList<>();
290327
if (null != installConfiguration.getSystems()) {
@@ -303,7 +340,8 @@ private List<SideEffect> createSystems(InstallConfiguration installConfiguration
303340
return sideEffects;
304341
}
305342

306-
private boolean shouldInsertSystem(HostSystem systemObj) {
343+
@Transactional
344+
protected boolean shouldInsertSystem(HostSystem systemObj) {
307345
var systems = systemRepository.findByDisplayName(systemObj.getDisplayName());
308346
if (systems.isEmpty()) {
309347
return true;
@@ -316,6 +354,7 @@ private boolean shouldInsertSystem(HostSystem systemObj) {
316354
return true;
317355
}
318356

357+
@Transactional
319358
protected List<UserType> createUserTypes(List<SideEffect> sideEffects, InstallConfiguration installConfiguration,
320359
boolean action) throws SQLException, GeneralSecurityException {
321360
List<UserType> types = new ArrayList<>();
@@ -365,6 +404,7 @@ protected List<UserType> createUserTypes(List<SideEffect> sideEffects, InstallCo
365404
return types;
366405
}
367406

407+
@Transactional
368408
protected List<User> createUsers(
369409
List<SideEffect> sideEffects, InstallConfiguration installConfiguration, List<UserType> userTypes,
370410
List<HostGroup> profiles, boolean action)
@@ -466,6 +506,8 @@ static void createOrUpdate(Map<Long, Set<Long>> assignments, Long profileId, Lon
466506
set.add(userId);
467507
}
468508

509+
510+
@Transactional
469511
protected List<SideEffect> createAdminUser(InstallConfiguration installConfiguration, boolean action) throws NoSuchAlgorithmException {
470512

471513
var user = installConfiguration.getAdminUser();
@@ -501,6 +543,7 @@ protected List<SideEffect> createAdminUser(InstallConfiguration installConfigura
501543
return sideEffects;
502544
}
503545

546+
@Transactional
504547
protected void createSystemUser(InstallConfiguration connection) throws NoSuchAlgorithmException {
505548

506549
User user = User.builder()

core/src/main/java/io/sentrius/sso/automation/auditing/RuleFactory.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import io.sentrius.sso.core.model.auditing.Rule;
88
import io.sentrius.sso.core.services.PluggableServices;
99
import io.sentrius.sso.core.services.terminal.SessionTrackingService;
10+
import io.sentrius.sso.install.configuration.dtos.RuleDTO;
1011
import lombok.extern.slf4j.Slf4j;
1112

1213
@Slf4j
@@ -41,4 +42,5 @@ public static void createRules(
4142
}
4243
}
4344
}
45+
4446
}

core/src/main/java/io/sentrius/sso/automation/auditing/rules/SudoPrevention.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,33 @@
33
import java.util.Optional;
44
import io.sentrius.sso.automation.auditing.Trigger;
55
import io.sentrius.sso.automation.auditing.TriggerAction;
6+
import lombok.extern.slf4j.Slf4j;
67

8+
import java.util.Optional;
9+
import java.util.regex.Pattern;
10+
11+
@Slf4j
712
public class SudoPrevention extends CommandEvaluator {
813

14+
// Updated pattern to match both 'sudo' and 'su' as standalone commands (case-insensitive)
15+
private static final Pattern SUDO_SU_PATTERN = Pattern.compile("\\b(sudo|su)\\b", Pattern.CASE_INSENSITIVE);
16+
917
public SudoPrevention() {
1018
action = TriggerAction.DENY_ACTION;
1119
isSanitized = true;
1220
}
1321

1422
@Override
1523
public Optional<Trigger> trigger(String text) {
16-
if (text.contains("sudo") || text.contains("SUDO")) {
17-
return Optional.of(new Trigger(action, "SUDO is not allowed"));
24+
if (text == null || text.isEmpty()) {
25+
return Optional.empty();
26+
}
27+
28+
// Check if the input contains 'sudo' or 'su'
29+
if (SUDO_SU_PATTERN.matcher(text).find()) {
30+
// Log the blocked attempt
31+
log.info("Blocked SUDO/SU attempt: {}", text);
32+
return Optional.of(new Trigger(action, "SUDO and SU are not allowed"));
1833
}
1934

2035
return Optional.empty();

core/src/main/java/io/sentrius/sso/core/model/hostgroup/HostGroup.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import java.io.IOException;
99
import java.util.Collection;
10+
import java.util.HashSet;
1011
import java.util.List;
1112
import java.util.Set;
1213
import com.fasterxml.jackson.annotation.JsonManagedReference;
@@ -89,9 +90,10 @@ public class HostGroup {
8990
joinColumns = @JoinColumn(name = "system_id"),
9091
inverseJoinColumns = @JoinColumn(name = "rule_id")
9192
)
92-
private Set<ProfileRule> rules;
93+
@Builder.Default
94+
private Set<ProfileRule> rules = new HashSet<>();
9395

94-
@OneToOne(cascade = CascadeType.ALL)
96+
@OneToOne(cascade = {CascadeType.MERGE, CascadeType.REMOVE})
9597
@JoinColumn(name = "application_key_id", referencedColumnName = "id", unique = true)
9698
private ApplicationKey applicationKey;
9799

core/src/main/java/io/sentrius/sso/core/model/hostgroup/ProfileRule.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.sentrius.sso.core.model.hostgroup;
22

3+
import java.util.HashSet;
34
import java.util.Set;
45
import io.sentrius.sso.core.model.auditing.Rule;
56
import jakarta.persistence.Column;
@@ -11,6 +12,7 @@
1112
import jakarta.persistence.ManyToMany;
1213
import jakarta.persistence.Table;
1314
import lombok.AllArgsConstructor;
15+
import lombok.Builder;
1416
import lombok.Getter;
1517
import lombok.NoArgsConstructor;
1618
import lombok.Setter;
@@ -41,6 +43,7 @@ public class ProfileRule extends Rule {
4143
private String ruleConfig;
4244

4345
@ManyToMany(mappedBy = "rules", fetch = FetchType.EAGER)
44-
private Set<HostGroup> hostGroups;
46+
@Builder.Default
47+
private Set<HostGroup> hostGroups = new HashSet<>();
4548

4649
}

0 commit comments

Comments
 (0)