Skip to content

Commit c6b40a1

Browse files
authored
Merge pull request #29 from SentriusLLC/newi
commit
2 parents e736a17 + 5d5e5c2 commit c6b40a1

File tree

28 files changed

+453
-68
lines changed

28 files changed

+453
-68
lines changed

.gcp.env

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
SENTRIUS_VERSION=1.0.34
2-
SENTRIUS_SSH_VERSION=1.0.3
3-
SENTRIUS_KEYCLOAK_VERSION=1.0.4
4-
SENTRIUS_AGENT_VERSION=1.0.15
1+
SENTRIUS_VERSION=1.0.37
2+
SENTRIUS_SSH_VERSION=1.0.4
3+
SENTRIUS_KEYCLOAK_VERSION=1.0.6
4+
SENTRIUS_AGENT_VERSION=1.0.16

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

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,35 @@
11
package io.sentrius.agent.analysis.agents.sessions;
22

3+
import java.nio.charset.StandardCharsets;
34
import java.sql.Timestamp;
45
import java.util.ArrayList;
5-
import java.util.Arrays;
6+
import java.util.Base64;
67
import java.util.List;
7-
import java.util.Map;
88
import java.util.Set;
99
import java.util.regex.Matcher;
1010
import java.util.regex.Pattern;
1111
import java.util.stream.Collectors;
12-
import com.fasterxml.jackson.core.JsonProcessingException;
12+
import io.sentrius.sso.core.model.categorization.CommandCategory;
1313
import io.sentrius.sso.core.model.metadata.AnalyticsTracking;
1414
import io.sentrius.sso.core.model.metadata.TerminalBehaviorMetrics;
1515
import io.sentrius.sso.core.model.metadata.TerminalCommand;
1616
import io.sentrius.sso.core.model.metadata.TerminalRiskIndicator;
1717
import io.sentrius.sso.core.model.metadata.TerminalSessionMetadata;
1818
import io.sentrius.sso.core.model.metadata.UserExperienceMetrics;
19-
import io.sentrius.sso.core.model.security.IntegrationSecurityToken;
2019
import io.sentrius.sso.core.model.sessions.TerminalLogs;
2120
import io.sentrius.sso.core.repository.AnalyticsTrackingRepository;
2221
import io.sentrius.sso.core.services.IntegrationSecurityTokenService;
23-
import io.sentrius.sso.core.services.PluggableServices;
2422
import io.sentrius.sso.core.services.SessionService;
2523
import io.sentrius.sso.core.services.metadata.TerminalBehaviorMetricsService;
2624
import io.sentrius.sso.core.services.metadata.TerminalCommandService;
2725
import io.sentrius.sso.core.services.metadata.TerminalRiskIndicatorService;
2826
import io.sentrius.sso.core.services.metadata.TerminalSessionMetadataService;
2927
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;
28+
import io.sentrius.sso.core.services.openai.categorization.CommandCategorizer;
3329
import jakarta.transaction.Transactional;
3430
import lombok.RequiredArgsConstructor;
3531
import lombok.extern.slf4j.Slf4j;
3632
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
37-
import org.springframework.context.ApplicationContext;
3833
import org.springframework.scheduling.annotation.Scheduled;
3934
import org.springframework.stereotype.Component;
4035

