Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import com.park.utmstack.domain.chart_builder.types.query.FilterType;
import com.park.utmstack.domain.chart_builder.types.query.OperatorType;
import com.park.utmstack.domain.index_pattern.enums.SystemIndexPattern;
import com.park.utmstack.domain.shared_types.alert.AlertType;
import com.park.utmstack.domain.shared_types.alert.UtmAlert;
import com.park.utmstack.security.SecurityUtils;
import com.park.utmstack.service.UtmAlertLogService;
import com.park.utmstack.service.elasticsearch.ElasticsearchService;
Expand Down Expand Up @@ -87,14 +87,14 @@ public Object logManualAlertStatusChange(ProceedingJoinPoint joinPoint) throws T
Integer status = (Integer) args[1];
String statusObservation = (String) args[2];

List<AlertType> alerts = getAlerts(alertIds);
List<UtmAlert> alerts = getAlerts(alertIds);

joinPoint.proceed();

if (CollectionUtils.isEmpty(alerts))
return null;

for (AlertType alert : alerts) {
for (UtmAlert alert : alerts) {
UtmAlertLog alertLog = new UtmAlertLog();
alertLog.setAlertId(alert.getId());
alertLog.setLogUser(SecurityUtils.getCurrentUserLogin().orElse("system"));
Expand Down Expand Up @@ -146,19 +146,19 @@ public Object logAutomaticAlertStatusChange(ProceedingJoinPoint joinPoint) throw
.size(Constants.LOG_ANALYZER_TOTAL_RESULTS)
.query(query));

HitsMetadata<AlertType> response = elasticsearchService.search(sr, AlertType.class).hits();
HitsMetadata<UtmAlert> response = elasticsearchService.search(sr, UtmAlert.class).hits();

joinPoint.proceed();

if (response.total().value() <= 0)
return null;

List<AlertType> alerts = response.hits().stream().map(Hit::source).collect(Collectors.toList());
List<UtmAlert> alerts = response.hits().stream().map(Hit::source).collect(Collectors.toList());

if (CollectionUtils.isEmpty(alerts))
return null;

for (AlertType alert : alerts) {
for (UtmAlert alert : alerts) {
UtmAlertLog alertLog = new UtmAlertLog();
alertLog.setAlertId(alert.getId());
alertLog.setLogUser("system");
Expand Down Expand Up @@ -197,7 +197,7 @@ public Object logManualAlertTagsChange(ProceedingJoinPoint joinPoint) throws Thr
List alertIds = (List) args[0];
List tags = (List) args[1];

List<AlertType> alerts = getAlerts(alertIds);
List<UtmAlert> alerts = getAlerts(alertIds);

joinPoint.proceed();

Expand All @@ -206,7 +206,7 @@ public Object logManualAlertTagsChange(ProceedingJoinPoint joinPoint) throws Thr

String user = SecurityUtils.getCurrentUserLogin().orElse("system");

for (AlertType alert : alerts) {
for (UtmAlert alert : alerts) {
UtmAlertLog alertLog = new UtmAlertLog();
alertLog.setAlertId(alert.getId());
alertLog.setLogUser(user);
Expand Down Expand Up @@ -247,21 +247,21 @@ public Object logAutomaticAlertTagsChange(ProceedingJoinPoint joinPoint) throws
SearchRequest request = SearchRequest.of(s -> s.query(query)
.size(Constants.LOG_ANALYZER_TOTAL_RESULTS).index(indexPattern));

HitsMetadata<AlertType> hits = elasticsearchService.search(request, AlertType.class).hits();
HitsMetadata<UtmAlert> hits = elasticsearchService.search(request, UtmAlert.class).hits();

joinPoint.proceed();

if (hits.total().value() <= 0)
return null;

List<AlertType> alerts = hits.hits().stream().map(Hit::source).collect(Collectors.toList());
List<UtmAlert> alerts = hits.hits().stream().map(Hit::source).collect(Collectors.toList());

if (CollectionUtils.isEmpty(alerts))
return null;

String user = SecurityUtils.getCurrentUserLogin().orElse("system");

for (AlertType alert : alerts) {
for (UtmAlert alert : alerts) {
UtmAlertLog alertLog = new UtmAlertLog();
alertLog.setAlertId(alert.getId());
alertLog.setLogUser(user);
Expand Down Expand Up @@ -294,7 +294,7 @@ public Object logManualAlertNotesChange(ProceedingJoinPoint joinPoint) throws Th
String alertId = (String) args[0];
String notes = (String) args[1];

List<AlertType> alerts = getAlerts(Collections.singletonList(alertId));
List<UtmAlert> alerts = getAlerts(Collections.singletonList(alertId));

joinPoint.proceed();

Expand All @@ -303,7 +303,7 @@ public Object logManualAlertNotesChange(ProceedingJoinPoint joinPoint) throws Th

String user = SecurityUtils.getCurrentUserLogin().orElse("system");

for (AlertType alert : alerts) {
for (UtmAlert alert : alerts) {
UtmAlertLog alertLog = new UtmAlertLog();
alertLog.setAlertId(alert.getId());
alertLog.setLogUser(user);
Expand Down Expand Up @@ -347,19 +347,19 @@ public Object logConvertToIncident(ProceedingJoinPoint joinPoint) throws Throwab
SearchRequest request = SearchRequest.of(s -> s.size(Constants.LOG_ANALYZER_TOTAL_RESULTS)
.query(query).index(indexPattern));

HitsMetadata<AlertType> hits = elasticsearchService.search(request, AlertType.class).hits();
HitsMetadata<UtmAlert> hits = elasticsearchService.search(request, UtmAlert.class).hits();

joinPoint.proceed();

if (hits.total().value() <= 0)
return null;

List<AlertType> alerts = hits.hits().stream().map(Hit::source).collect(Collectors.toList());
List<UtmAlert> alerts = hits.hits().stream().map(Hit::source).collect(Collectors.toList());

if (CollectionUtils.isEmpty(alerts))
return null;

for (AlertType alert : alerts) {
for (UtmAlert alert : alerts) {
UtmAlertLog alertLog = new UtmAlertLog();
alertLog.setAlertId(alert.getId());
alertLog.setLogUser(incidentCreatedBy);
Expand Down Expand Up @@ -393,14 +393,14 @@ public Object logConvertToIncident(ProceedingJoinPoint joinPoint) throws Throwab
* @return
* @throws Exception
*/
private List<AlertType> getAlerts(List<?> ids) throws Exception {
private List<UtmAlert> getAlerts(List<?> ids) throws Exception {
final String ctx = CLASS_NAME + ".getAlerts";
try {
List<FilterType> filters = new ArrayList<>();
filters.add(new FilterType(Constants.alertIdKeyword, OperatorType.IS_ONE_OF_TERMS, ids));
SearchRequest request = SearchRequest.of(s -> s.query(SearchUtil.toQuery(filters))
.index(Constants.SYS_INDEX_PATTERN.get(SystemIndexPattern.ALERTS)));
HitsMetadata<AlertType> hits = elasticsearchService.search(request, AlertType.class).hits();
HitsMetadata<UtmAlert> hits = elasticsearchService.search(request, UtmAlert.class).hits();
if (hits.total().value() <= 0)
return Collections.emptyList();
return hits.hits().stream().map(Hit::source).collect(Collectors.toList());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
package com.park.utmstack.domain.reports.types;

import com.park.utmstack.domain.incident_response.UtmIncidentJob;
import com.park.utmstack.domain.shared_types.alert.AlertType;
import com.park.utmstack.domain.shared_types.alert.UtmAlert;

import java.util.List;

public class IncidentType {
private AlertType incident;
private UtmAlert incident;
private List<UtmIncidentJob> srcResponses;
private List<UtmIncidentJob> destResponses;

public AlertType getIncident() {
public UtmAlert getIncident() {
return incident;
}

public void setIncident(AlertType incident) {
public void setIncident(UtmAlert incident) {
this.incident = incident;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
@JsonIgnoreProperties(ignoreUnknown = true)
@Getter
@Setter
public class AlertType {
public class UtmAlert {
@JsonProperty("@timestamp")
private String timestamp;

Expand Down Expand Up @@ -106,6 +106,10 @@ public class AlertType {
@JsonProperty("logs")
private List<String> logs;

private String assetGroupName;

private Long assetGroupId;

public Instant getTimestampAsInstant() {
if (StringUtils.hasText(timestamp))
return Instant.parse(timestamp);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,10 @@ void updateGroup(@Param("assetIds") List<Long> assetIds,

@Query(nativeQuery = true, value = "select n.asset_name from utm_network_scan n where n.asset_name is not null and n.is_agent is true and n.asset_alive is true and n.asset_status <> 'MISSING' and n.asset_os_platform = :platform")
List<String> findAgentNamesByPlatform(@Param("platform") String platform);

@Query("SELECT ns.assetName, ns.groupId, ag.groupName " +
"FROM UtmNetworkScan ns " +
"JOIN UtmAssetGroup ag ON ns.groupId = ag.id " +
"WHERE ns.groupId IS NOT NULL")
List<Object[]> findAllAssetGroupMappings();
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import com.park.utmstack.domain.application_events.enums.ApplicationEventType;
import com.park.utmstack.domain.incident.UtmIncident;
import com.park.utmstack.domain.mail_sender.MailConfig;
import com.park.utmstack.domain.shared_types.alert.AlertType;
import com.park.utmstack.domain.shared_types.alert.UtmAlert;
import com.park.utmstack.domain.shared_types.LogType;
import com.park.utmstack.service.application_events.ApplicationEventService;
import com.park.utmstack.service.mail_sender.BaseMailSender;
Expand Down Expand Up @@ -250,7 +250,7 @@ public void sendPasswordResetMail(User user) {
}

@Async
public void sendAlertEmail(List<String> emailsTo, AlertType alert, List<LogType> relatedLogs) {
public void sendAlertEmail(List<String> emailsTo, UtmAlert alert, List<LogType> relatedLogs) {
final String ctx = CLASS_NAME + ".sendAlertEmail";
try {
JavaMailSender javaMailSender = getJavaMailSender();
Expand Down Expand Up @@ -289,7 +289,7 @@ public void sendAlertEmail(List<String> emailsTo, AlertType alert, List<LogType>
}

@Async
public void sendIncidentEmail(List<String> emailsTo, List<AlertType> alerts, UtmIncident incident) {
public void sendIncidentEmail(List<String> emailsTo, List<UtmAlert> alerts, UtmIncident incident) {
final String ctx = CLASS_NAME + ".sendIncidentEmail";
try {
JavaMailSender javaMailSender = getJavaMailSender();
Expand Down Expand Up @@ -332,7 +332,7 @@ public void sendIncidentEmail(List<String> emailsTo, List<AlertType> alerts, Utm
* @return ByteArrayResource object with attachment to alert mail
* @throws Exception In case of any error
*/
private ByteArrayResource buildAlertEmailAttachment(Context context, AlertType alert,
private ByteArrayResource buildAlertEmailAttachment(Context context, UtmAlert alert,
List<LogType> relatedLogs) throws Exception {
final String ctx = CLASS_NAME + ".buildAlertEmailAttachment";
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.park.utmstack.service;

import com.park.utmstack.domain.chart_builder.types.query.FilterType;
import com.park.utmstack.domain.shared_types.alert.AlertType;
import com.park.utmstack.domain.shared_types.alert.UtmAlert;
import com.park.utmstack.domain.shared_types.static_dashboard.CardType;
import com.park.utmstack.util.exceptions.DashboardOverviewException;
import com.park.utmstack.util.exceptions.ElasticsearchIndexDocumentUpdateException;
Expand All @@ -26,7 +26,7 @@ void updateStatus(List<String> alertIds, int status, String statusObservation) t

void convertToIncident(List<String> eventIds, String incidentName, Integer incidentId, String incidentSource) throws ElasticsearchIndexDocumentUpdateException;

List<AlertType> getAlertsByIds(List<String> ids) throws UtmElasticsearchException;
List<UtmAlert> getAlertsByIds(List<String> ids) throws UtmElasticsearchException;

void updateStatusAndTag(List<String> alertIds, int status, String statusObservation) throws UtmElasticsearchException,
IOException, ElasticsearchIndexDocumentUpdateException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
import com.park.utmstack.service.application_events.ApplicationEventService;
import com.park.utmstack.service.elasticsearch.ElasticsearchService;
import com.park.utmstack.service.elasticsearch.SearchUtil;
import com.park.utmstack.service.network_scan.AlertAssetGroupService;
import com.park.utmstack.util.AlertUtil;
import com.park.utmstack.util.enums.AlertStatus;
import com.park.utmstack.util.events.RulesEvaluationEndEvent;
import com.park.utmstack.web.rest.vm.AlertTagRuleFilterVM;
import lombok.RequiredArgsConstructor;
import org.hibernate.jpa.TypedParameterValue;
import org.hibernate.type.BooleanType;
import org.hibernate.type.LongType;
Expand All @@ -38,6 +40,7 @@
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

Expand All @@ -46,6 +49,7 @@
*/
@Service
@Transactional
@RequiredArgsConstructor
public class UtmAlertTagRuleService {

private final Logger log = LoggerFactory.getLogger(UtmAlertTagRuleService.class);
Expand All @@ -58,22 +62,8 @@ public class UtmAlertTagRuleService {
private final AlertPointcut alertPointcut;
private final UtmAlertTagService alertTagService;
private final ElasticsearchService elasticsearchService;
private final AlertAssetGroupService alertAssetGroupService;

public UtmAlertTagRuleService(UtmAlertTagRuleRepository alertTagRuleRepository,
AlertUtil alertUtil,
ApplicationEventPublisher publisher,
ApplicationEventService eventService,
AlertPointcut alertPointcut,
UtmAlertTagService alertTagService,
ElasticsearchService elasticsearchService) {
this.alertTagRuleRepository = alertTagRuleRepository;
this.alertUtil = alertUtil;
this.publisher = publisher;
this.eventService = eventService;
this.alertPointcut = alertPointcut;
this.alertTagService = alertTagService;
this.elasticsearchService = elasticsearchService;
}

/**
* Save a utmTagRule.
Expand Down Expand Up @@ -148,6 +138,9 @@ public void automaticReview() {
if (alertUtil.countAllAlertsByStatus(AlertStatus.AUTOMATIC_REVIEW.getCode()) == 0)
return;

// Assigning asset groups to alerts in automatic review
this.assignAssetGroupsToReviewAlerts();

// Getting all registered rules
List<UtmAlertTagRule> tagRules = alertTagRuleRepository.findAll();

Expand Down Expand Up @@ -247,4 +240,61 @@ private void applyTagRule(List<UtmAlertTagRule> rules, Instant rulesEvaluationSt
}
}
}


private void assignAssetGroupsToReviewAlerts() {
final String ctx = CLASSNAME + ".assignAssetGroupsToReviewAlerts";
try {

Map<String, Map<String, Object>> assetGroups =
alertAssetGroupService.getAssetGroupsMapForAlerts();

if (assetGroups.isEmpty()) {
log.debug("{}: No asset-group mappings found", ctx);
return;
}

StringBuilder scriptBuilder = new StringBuilder();
scriptBuilder.append("if (ctx._source.containsKey('dataSource') && ctx._source.dataSource != null) {\n");

for (Map.Entry<String, Map<String, Object>> entry : assetGroups.entrySet()) {
String assetName = entry.getKey();
Long groupId = (Long) entry.getValue().get("id");
String groupName = (String) entry.getValue().get("name");

scriptBuilder.append(String.format(
"""
if (ctx._source.dataSource == '%s') {
ctx._source.assetGroupId = %dL;
ctx._source.assetGroupName = '%s';
}
""",
assetName.replace("'", "\\'"), // Escapar comillas simples
groupId,
groupName.replace("'", "\\'")
));
}

scriptBuilder.append("}");
String script = scriptBuilder.toString();


List<FilterType> filters = new ArrayList<>();
filters.add(new FilterType(Constants.alertStatus, OperatorType.IS,
AlertStatus.AUTOMATIC_REVIEW.getCode()));
filters.add(new FilterType("dataSource", OperatorType.IS_NOT, null));

Query query = SearchUtil.toQuery(filters);
String indexPattern = Constants.SYS_INDEX_PATTERN.get(SystemIndexPattern.ALERTS);

elasticsearchService.updateByQuery(query, indexPattern, script);

log.info("{}: Asset groups assigned to {} alerts", ctx, assetGroups.size());

} catch (Exception e) {
String msg = ctx + ": " + e.getMessage();
eventService.createEvent(msg, ApplicationEventType.ERROR);
log.error(msg, e);
}
}
}
Loading