Skip to content

Commit

Permalink
#124 Use separate search query on THEN/AND/OR rules
Browse files Browse the repository at this point in the history
  • Loading branch information
VincentD06 committed Jun 24, 2024
1 parent 9fd03fb commit dca347e
Show file tree
Hide file tree
Showing 15 changed files with 67 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ private GetDataAlertRule constructDataAlertRule(AlertRule alert) {
alertRuleStream2 = this.constructAlertRuleStream(conditions2);
isDisabled = this.isDisabled(conditions);
eventIdentifier2 = pattern.eventIdentifier2();
completeParametersConditionForDisjunction(parametersCondition, this.eventDefinitionService.getEventDefinition(eventIdentifier2));
} else if (alertPattern instanceof AggregationAlertPattern pattern) {
event = this.eventDefinitionService.getEventDefinition(pattern.eventIdentifier());
parametersCondition = getConditionParameters(event);
Expand All @@ -192,19 +193,10 @@ private GetDataAlertRule constructDataAlertRule(AlertRule alert) {

String eventIdentifier = null;
String description = null;
String searchQuery = null;
if (event.isPresent()) {
EventDefinitionDto eventDefinitionDto = event.get();
eventIdentifier = eventDefinitionDto.id();
description = eventDefinitionDto.description();
if(eventDefinitionDto.config() != null) {
if(eventDefinitionDto.config() instanceof AggregationEventProcessorConfig) {
searchQuery = ((AggregationEventProcessorConfig) eventDefinitionDto.config()).query();
}
if(eventDefinitionDto.config() instanceof CorrelationCountProcessorConfig) {
searchQuery = ((CorrelationCountProcessorConfig) eventDefinitionDto.config()).searchQuery();
}
}
}

return GetDataAlertRule.create(alert.getTitle(),
Expand All @@ -217,7 +209,6 @@ private GetDataAlertRule constructDataAlertRule(AlertRule alert) {
lastModified,
isDisabled,
description,
searchQuery,
alert.getAlertType(),
parametersCondition,
alertRuleStream,
Expand All @@ -231,6 +222,12 @@ private Map<String, Object> getConditionParameters(Optional<EventDefinitionDto>
return this.conversions.getConditionParameters(event.get().config());
}

private void completeParametersConditionForDisjunction(Map<String, Object> configParameters, Optional<EventDefinitionDto> event) {
if (event.isPresent()) {
configParameters.put("additional_search_query", ((AggregationEventProcessorConfig) event.get().config()).query());
}
}

@GET
@Timed
@ApiOperation(value = "Lists all existing alerts")
Expand Down Expand Up @@ -399,10 +396,9 @@ private AlertPattern createAlertPattern(String notificationIdentifier, AlertRule
return createDisjunctionAlertPattern(notificationIdentifier, request, alertTitle, userContext, userName, conditions);
default:
String description = request.getDescription();
String searchQuery = request.getSearchQuery();
Map<String, Object> conditionParameters = request.conditionParameters();
String streamIdentifier = conditions.outputStreamIdentifier();
EventProcessorConfig configuration1 = this.conversions.createEventConfiguration(alertType, conditionParameters, streamIdentifier, searchQuery);
EventProcessorConfig configuration1 = this.conversions.createEventConfiguration(alertType, conditionParameters, streamIdentifier);
String eventIdentifier = this.eventDefinitionService.createEvent(alertTitle, description, notificationIdentifier, configuration1, userContext);

return AggregationAlertPattern.builder().conditions(conditions).eventIdentifier(eventIdentifier).build();
Expand All @@ -411,15 +407,14 @@ private AlertPattern createAlertPattern(String notificationIdentifier, AlertRule

private DisjunctionAlertPattern createDisjunctionAlertPattern(String notificationIdentifier, AlertRuleRequest request, String alertTitle, UserContext userContext, String userName, TriggeringConditions conditions) throws ValidationException {
String description = request.getDescription();
String searchQuery = request.getSearchQuery();
Map<String, Object> conditionParameters = request.conditionParameters();

TriggeringConditions conditions2 = createTriggeringConditions(request.getSecondStream(), alertTitle + "#2", userName);
String streamIdentifier = conditions.outputStreamIdentifier();
EventProcessorConfig configuration = this.conversions.createAggregationCondition(streamIdentifier, searchQuery, conditionParameters);
EventProcessorConfig configuration = this.conversions.createAggregationCondition(streamIdentifier, conditionParameters);
String eventIdentifier = this.eventDefinitionService.createEvent(alertTitle, description, notificationIdentifier, configuration, userContext);
String streamIdentifier2 = conditions2.outputStreamIdentifier();
EventProcessorConfig configuration2 = this.conversions.createAggregationCondition(streamIdentifier2, searchQuery, conditionParameters);
EventProcessorConfig configuration2 = this.conversions.createAggregationCondition(streamIdentifier2, conditionParameters, true);
String eventIdentifier2 = this.eventDefinitionService.createEvent(alertTitle + "#2", description, notificationIdentifier, configuration2, userContext);

return DisjunctionAlertPattern.builder()
Expand All @@ -429,14 +424,13 @@ private DisjunctionAlertPattern createDisjunctionAlertPattern(String notificatio

private CorrelationAlertPattern createCorrelationAlertPattern(String notificationIdentifier, AlertRuleRequest request, String alertTitle, UserContext userContext, String userName, TriggeringConditions conditions) throws ValidationException {
String description = request.getDescription();
String searchQuery = request.getSearchQuery();
AlertType alertType = request.getConditionType();
Map<String, Object> conditionParameters = request.conditionParameters();

TriggeringConditions conditions2 = createTriggeringConditions(request.getSecondStream(), alertTitle + "#2", userName);
String streamIdentifier = conditions.outputStreamIdentifier();
String streamIdentifier2 = conditions2.outputStreamIdentifier();
EventProcessorConfig configuration = this.conversions.createCorrelationCondition(alertType, streamIdentifier, streamIdentifier2, searchQuery, conditionParameters);
EventProcessorConfig configuration = this.conversions.createCorrelationCondition(alertType, streamIdentifier, streamIdentifier2, conditionParameters);
String eventIdentifier = this.eventDefinitionService.createEvent(alertTitle, description, notificationIdentifier, configuration, userContext);
return CorrelationAlertPattern.builder().conditions1(conditions).conditions2(conditions2).eventIdentifier(eventIdentifier).build();
}
Expand All @@ -462,7 +456,7 @@ private AlertPattern updateAlertPattern(AlertPattern previousAlertPattern, Strin

String streamIdentifier = conditions.outputStreamIdentifier();
String streamIdentifier2 = conditions2.outputStreamIdentifier();
EventProcessorConfig configuration = this.conversions.createCorrelationCondition(alertType, streamIdentifier, streamIdentifier2, request.getSearchQuery(), request.conditionParameters());
EventProcessorConfig configuration = this.conversions.createCorrelationCondition(alertType, streamIdentifier, streamIdentifier2, request.conditionParameters());
this.eventDefinitionService.updateEvent(title, request.getDescription(), previousPattern.eventIdentifier(), configuration);

return previousPattern.toBuilder().conditions1(conditions).build();
Expand All @@ -473,19 +467,19 @@ private AlertPattern updateAlertPattern(AlertPattern previousAlertPattern, Strin
TriggeringConditions conditions2 = this.updateTriggeringConditions(previousConditions2, title2, streamConfiguration2, userName);

String streamIdentifier = conditions.outputStreamIdentifier();
EventProcessorConfig configuration = this.conversions.createEventConfiguration(request.getConditionType(), request.conditionParameters(), streamIdentifier, request.getSearchQuery());
EventProcessorConfig configuration = this.conversions.createEventConfiguration(request.getConditionType(), request.conditionParameters(), streamIdentifier);
this.eventDefinitionService.updateEvent(title, request.getDescription(), previousPattern.eventIdentifier1(), configuration);

String streamIdentifier2 = conditions2.outputStreamIdentifier();
EventProcessorConfig configuration2 = this.conversions.createAggregationCondition(streamIdentifier2, request.getSearchQuery(), request.conditionParameters());
EventProcessorConfig configuration2 = this.conversions.createAggregationCondition(streamIdentifier2, request.conditionParameters(), true);
this.eventDefinitionService.updateEvent(title2, request.getDescription(), previousPattern.eventIdentifier2(), configuration2);

return previousPattern.toBuilder().conditions1(conditions).build();
} else if (previousAlertPattern instanceof AggregationAlertPattern previousPattern) {
TriggeringConditions previousConditions = previousPattern.conditions();
TriggeringConditions conditions = updateTriggeringConditions(previousConditions, title, streamConfiguration, userName);
String streamIdentifier = conditions.outputStreamIdentifier();
EventProcessorConfig configuration = this.conversions.createEventConfiguration(request.getConditionType(), request.conditionParameters(), streamIdentifier, request.getSearchQuery());
EventProcessorConfig configuration = this.conversions.createEventConfiguration(request.getConditionType(), request.conditionParameters(), streamIdentifier);
this.eventDefinitionService.updateEvent(title, request.getDescription(), previousPattern.eventIdentifier(), configuration);

return previousPattern.toBuilder().conditions(conditions).build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ public class Conversions {
private static final String THRESHOLD = "threshold";
private static final String THRESHOLD_TYPE_MORE = ">";
private static final String THRESHOLD_TYPE_LESS = "<";
private static final String SEARCH_QUERY = "search_query";
private static final String ADDITIONAL_SEARCH_QUERY = "additional_search_query";

private final FieldRulesUtilities fieldRulesUtilities;

Expand Down Expand Up @@ -135,11 +137,14 @@ Map<String, Object> getConditionParameters(EventProcessorConfig eventConfig) {
parametersCondition.put(TIME, this.convertMillisecondsToMinutes(correlationConfig.searchWithinMs()));
parametersCondition.put(GROUPING_FIELDS, correlationConfig.groupingFields());
parametersCondition.put(GRACE, this.convertMillisecondsToMinutes(correlationConfig.executeEveryMs()));
parametersCondition.put(SEARCH_QUERY, correlationConfig.searchQuery());
parametersCondition.put(ADDITIONAL_SEARCH_QUERY, correlationConfig.additionalSearchQuery());
break;
case "aggregation-v1":
AggregationEventProcessorConfig aggregationConfig = (AggregationEventProcessorConfig) eventConfig;
parametersCondition.put(TIME, this.convertMillisecondsToMinutes(aggregationConfig.searchWithinMs()));
parametersCondition.put(GRACE, this.convertMillisecondsToMinutes(aggregationConfig.executeEveryMs()));
parametersCondition.put(SEARCH_QUERY, aggregationConfig.query());
parametersCondition.put(THRESHOLD, convertThreshold(aggregationConfig.conditions().get().expression().get()));
parametersCondition.put(THRESHOLD_TYPE, aggregationConfig.conditions().get().expression().get().expr());
AggregationSeries series = aggregationConfig.series().get(0);
Expand Down Expand Up @@ -293,7 +298,7 @@ private int accessThreshold(Map<String, Object> conditionParameter) {

// TODO move method to AlertRuleUtils?
// TODO instead of a String, the type could already be a com.airbus_cyber_security.graylog.events.processor.correlation.checks.OrderType
EventProcessorConfig createCorrelationCondition(AlertType type, String streamID, String streamID2, String searchQuery, Map<String, Object> conditionParameter) {
EventProcessorConfig createCorrelationCondition(AlertType type, String streamID, String streamID2, Map<String, Object> conditionParameter) {
OrderType messageOrder;
if (type == AlertType.THEN) {
messageOrder = OrderType.AFTER;
Expand All @@ -302,6 +307,8 @@ EventProcessorConfig createCorrelationCondition(AlertType type, String streamID,
}
String thresholdType = convertThresholdTypeToCorrelation((String) conditionParameter.get(THRESHOLD_TYPE));
String additionalThresholdType = convertThresholdTypeToCorrelation((String) conditionParameter.get(ADDITIONAL_THRESHOLD_TYPE));
String searchQuery = (String) conditionParameter.get(SEARCH_QUERY);
String additionalSearchQuery = (String) conditionParameter.get(ADDITIONAL_SEARCH_QUERY);

int threshold = this.accessThreshold(conditionParameter);

Expand All @@ -322,6 +329,7 @@ EventProcessorConfig createCorrelationCondition(AlertType type, String streamID,
.groupingFields((List<String>) conditionParameter.get(GROUPING_FIELDS))
.comment(Description.COMMENT_ALERT_WIZARD)
.searchQuery(searchQuery)
.additionalSearchQuery(additionalSearchQuery)
.build();
}

Expand All @@ -338,7 +346,11 @@ private Expression<Boolean> createExpressionFromNumberThreshold(String identifie
}
}

public EventProcessorConfig createAggregationCondition(String streamIdentifier, String searchQuery, Map<String, Object> conditionParameter) {
public EventProcessorConfig createAggregationCondition(String streamIdentifier, Map<String, Object> conditionParameter) {
return createAggregationCondition(streamIdentifier, conditionParameter, false);
}

public EventProcessorConfig createAggregationCondition(String streamIdentifier, Map<String, Object> conditionParameter, boolean useAdditionalSearchQuery) {
List<String> groupByFields = (List<String>) conditionParameter.get(GROUPING_FIELDS);
String distinctBy = (String) conditionParameter.get(DISTINCT_BY);

Expand Down Expand Up @@ -367,6 +379,8 @@ public EventProcessorConfig createAggregationCondition(String streamIdentifier,
.expression(expression)
.build();

String searchQuery = useAdditionalSearchQuery ? (String) conditionParameter.get(ADDITIONAL_SEARCH_QUERY) : (String) conditionParameter.get(SEARCH_QUERY);

return AggregationEventProcessorConfig.builder()
.query(searchQuery)
.streams(streams)
Expand Down Expand Up @@ -422,7 +436,7 @@ private Expression<Boolean> createExpressionFromThreshold(String identifier, Str
}
}

public EventProcessorConfig createStatisticalCondition(String streamID, String searchQuery, Map<String, Object> conditionParameter) {
public EventProcessorConfig createStatisticalCondition(String streamID, Map<String, Object> conditionParameter) {
String type = conditionParameter.get(TYPE).toString();
LOG.debug("Begin Stat, type: {}", type);
// TODO extract method to parse searchWithinMs
Expand All @@ -443,6 +457,8 @@ public EventProcessorConfig createStatisticalCondition(String streamID, String s
conditionParameter.get(THRESHOLD_TYPE).toString(),
threshold);

String searchQuery = (String) conditionParameter.get(SEARCH_QUERY);

return AggregationEventProcessorConfig.builder()
.query(searchQuery)
.streams(new HashSet<>(Collections.singleton(streamID)))
Expand All @@ -456,11 +472,11 @@ public EventProcessorConfig createStatisticalCondition(String streamID, String s
.build();
}

public EventProcessorConfig createEventConfiguration(AlertType alertType, Map<String, Object> conditionParameter, String streamIdentifier, String searchQuery) {
public EventProcessorConfig createEventConfiguration(AlertType alertType, Map<String, Object> conditionParameter, String streamIdentifier) {
if (alertType == AlertType.STATISTICAL) {
return createStatisticalCondition(streamIdentifier, searchQuery, conditionParameter);
return createStatisticalCondition(streamIdentifier, conditionParameter);
} else {
return createAggregationCondition(streamIdentifier, searchQuery, conditionParameter);
return createAggregationCondition(streamIdentifier, conditionParameter);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,6 @@ public abstract class AlertRuleRequest {
@NotNull
public abstract String getDescription();

@JsonProperty("search_query")
@NotNull
public abstract String getSearchQuery();

// TODO should be an enum. Possible values: COUNT, GROUP_DISTINCT, STATISTICAL, AND, THEN, OR
@JsonProperty("condition_type")
@NotNull
Expand All @@ -69,11 +65,10 @@ public abstract class AlertRuleRequest {
public static AlertRuleRequest create(@JsonProperty("title") String title,
@JsonProperty("severity") String severity,
@JsonProperty("description") String description,
@JsonProperty("search_query") String searchQuery,
@JsonProperty("condition_type") AlertType alertType,
@JsonProperty("condition_parameters") Map<String, Object> conditionParameters,
@JsonProperty("stream") AlertRuleStream stream,
@JsonProperty("second_stream") AlertRuleStream stream2) {
return new AutoValue_AlertRuleRequest(title, severity, description, searchQuery, alertType, conditionParameters, stream, stream2);
return new AutoValue_AlertRuleRequest(title, severity, description, alertType, conditionParameters, stream, stream2);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,6 @@ public abstract class GetDataAlertRule {
@Nullable
public abstract String getDescription();

@JsonProperty("search_query")
@Nullable
public abstract String getSearchQuery();

@JsonProperty("condition_type")
@Nullable
public abstract AlertType getConditionType();
Expand Down Expand Up @@ -115,12 +111,11 @@ public static GetDataAlertRule create(@JsonProperty("title") String title,
@JsonProperty("created_at") DateTime lastModified,
@JsonProperty("disabled") boolean isDisabled,
@JsonProperty("description") String description,
@JsonProperty("search_query") String searchQuery,
@JsonProperty("condition_type") AlertType alertType,
@JsonProperty("condition_parameters") Map<String, Object> conditionParameters,
@JsonProperty("stream") AlertRuleStream stream,
@JsonProperty("second_stream") AlertRuleStream stream2) {
return new AutoValue_GetDataAlertRule(title, severity, description, searchQuery, alertType, conditionParameters, stream, stream2,
return new AutoValue_GetDataAlertRule(title, severity, description, alertType, conditionParameters, stream, stream2,
eventDefinitionIdentifier, secondEventDefinitionIdentifier, notificationIdentifier, createdAt, creatorUserIdentifier,
lastModified, isDisabled);
}
Expand Down
Loading

0 comments on commit dca347e

Please sign in to comment.