Skip to content

Commit aedf1f3

Browse files
Adds featureFlag control
Signed-off-by: Darshit Chanpura <dchanp@amazon.com>
1 parent d2a30d8 commit aedf1f3

File tree

6 files changed

+63
-17
lines changed

6 files changed

+63
-17
lines changed

build.gradle

+2-1
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ dependencies {
115115
implementation "org.opensearch:opensearch:${opensearch_version}"
116116
compileOnly "org.opensearch.plugin:opensearch-scripting-painless-spi:${opensearch_version}"
117117
compileOnly "org.opensearch:opensearch-job-scheduler-spi:${job_scheduler_version}"
118+
compileOnly "org.opensearch:opensearch-resource-sharing-spi:${opensearch_build}"
118119
implementation "org.opensearch:common-utils:${common_utils_version}"
119120
implementation "org.opensearch.client:opensearch-rest-client:${opensearch_version}"
120121
compileOnly group: 'com.google.guava', name: 'guava', version:'32.1.3-jre'
@@ -205,7 +206,7 @@ opensearchplugin {
205206
name 'opensearch-anomaly-detection'
206207
description 'OpenSearch anomaly detector plugin'
207208
classname 'org.opensearch.timeseries.TimeSeriesAnalyticsPlugin'
208-
extendedPlugins = ['lang-painless', 'opensearch-job-scheduler']
209+
extendedPlugins = ['lang-painless', 'opensearch-job-scheduler', 'opensearch-security;optional=true']
209210
}
210211

211212
// Handle case where older versions of esplugin doesn't expose the joda time version it uses
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.opensearch.ad.constant;
2+
3+
import org.opensearch.security.spi.resources.ResourceAccessScope;
4+
5+
public enum ADResourceScope implements ResourceAccessScope<ADResourceScope> {
6+
AD_READ_ACCESS("ad_read_access"),
7+
AD_FULL_ACCESS("ad_full_access");
8+
9+
private final String scopeName;
10+
11+
ADResourceScope(String scopeName) {
12+
this.scopeName = scopeName;
13+
}
14+
15+
@Override
16+
public String value() {
17+
return scopeName;
18+
}
19+
}

src/main/java/org/opensearch/ad/transport/IndexAnomalyDetectorTransportAction.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,10 @@ private void resolveUserAndExecute(
115115
Consumer<AnomalyDetector> function
116116
) {
117117
try {
118-
// Check if user has backend roles
119-
// When filter by is enabled, block users creating/updating detectors who do not have backend roles.
120-
if (filterByEnabled) {
118+
// If resource sharing flag is enabled then access evaluation will be performed at DLS level
119+
if (!featureEnabled && filterByEnabled) {
120+
// Check if user has backend roles
121+
// When filter by is enabled, block users creating/updating detectors who do not have backend roles.
121122
String error = checkFilterByBackendRoles(requestedUser);
122123
if (error != null) {
123124
listener.onFailure(new TimeSeriesException(error));
@@ -175,6 +176,8 @@ protected void adExecute(
175176
checkIndicesAndExecute(detector.getIndices(), () -> {
176177
// Don't replace detector's user when update detector
177178
// Github issue: https://github.com/opensearch-project/anomaly-detection/issues/124
179+
// TODO this and similar code should be updated to remove reference to a user
180+
178181
User detectorUser = currentDetector == null ? user : currentDetector.getUser();
179182
IndexAnomalyDetectorActionHandler indexAnomalyDetectorActionHandler = new IndexAnomalyDetectorActionHandler(
180183
clusterService,

src/main/java/org/opensearch/forecast/transport/IndexForecasterTransportAction.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ protected void doExecute(Task task, IndexForecasterRequest request, ActionListen
100100
ActionListener<IndexForecasterResponse> listener = wrapRestActionListener(actionListener, errorMessage);
101101
try (ThreadContext.StoredContext context = client.threadPool().getThreadContext().stashContext()) {
102102
resolveUserAndExecute(
103-
user,
104103
forecasterId,
105104
method,
106105
listener,
@@ -125,9 +124,10 @@ private void resolveUserAndExecute(
125124
// this case, so we can keep current forecaster's user data.
126125
boolean filterByBackendRole = requestedUser == null ? false : filterByEnabled;
127126

128-
// Check if user has backend roles
129-
// When filter by is enabled, block users creating/updating detectors who do not have backend roles.
130-
if (filterByEnabled) {
127+
// If resource sharing flag is enabled then access evaluation will be performed at DLS level
128+
if (!featureEnabled && filterByEnabled) {
129+
// Check if user has backend roles
130+
// When filter by is enabled, block users creating/updating detectors who do not have backend roles.
131131
String error = checkFilterByBackendRoles(requestedUser);
132132
if (error != null) {
133133
listener.onFailure(new IllegalArgumentException(error));

src/main/java/org/opensearch/timeseries/TimeSeriesAnalyticsPlugin.java

+18-1
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@
275275
import org.opensearch.rest.RestController;
276276
import org.opensearch.rest.RestHandler;
277277
import org.opensearch.script.ScriptService;
278+
import org.opensearch.security.spi.resources.ResourceSharingExtension;
278279
import org.opensearch.threadpool.ExecutorBuilder;
279280
import org.opensearch.threadpool.ScalingExecutorBuilder;
280281
import org.opensearch.threadpool.ThreadPool;
@@ -327,7 +328,13 @@
327328
/**
328329
* Entry point of time series analytics plugin.
329330
*/
330-
public class TimeSeriesAnalyticsPlugin extends Plugin implements ActionPlugin, ScriptPlugin, SystemIndexPlugin, JobSchedulerExtension {
331+
public class TimeSeriesAnalyticsPlugin extends Plugin
332+
implements
333+
ActionPlugin,
334+
ScriptPlugin,
335+
SystemIndexPlugin,
336+
JobSchedulerExtension,
337+
ResourceSharingExtension {
331338

332339
private static final Logger LOG = LogManager.getLogger(TimeSeriesAnalyticsPlugin.class);
333340

@@ -1758,4 +1765,14 @@ public void close() {
17581765
}
17591766
}
17601767
}
1768+
1769+
@Override
1770+
public String getResourceType() {
1771+
return "detectors";
1772+
}
1773+
1774+
@Override
1775+
public String getResourceIndex() {
1776+
return CommonName.CONFIG_INDEX;
1777+
}
17611778
}

src/main/java/org/opensearch/timeseries/util/ParseUtils.java

+14-8
Original file line numberDiff line numberDiff line change
@@ -619,17 +619,23 @@ public static <ConfigType extends Config, GetConfigResponseType extends ActionRe
619619
ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser);
620620
@SuppressWarnings("unchecked")
621621
ConfigType config = (ConfigType) Config.parseConfig(configTypeClass, parser);
622-
User resourceUser = config.getUser();
623-
624-
if (!filterByBackendRole || checkUserPermissions(requestUser, resourceUser, configId) || isAdmin(requestUser)) {
622+
if(featureFlagEnabled) {
623+
// Permission evaluation will be done at DLS level in security plugin
625624
function.accept(config);
626625
} else {
627-
logger.debug("User: " + requestUser.getName() + " does not have permissions to access config: " + configId);
628-
listener
629-
.onFailure(
630-
new OpenSearchStatusException(CommonMessages.NO_PERMISSION_TO_ACCESS_CONFIG + configId, RestStatus.FORBIDDEN)
631-
);
626+
User resourceUser = config.getUser();
627+
628+
if (!filterByBackendRole || checkUserPermissions(requestUser, resourceUser, configId) || isAdmin(requestUser)) {
629+
function.accept(config);
630+
} else {
631+
logger.debug("User: " + requestUser.getName() + " does not have permissions to access config: " + configId);
632+
listener
633+
.onFailure(
634+
new OpenSearchStatusException(CommonMessages.NO_PERMISSION_TO_ACCESS_CONFIG + configId, RestStatus.FORBIDDEN)
635+
);
636+
}
632637
}
638+
633639
} catch (Exception e) {
634640
logger.error("Fail to parse user out of config", e);
635641
listener.onFailure(new OpenSearchStatusException(CommonMessages.FAIL_TO_GET_USER_INFO + configId, RestStatus.BAD_REQUEST));

0 commit comments

Comments
 (0)