Skip to content
Open
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 @@ -61,6 +61,7 @@
import org.opensearch.securityanalytics.action.GetCorrelationAlertsAction;
import org.opensearch.securityanalytics.action.GetDetectorAction;
import org.opensearch.securityanalytics.action.GetFindingsAction;
import org.opensearch.securityanalytics.action.GetRuleAction;
import org.opensearch.securityanalytics.action.GetIndexMappingsAction;
import org.opensearch.securityanalytics.action.GetMappingsViewAction;
import org.opensearch.securityanalytics.action.IndexCorrelationRuleAction;
Expand Down Expand Up @@ -106,6 +107,7 @@
import org.opensearch.securityanalytics.resthandler.RestGetFindingsAction;
import org.opensearch.securityanalytics.resthandler.RestGetIndexMappingsAction;
import org.opensearch.securityanalytics.resthandler.RestGetMappingsViewAction;
import org.opensearch.securityanalytics.resthandler.RestGetRuleAction;
import org.opensearch.securityanalytics.resthandler.RestIndexCorrelationRuleAction;
import org.opensearch.securityanalytics.resthandler.RestIndexCustomLogTypeAction;
import org.opensearch.securityanalytics.resthandler.RestIndexDetectorAction;
Expand Down Expand Up @@ -190,6 +192,7 @@
import org.opensearch.securityanalytics.transport.TransportGetFindingsAction;
import org.opensearch.securityanalytics.transport.TransportGetIndexMappingsAction;
import org.opensearch.securityanalytics.transport.TransportGetMappingsViewAction;
import org.opensearch.securityanalytics.transport.TransportGetRuleAction;
import org.opensearch.securityanalytics.transport.TransportIndexCorrelationRuleAction;
import org.opensearch.securityanalytics.transport.TransportIndexCustomLogTypeAction;
import org.opensearch.securityanalytics.transport.TransportIndexDetectorAction;
Expand Down Expand Up @@ -367,6 +370,7 @@ public List<RestHandler> getRestHandlers(Settings settings,
new RestGetFindingsAction(),
new RestGetMappingsViewAction(),
new RestGetAlertsAction(),
new RestGetRuleAction(),
new RestGetThreatIntelAlertsAction(),
new RestUpdateThreatIntelAlertsStatusAction(),
new RestIndexRuleAction(),
Expand Down Expand Up @@ -526,6 +530,7 @@ public List<Setting<?>> getSettings() {
new ActionPlugin.ActionHandler<>(GetDetectorAction.INSTANCE, TransportGetDetectorAction.class),
new ActionPlugin.ActionHandler<>(SearchDetectorAction.INSTANCE, TransportSearchDetectorAction.class),
new ActionPlugin.ActionHandler<>(GetFindingsAction.INSTANCE, TransportGetFindingsAction.class),
new ActionPlugin.ActionHandler<>(GetRuleAction.INSTANCE, TransportGetRuleAction.class),
new ActionPlugin.ActionHandler<>(GetAlertsAction.INSTANCE, TransportGetAlertsAction.class),
new ActionPlugin.ActionHandler<>(IndexRuleAction.INSTANCE, TransportIndexRuleAction.class),
new ActionPlugin.ActionHandler<>(SearchRuleAction.INSTANCE, TransportSearchRuleAction.class),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/
package org.opensearch.securityanalytics.action;

import org.opensearch.action.ActionType;

public class GetRuleAction extends ActionType<GetRuleResponse> {

public static final GetRuleAction INSTANCE = new GetRuleAction();
public static final String NAME = "cluster:admin/opensearch/securityanalytics/rule/get";

public GetRuleAction() {
super(NAME, GetRuleResponse::new);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/
package org.opensearch.securityanalytics.action;

import org.opensearch.action.ActionRequest;
import org.opensearch.action.ActionRequestValidationException;
import org.opensearch.core.common.io.stream.StreamInput;
import org.opensearch.core.common.io.stream.StreamOutput;

import java.io.IOException;
import java.util.Locale;

import static org.opensearch.action.ValidateActions.addValidationError;

public class GetRuleRequest extends ActionRequest {

private String ruleId;
private Boolean isPrepackaged;
private Long version;

public static final String RULE_ID = "ruleID";
public static final String IS_PREPACKAGED = "pre_packaged";

public GetRuleRequest(String ruleId, Boolean isPrepackaged, Long version) {
super();
this.ruleId = ruleId;
this.isPrepackaged = isPrepackaged;
this.version = version;
}

public GetRuleRequest(StreamInput sin) throws IOException {
this(sin.readString(),
sin.readBoolean(),
sin.readLong());
}

@Override
public ActionRequestValidationException validate() {
ActionRequestValidationException validationException = null;
if (ruleId == null || ruleId.length() == 0 || isPrepackaged) {
validationException = addValidationError(String.format(Locale.getDefault(), "%s is missing", RULE_ID), validationException);
}
return validationException;
}

@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeString(ruleId);
out.writeLong(version);
}

public String getRuleId() {
return ruleId;
}

public Boolean isPrepackaged() {
return isPrepackaged;
}

public Long getVersion() {
return version;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/
package org.opensearch.securityanalytics.action;

import org.opensearch.core.action.ActionResponse;
import org.opensearch.core.common.io.stream.StreamInput;
import org.opensearch.core.common.io.stream.StreamOutput;
import org.opensearch.core.xcontent.ToXContentObject;
import org.opensearch.core.xcontent.XContentBuilder;
import org.opensearch.core.rest.RestStatus;
import org.opensearch.securityanalytics.model.Rule;

import java.io.IOException;

import static org.opensearch.securityanalytics.util.RestHandlerUtils._ID;
import static org.opensearch.securityanalytics.util.RestHandlerUtils._VERSION;

public class GetRuleResponse extends ActionResponse implements ToXContentObject {

private String id;
private Long version;
private RestStatus status;
private Rule rule;

public GetRuleResponse(String id, Long version, RestStatus status, Rule rule) {
super();
this.id = id;
this.version = version;
this.status = status;
this.rule = rule;
}

public GetRuleResponse(StreamInput sin) throws IOException {
this(sin.readString(),
sin.readLong(),
sin.readEnum(RestStatus.class),
sin.readBoolean()? Rule.readFrom(sin): null);
}

@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeString(id);
out.writeLong(version);
out.writeEnum(status);
if (rule != null) {
out.writeBoolean(true);
rule.writeTo(out);
} else {
out.writeBoolean(false);
}
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject()
.field(_ID, id)
.field(_VERSION, version);
builder.startObject("rule")
.field(Rule.TITLE, rule.getTitle())
.field(Rule.CATEGORY, rule.getCategory())
.field(Rule.LOG_SOURCE, rule.getLogSource())
.field(Rule.DESCRIPTION, rule.getDescription())
.field(Rule.TAGS, rule.getTags())
.field(Rule.REFERENCES, rule.getReferences())
.field(Rule.LEVEL, rule.getLevel())
.field(Rule.FALSE_POSITIVES, rule.getFalsePositives())
.field(Rule.AUTHOR, rule.getAuthor())
.field(Rule.STATUS, rule.getStatus())
.field(Rule.LAST_UPDATE_TIME_FIELD, rule.getDate())
.field(Rule.QUERIES, rule.getQueries())
.field(Rule.RULE, rule.getRule())
.endObject();
return builder.endObject();
}

public String getId() {
return id;
}

public Long getVersion() {
return version;
}

public RestStatus getStatus() {
return status;
}

public Rule getRule() {
return rule;
}
}
13 changes: 6 additions & 7 deletions src/main/java/org/opensearch/securityanalytics/model/Rule.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import org.opensearch.securityanalytics.rules.backend.OSQueryBackend.AggregationQueries;
import org.opensearch.securityanalytics.rules.condition.ConditionItem;
import org.opensearch.securityanalytics.rules.exceptions.SigmaConditionError;
import org.opensearch.securityanalytics.rules.exceptions.CompositeSigmaErrors;
import org.opensearch.securityanalytics.rules.objects.SigmaCondition;
import org.opensearch.securityanalytics.rules.objects.SigmaRule;

Expand All @@ -33,11 +32,6 @@
import java.util.Objects;
import java.util.stream.Collectors;

import static org.opensearch.securityanalytics.model.Detector.LAST_UPDATE_TIME_FIELD;
import static org.opensearch.securityanalytics.model.Detector.NO_ID;
import static org.opensearch.securityanalytics.model.Detector.NO_VERSION;


public class Rule implements Writeable, ToXContentObject {

private static final Logger log = LogManager.getLogger(Rule.class);
Expand All @@ -56,15 +50,20 @@ public class Rule implements Writeable, ToXContentObject {
public static final String AUTHOR = "author";
public static final String STATUS = "status";

private static final String QUERIES = "queries";
public static final String QUERIES = "queries";
public static final String QUERY_FIELD_NAMES = "query_field_names";

public static final String RULE = "rule";

public static final String LAST_UPDATE_TIME_FIELD = "last_update_time";

public static final String PRE_PACKAGED_RULES_INDEX = ".opensearch-sap-pre-packaged-rules-config";
public static final String CUSTOM_RULES_INDEX = ".opensearch-sap-custom-rules-config";
public static final String AGGREGATION_QUERIES = "aggregationQueries";

public static final String NO_ID = "";
public static final Long NO_VERSION = 1L;

public static final NamedXContentRegistry.Entry XCONTENT_REGISTRY = new NamedXContentRegistry.Entry(
Rule.class,
new ParseField(CATEGORY),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/
package org.opensearch.securityanalytics.resthandler;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import org.opensearch.rest.BaseRestHandler;
import org.opensearch.rest.RestRequest;
import org.opensearch.rest.action.RestActions;
import org.opensearch.rest.action.RestToXContentListener;
import org.opensearch.transport.client.node.NodeClient;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import static org.opensearch.rest.RestRequest.Method.GET;

import org.opensearch.securityanalytics.action.GetRuleAction;
import org.opensearch.securityanalytics.action.GetRuleRequest;
import org.opensearch.securityanalytics.model.Rule;
import org.opensearch.securityanalytics.SecurityAnalyticsPlugin;

public class RestGetRuleAction extends BaseRestHandler {

@Override
public String getName() {
return "get_rule_action";
}

@Override
public List<Route> routes() {
return List.of(new Route(GET, String.format(Locale.getDefault(), "%s/{%s}", SecurityAnalyticsPlugin.RULE_BASE_URI, GetRuleRequest.RULE_ID)));
}

@Override
protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
String ruleId = request.param(GetRuleRequest.RULE_ID, Rule.NO_ID);
Boolean isPrepackaged = request.paramAsBoolean(GetRuleRequest.IS_PREPACKAGED, false);

if (ruleId == null || ruleId.isEmpty()) {
throw new IllegalArgumentException("missing id");
}

GetRuleRequest req = new GetRuleRequest(ruleId, isPrepackaged, RestActions.parseVersion(request));
return channel -> client.execute(
GetRuleAction.INSTANCE,
req,
new RestToXContentListener<>(channel)
);
}
}
Loading