Skip to content

Commit

Permalink
Added dummy search when creating detector on the given indicies
Browse files Browse the repository at this point in the history
Signed-off-by: Stevan Buzejic <[email protected]>
  • Loading branch information
stevanbuzejic committed Jan 4, 2023
1 parent d5b9b6f commit 30ac233
Show file tree
Hide file tree
Showing 5 changed files with 750 additions and 448 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,31 @@ protected void doExecute(Task task, IndexDetectorRequest request, ActionListener
return;
}

checkIndicesAndExecute(task, request, listener, user);
}

// Checks if user can access the indices and executes detector creation
private void checkIndicesAndExecute(
Task task,
IndexDetectorRequest request,
ActionListener<IndexDetectorResponse> listener,
User user
) {
String [] detectorIndices = request.getDetector().getInputs().stream().flatMap(detectorInput -> detectorInput.getIndices().stream()).toArray(String[]::new);
SearchRequest searchRequest = new SearchRequest(detectorIndices).source(SearchSourceBuilder.searchSource().size(1).query(QueryBuilders.matchAllQuery()));;
StepListener<SearchResponse> checkIndexAccessStep = new StepListener();
client.search(searchRequest, checkIndexAccessStep);
AsyncIndexDetectorsAction asyncAction = new AsyncIndexDetectorsAction(user, task, request, listener);
asyncAction.start();
// Check and execute as a step if the check was successful
checkIndexAccessStep.whenComplete(searchResponse -> asyncAction.start(), e -> {
if(e instanceof OpenSearchStatusException) {
listener.onFailure(SecurityAnalyticsException.wrap(
new OpenSearchStatusException(String.format(Locale.getDefault(), "User doesn't have read permissions for one or more configured index %s", detectorIndices), RestStatus.FORBIDDEN)
));
} else {
listener.onFailure(e);
}
});
}