@@ -51,6 +46,7 @@ public class SessionAnalyticsAgent {
5146
private final UserExperienceMetricsService experienceMetricsService;
5247
private final AnalyticsTrackingRepository trackingRepository;
5348
private final SessionService sessionService;
49+
private final CommandCategorizer commandCategorizer;
5450
final IntegrationSecurityTokenService integrationSecurityTokenService;
5551

5652

@@ -61,6 +57,7 @@ public void processSessions() {
6157

6258
// Fetch already processed session IDs in bulk
6359
Set<Long> processedSessionIds = trackingRepository.findAllSessionIds();
60+
log.info("Found {} processed sessions", processedSessionIds.size());
6461
List<TerminalSessionMetadata> unprocessedSessions = sessionMetadataService.getSessionsByState("CLOSED").stream()
6562
.filter(session -> !processedSessionIds.contains(session.getId()))
6663
.collect(Collectors.toList());
@@ -69,13 +66,13 @@ public void processSessions() {
6966
try {
7067
processSession(session);
7168
// ACTIVE -> INACTIVE -> CLOSED -> PROCESSED
72-
// saveToTracking(session.getId(), "PROCESSED");
69+
saveToTracking(session.getId(), "PROCESSED");
7370
} catch (Exception e) {
7471
log.error("Error processing session {}: {}", session.getId(), e.getMessage(), e);
7572
saveToTracking(session.getId(), "ERROR");
7673
}
77-
// session.setSessionStatus("PROCESSED");
78-
// sessionMetadataService.saveSession(session);
74+
session.setSessionStatus("PROCESSED");
75+
sessionMetadataService.saveSession(session);
7976
}
8077

8178
log.info("Finished processing sessions");
@@ -185,7 +182,6 @@ public static String extractCommand(TerminalLogs previousLog, String logLine) {
185182
return matcher.group(1).trim();
186183
} else {
187184
if (null != previousLog) {
188-
log.info("Previous log: {}", previousLog.getOutput());
189185
// it could be that we are at the beginning of the log set.
190186
String lastLogLine = getLastLogLine(previousLog);
191187
if (!lastLogLine.isEmpty()) {
@@ -215,26 +211,20 @@ private static String getLastLogLine(TerminalLogs previousLog) {
215211
}
216212

217213
private TerminalCommand createTerminalCommand(String command, TerminalLogs terminalLog, TerminalSessionMetadata sessionMetadata) {
214+
String encodedString = Base64.getEncoder().encodeToString(command.trim().getBytes(StandardCharsets.UTF_8));
215+
218216
TerminalCommand terminalCommand = new TerminalCommand();
219-
terminalCommand.setCommand(command.trim());
217+
terminalCommand.setCommand(encodedString);
220218
terminalCommand.setSession(sessionMetadata);
221219
terminalCommand.setExecutionTime(new Timestamp(System.currentTimeMillis()));
222220
terminalCommand.setExecutionStatus("SUCCESS");
223221
terminalCommand.setOutput(""); // Assume no output initially
224-
terminalCommand.setCommandCategory(categorizeCommand(command));
222+
terminalCommand.setCommandCategory(categorizeCommand(command).getCategoryName());
225223

226224
return terminalCommand;
227225
}
228226

229-
private String categorizeCommand(String command) {
230-
// probably need to define externally
231-
if (command.startsWith("sudo")) {
232-
return "PRIVILEGED";
233-
} else if (command.contains("rm")) {
234-
return "DESTRUCTIVE";
235-
} else if (command.contains("ls") || command.contains("cat")) {
236-
return "INFORMATIONAL";
237-
}
238-
return "GENERAL";
227+
private CommandCategory categorizeCommand(String command) {
228+
return commandCategorizer.categorizeCommand(command);
239229
}
240230
}

analyagents/src/main/resources/application.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,5 @@ spring.security.oauth2.client.provider.keycloak.issuer-uri=http://192.168.1.162:
6161
# for testing analytics agents
6262
agents.session-analytics.enabled=true
6363
management.endpoints.web.exposure.include=health
64-
management.endpoint.health.show-details=always
64+
management.endpoint.health.show-details=always
65+

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

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ protected List<HostGroup> createHostGroups(List<SideEffect> sideEffects, Map<Str
276276
if (action) {
277277

278278
hostGroup = hostGroupRepository.save(hostGroup);
279-
log.info("Creating Host Group {} with {}", hostGroup.getId(), hostGroupDto.getDisplayName());
279+
log.info("Creating Host Enclave {} with {}", hostGroup.getId(), hostGroupDto.getDisplayName());
280280
profiles.add(hostGroup);
281281
for(var hs : hostGroup.getHostSystems()) {
282282
if (null == hs.getHostGroups()){
@@ -287,27 +287,27 @@ protected List<HostGroup> createHostGroups(List<SideEffect> sideEffects, Map<Str
287287
systemRepository.save(hs);
288288
}
289289
}
290-
sideEffects.add(SideEffect.builder().sideEffectDescription("Creating Host Group " + hostGroupDto.getDisplayName()).type(
290+
sideEffects.add(SideEffect.builder().sideEffectDescription("Creating Host Enclave " + hostGroupDto.getDisplayName()).type(
291291
SideEffectType.UPDATE_DATABASE).asset("HostGroups").build());
292292
}else {
293293

294294
boolean existsInHostGroup = false;
295295

296296

297297
for(HostGroup hg : hostGroups) {
298-
log.info("Updating Host Group {} with {}", hg.getId(), hg.getId());
298+
log.info("Updating Host Enclave {} with {}", hg.getId(), hg.getId());
299299
profiles.add(hg);
300300

301301
for(var hs : hostGroup.getHostSystems()) {
302302
if (!systemRepository.isAssignedToHostGroups(hs.getId(), List.of( hg.getId()))) {
303303
if (action) {
304304
hs.getHostGroups().add(hg);
305305
systemRepository.save(hs);
306-
log.info("Updating Host Group {} with {}", hg.getId(), hs.getId());
306+
log.info("Updating Host Enclave {} with {}", hg.getId(), hs.getId());
307307
}
308308

309309
sideEffects.add(SideEffect.builder()
310-
.sideEffectDescription("Updating Host Group " + hostGroupDto.getDisplayName()).type(
310+
.sideEffectDescription("Updating Host Enclave " + hostGroupDto.getDisplayName()).type(
311311
SideEffectType.UPDATE_DATABASE).asset("HostGroups").build());
312312
}
313313
}
@@ -453,10 +453,10 @@ protected List<User> createUsers(
453453

454454

455455
sideEffects.add(SideEffect.builder().sideEffectDescription(
456-
"Assigning user " + userDTO.getUsername() + " to Host Group " +
456+
"Assigning user " + userDTO.getUsername() + " to Host Enclave " +
457457
hostGroup.getName()).type(
458458
SideEffectType.UPDATE_DATABASE).asset("Users").build());
459-
log.info("Assigning user {} to Host Group {}", userDTO.getUsername(),
459+
log.info("Assigning user {} to Host Enclave {}", userDTO.getUsername(),
460460
hostGroup.getId());
461461
user.getHostGroups().add(hostGroup);
462462
}
@@ -473,15 +473,15 @@ protected List<User> createUsers(
473473
for (var profile : userDTO.getHostGroups()) {
474474
for (HostGroup hostGroup : profiles) {
475475
if (hostGroup.getName().equals(profile.getDisplayName())) {
476-
log.info("Assigning user {} to Host Group {}", userDTO.getUsername(),
476+
log.info("Assigning user {} to Host Enclave {}", userDTO.getUsername(),
477477
hostGroup.getId());
478478
if (null == hostGroup.getId() || !userRepository.isAssignedToHostGroups(user.getId(),
479479
List.of(hostGroup.getId()))) {
480480
sideEffects.add(SideEffect.builder().sideEffectDescription(
481-
"Assigning user " + userDTO.getUsername() + " to Host Group " +
481+
"Assigning user " + userDTO.getUsername() + " to Host Enclave " +
482482
hostGroup.getName()).type(
483483
SideEffectType.UPDATE_DATABASE).asset("Users").build());
484-
log.info("Assigning user {} to Host Group {}", userDTO.getUsername(),
484+
log.info("Assigning user {} to Host Enclave {}", userDTO.getUsername(),
485485
hostGroup.getId()
486486
);
487487
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CREATE TABLE command_categories (
2+
id SERIAL PRIMARY KEY,
3+
category_name VARCHAR(50) NOT NULL,
4+
pattern TEXT NOT NULL, -- Store regex patterns
5+
priority INT NOT NULL DEFAULT 0 -- Optional: for matching precedence
6+
);
7+
8+
9+
CREATE INDEX idx_pattern ON command_categories (pattern);
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CREATE EXTENSION IF NOT EXISTS pg_trgm;
2+
3+
CREATE INDEX idx_command_pattern_trgm ON command_categories USING gin (pattern gin_trgm_ops);

api/src/main/resources/static/js/rules.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ $(document).ready(function () {
110110

111111
if (row.canEdit) {
112112
buttons +=
113-
`<button class="btn btn-secondary spacer spacer-middle" data-bs-toggle="modal" data-bs-target="#edit_dialog_${data}" onclick="editRule(${data})">Edit</button><button id="role_btn_${data}" onclick="assignRule(${data})" class="btn btn-secondary assign_btn spacer spacer-right">Assign Host Groups</button>
113+
`<button class="btn btn-secondary spacer spacer-middle" data-bs-toggle="modal" data-bs-target="#edit_dialog_${data}" onclick="editRule(${data})">Edit</button><button id="role_btn_${data}" onclick="assignRule(${data})" class="btn btn-secondary assign_btn spacer spacer-right">Assign Host Enclaves</button>
114114
`;
115115
}
116116

@@ -165,7 +165,7 @@ $(document).ready(function () {
165165
if (response.ok) {
166166
$('#rule-table').DataTable().ajax.reload(null, false);
167167
} else {
168-
alert("Failed to assign host groups.");
168+
alert("Failed to assign host enclaves.");
169169
}
170170
const modal = bootstrap.Modal.getInstance(document.getElementById("assignHostGroupsModal"));
171171
modal.hide();

api/src/main/resources/templates/fragments/assign_rule.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
<!-- Assign Host Groups Modal -->
1+
<!-- Assign Host Enclaves Modal -->
22
<div class="modal fade" id="assignHostGroupsModal" tabindex="-1" aria-labelledby="assignHostGroupsModalLabel" aria-hidden="true">
33
<div class="modal-dialog">
44
<div class="modal-content">
55
<form id="assignHostGroupsForm" method="POST">
66
<div class="modal-header">
7-
<h5 class="modal-title" id="assignHostGroupsModalLabel">Assign Host Groups</h5>
7+
<h5 class="modal-title" id="assignHostGroupsModalLabel">Assign Host Enclaves</h5>
88
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
99
</div>
1010
<div class="modal-body">
@@ -15,17 +15,17 @@ <h5 class="modal-title" id="assignHostGroupsModalLabel">Assign Host Groups</h5>
1515
<label for="assignRuleName" class="form-label">Rule Name</label>
1616
<input type="text" class="form-control" id="assignRuleName" name="assignRuleName" readonly>
1717
</div>
18-
<!-- Host Groups Multi-select -->
18+
<!-- Host Enclaves Multi-select -->
1919
<div class="mb-3">
20-
<label for="hostGroups" class="form-label">Host Groups</label>
20+
<label for="hostGroups" class="form-label">Host Enclaves</label>
2121
<select name="hostGroups" id="hostGroups" class="form-select" multiple>
2222
<!-- Options will be dynamically populated -->
2323
</select>
2424
</div>
2525
</div>
2626
<div class="modal-footer">
2727
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
28-
<button type="submit" class="btn btn-primary">Assign Host Groups</button>
28+
<button type="submit" class="btn btn-primary">Assign Host Enclaves</button>
2929
</div>
3030
<!-- CSRF Token -->
3131

api/src/main/resources/templates/fragments/dashboard/dashboard_cards.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ <h5 class="card-title">Number of assigned hosts</h5>
5050
<i class="fas fa-users card-icon"></i> <!-- Icon for the card -->
5151
</div>
5252
<div class="card-body">
53-
<h5 class="card-title">Number of Host Groups</h5>
53+
<h5 class="card-title">Number of Host Enclaves</h5>
5454
<p class="card-text"><span id="assigned-sgs"></span></p>
5555
</div>
5656
</div>

api/src/main/resources/templates/fragments/ssh_server_card.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<img src="/images/hosts_medium.png" alt="Terminal Icon" class="card-image">
66
</div>
77
<div class="card-content">
8-
<h3 class="card-title">Host Groups</h3>
8+
<h3 class="card-title">Host Enclaves</h3>
99
<div class="card-stats">
1010
<div class="card-stat">
1111
<span>Assigned Systems:</span>

0 commit comments

Comments
 (0)