private void createMonitorFromQueries(String index, List<Pair<String, Rule>> rulesById, Detector detector, ActionListener<List<IndexMonitorResponse>> listener, WriteRequest.RefreshPolicy refreshPolicy) throws SigmaError, IOException {
Expand Down Expand Up @@ -595,7 +618,6 @@ class AsyncIndexDetectorsAction {

void start() {
try {

TransportIndexDetectorAction.this.threadPool.getThreadContext().stashContext();

if (!detectorIndices.detectorIndexExists()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
import static org.opensearch.action.admin.indices.create.CreateIndexRequest.MAPPINGS;
import static org.opensearch.securityanalytics.TestHelpers.sumAggregationTestRule;
import static org.opensearch.securityanalytics.TestHelpers.productIndexAvgAggRule;
import static org.opensearch.securityanalytics.util.RuleTopicIndices.ruleTopicIndexMappings;
import static org.opensearch.securityanalytics.TestHelpers.windowsIndexMapping;
import static org.opensearch.securityanalytics.util.RuleTopicIndices.ruleTopicIndexSettings;

public class SecurityAnalyticsRestTestCase extends OpenSearchRestTestCase {
Expand Down Expand Up @@ -108,6 +108,22 @@ protected void createRuleTopicIndex(String detectorType, String additionalMappin
}
}

protected final List<String> clusterPermissions = List.of(
"cluster:admin/opensearch/securityanalytics/detector/*",
"cluster:admin/opendistro/alerting/alerts/*",
"cluster:admin/opendistro/alerting/findings/*",
"cluster:admin/opensearch/securityanalytics/mapping/*",
"cluster:admin/opensearch/securityanalytics/rule/*"
);

protected final List<String> indexPermissions = List.of(
"indices:admin/mappings/get",
"indices:admin/mapping/put",
"indices:data/read/search"
);

protected static String TEST_HR_ROLE = "hr_role";

protected String createTestIndex(String index, String mapping) throws IOException {
createTestIndex(index, mapping, Settings.EMPTY);
return index;
Expand Down Expand Up @@ -375,6 +391,20 @@ public static SearchResponse executeSearchRequest(String indexName, String query
return SearchResponse.fromXContent(parser);
}

public static SearchResponse executeSearchRequest(RestClient client, String indexName, String queryJson) throws IOException {

Request request = new Request("GET", indexName + "/_search");
request.setJsonEntity(queryJson);
Response response = client.performRequest(request);

XContentParser parser = JsonXContent.jsonXContent.createParser(
new NamedXContentRegistry(ClusterModule.getNamedXWriteables()),
DeprecationHandler.THROW_UNSUPPORTED_OPERATION,
response.getEntity().getContent()
);
return SearchResponse.fromXContent(parser);
}

protected HttpEntity toHttpEntity(Detector detector) throws IOException {
return new StringEntity(toJsonString(detector), ContentType.APPLICATION_JSON);
}
Expand Down Expand Up @@ -997,6 +1027,41 @@ protected RestClient buildClient(Settings settings, HttpHost[] hosts) throws IOE

}

protected void createIndexRole(String name, List<String> clusterPermissions, List<String> indexPermission, List<String> indexPatterns) throws IOException {
Response response;
try {
response = client().performRequest(new Request("GET", String.format(Locale.getDefault(), "/_plugins/_security/api/roles/%s", name)));
} catch (ResponseException ex) {
response = ex.getResponse();
}
// Role already exists
if(response.getStatusLine().getStatusCode() == RestStatus.OK.getStatus()) {
return;
}

Request request = new Request("PUT", String.format(Locale.getDefault(), "/_plugins/_security/api/roles/%s", name));
String clusterPermissionsStr = clusterPermissions.stream().map(p -> "\"" + p + "\"").collect(Collectors.joining(","));
String indexPermissionsStr = indexPermission.stream().map(p -> "\"" + p + "\"").collect(Collectors.joining(","));
String indexPatternsStr = indexPatterns.stream().map(p -> "\"" + p + "\"").collect(Collectors.joining(","));

String entity = "{\n" +
"\"cluster_permissions\": [\n" +
"" + clusterPermissionsStr + "\n" +
"], \n" +
"\"index_permissions\": [\n" +
"{" +
"\"fls\": [], " +
"\"masked_fields\": [], " +
"\"allowed_actions\": [" + indexPermissionsStr + "], " +
"\"index_patterns\": [" + indexPatternsStr + "]" +
"}" +
"], " +
"\"tenant_permissions\": []" +
"}";

request.setJsonEntity(entity);
client().performRequest(request);
}

protected void createCustomRole(String name, String clusterPermissions) throws IOException {
Request request = new Request("PUT", String.format(Locale.getDefault(), "/_plugins/_security/api/roles/%s", name));
Expand All @@ -1009,7 +1074,7 @@ protected void createCustomRole(String name, String clusterPermissions) throws I
client().performRequest(request);
}

protected void createUser(String name, String passwd, String[] backendRoles) throws IOException {
public void createUser(String name, String passwd, String[] backendRoles) throws IOException {
Request request = new Request("PUT", String.format(Locale.getDefault(), "/_plugins/_security/api/internalusers/%s", name));
String broles = String.join(",", backendRoles);
//String roles = String.join(",", customRoles);
Expand Down Expand Up @@ -1048,19 +1113,46 @@ protected void createUserWithDataAndCustomRole(String userName, String userPass
createUserRolesMapping(roleName, users);
}

protected void createUserWithData(String userName, String userPasswd, String roleName, String[] backendRoles ) throws IOException {
protected void createUserWithDataAndCustomRole(String userName, String userPasswd, String roleName, String[] backendRoles, List<String> clusterPermissions, List<String> indexPermissions, List<String> indexPatterns) throws IOException {
String[] users = {userName};
createUser(userName, userPasswd, backendRoles);
createIndexRole(roleName, clusterPermissions, indexPermissions, indexPatterns);
createUserRolesMapping(roleName, users);
}

protected void createUserWithData(String userName, String userPasswd, String roleName, String[] backendRoles ) throws IOException {
String[] users = {userName};
createUser(userName, userPasswd, backendRoles);
createUserRolesMapping(roleName, users);
}

public void createUserWithTestData(String user, String index, String role, String [] backendRoles, List<String> indexPermissions) throws IOException{
String[] users = {user};
createUser(user, user, backendRoles);
createTestIndex(client(), index, windowsIndexMapping(), Settings.EMPTY);
createIndexRole(role, Collections.emptyList(), indexPermissions, List.of(index));
createUserRolesMapping(role, users);
}

protected void deleteUser(String name) throws IOException {
Request request = new Request("DELETE", String.format(Locale.getDefault(), "/_plugins/_security/api/internalusers/%s", name));
client().performRequest(request);
}

protected void tryDeletingRole(String name) throws IOException{
Response response;
try {
response = client().performRequest(new Request("GET", String.format(Locale.getDefault(), "/_plugins/_security/api/roles/%s", name)));
} catch (ResponseException ex) {
response = ex.getResponse();
}
// Role already exists
if(response.getStatusLine().getStatusCode() == RestStatus.OK.getStatus()) {
Request request = new Request("DELETE", String.format(Locale.getDefault(), "/_plugins/_security/api/roles/%s", name));
client().performRequest(request);
}
}

@Override
protected boolean preserveIndicesUponCompletion() {
return true;
Expand Down
Loading

0 comments on commit 30ac233

Please sign in to comment.