diff --git a/.github/actions/create-bwc-build/action.yaml b/.github/actions/create-bwc-build/action.yaml
index 8960849333..0f9e373b16 100644
--- a/.github/actions/create-bwc-build/action.yaml
+++ b/.github/actions/create-bwc-build/action.yaml
@@ -42,7 +42,7 @@ runs:
uses: gradle/gradle-build-action@v2
with:
cache-disabled: true
- arguments: assemble
+ arguments: :assemble
build-root-directory: ${{ inputs.plugin-branch }}
- id: get-opensearch-version
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 56114de73a..8a9a9bbf56 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -447,7 +447,7 @@ jobs:
- uses: github/codeql-action/init@v3
with:
languages: java
- - run: ./gradlew clean assemble
+ - run: ./gradlew clean :assemble
- uses: github/codeql-action/analyze@v3
build-artifact-names:
diff --git a/.github/workflows/plugin_install.yml b/.github/workflows/plugin_install.yml
index da3e240a68..1f28dec592 100644
--- a/.github/workflows/plugin_install.yml
+++ b/.github/workflows/plugin_install.yml
@@ -33,7 +33,7 @@ jobs:
uses: gradle/gradle-build-action@v3
with:
cache-disabled: true
- arguments: assemble
+ arguments: :assemble
# Move and rename the plugin for installation
- name: Move and rename the plugin for installation
diff --git a/checkstyle/checkstyle.xml b/checkstyle/checkstyle.xml
index a9c1a8f765..7fe4a703de 100644
--- a/checkstyle/checkstyle.xml
+++ b/checkstyle/checkstyle.xml
@@ -205,12 +205,12 @@
-
-
-
-
-
-
+
+
+
+
+
+
@@ -228,12 +228,12 @@
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/sample-resource-plugin/build.gradle b/sample-resource-plugin/build.gradle
index 1b3670fa7d..ceb5a464fd 100644
--- a/sample-resource-plugin/build.gradle
+++ b/sample-resource-plugin/build.gradle
@@ -86,6 +86,7 @@ sourceSets {
srcDir file('src/integrationTest/java')
compileClasspath += sourceSets.main.output
runtimeClasspath += sourceSets.main.output
+ // TODO How to ensure resource are also on the classpath?
}
resources {
srcDir file('src/integrationTest/resources')
diff --git a/sample-resource-plugin/src/integrationTest/java/org/opensearch/sample/SampleResourcePluginTestHelper.java b/sample-resource-plugin/src/integrationTest/java/org/opensearch/sample/SampleResourcePluginTestHelper.java
index fddaa94940..9f08dcfa17 100644
--- a/sample-resource-plugin/src/integrationTest/java/org/opensearch/sample/SampleResourcePluginTestHelper.java
+++ b/sample-resource-plugin/src/integrationTest/java/org/opensearch/sample/SampleResourcePluginTestHelper.java
@@ -10,7 +10,7 @@
import org.opensearch.test.framework.TestSecurityConfig;
-import static org.opensearch.sample.utils.Constants.SAMPLE_RESOURCE_PLUGIN_PREFIX;
+import static org.opensearch.sample.utils.Constants.SAMPLE_PLUGIN_PREFIX;
/**
* Abstract class for sample resource plugin tests. Provides common constants and utility methods for testing. This class is not intended to be
@@ -35,12 +35,12 @@ public abstract class SampleResourcePluginTestHelper {
)
);
- protected static final String SAMPLE_RESOURCE_CREATE_ENDPOINT = SAMPLE_RESOURCE_PLUGIN_PREFIX + "/create";
- protected static final String SAMPLE_RESOURCE_GET_ENDPOINT = SAMPLE_RESOURCE_PLUGIN_PREFIX + "/get";
- protected static final String SAMPLE_RESOURCE_UPDATE_ENDPOINT = SAMPLE_RESOURCE_PLUGIN_PREFIX + "/update";
- protected static final String SAMPLE_RESOURCE_DELETE_ENDPOINT = SAMPLE_RESOURCE_PLUGIN_PREFIX + "/delete";
- protected static final String SAMPLE_RESOURCE_SHARE_ENDPOINT = SAMPLE_RESOURCE_PLUGIN_PREFIX + "/share";
- protected static final String SAMPLE_RESOURCE_REVOKE_ENDPOINT = SAMPLE_RESOURCE_PLUGIN_PREFIX + "/revoke";
+ protected static final String SAMPLE_RESOURCE_CREATE_ENDPOINT = SAMPLE_PLUGIN_PREFIX + "/create";
+ protected static final String SAMPLE_RESOURCE_GET_ENDPOINT = SAMPLE_PLUGIN_PREFIX + "/get";
+ protected static final String SAMPLE_RESOURCE_UPDATE_ENDPOINT = SAMPLE_PLUGIN_PREFIX + "/update";
+ protected static final String SAMPLE_RESOURCE_DELETE_ENDPOINT = SAMPLE_PLUGIN_PREFIX + "/delete";
+ protected static final String SAMPLE_RESOURCE_SHARE_ENDPOINT = SAMPLE_PLUGIN_PREFIX + "/share";
+ protected static final String SAMPLE_RESOURCE_REVOKE_ENDPOINT = SAMPLE_PLUGIN_PREFIX + "/revoke";
protected static String shareWithPayload(String user) {
return """
diff --git a/sample-resource-plugin/src/integrationTest/java/org/opensearch/sample/secure/SecurePluginTests.java b/sample-resource-plugin/src/integrationTest/java/org/opensearch/sample/secure/SecurePluginTests.java
new file mode 100644
index 0000000000..8eb55b73bd
--- /dev/null
+++ b/sample-resource-plugin/src/integrationTest/java/org/opensearch/sample/secure/SecurePluginTests.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * The OpenSearch Contributors require contributions made to
+ * this file be licensed under the Apache-2.0 license or a
+ * compatible open source license.
+ *
+ */
+package org.opensearch.sample.secure;
+
+import java.util.List;
+import java.util.Map;
+
+import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.opensearch.Version;
+import org.opensearch.core.rest.RestStatus;
+import org.opensearch.painless.PainlessModulePlugin;
+import org.opensearch.plugins.PluginInfo;
+import org.opensearch.sample.SampleResourcePlugin;
+import org.opensearch.security.OpenSearchSecurityPlugin;
+import org.opensearch.test.framework.TestSecurityConfig.AuthcDomain;
+import org.opensearch.test.framework.cluster.ClusterManager;
+import org.opensearch.test.framework.cluster.LocalCluster;
+import org.opensearch.test.framework.cluster.TestRestClient;
+import org.opensearch.test.framework.cluster.TestRestClient.HttpResponse;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
+import static org.opensearch.sample.utils.Constants.SAMPLE_PLUGIN_PREFIX;
+import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED;
+import static org.opensearch.security.support.ConfigConstants.SECURITY_SYSTEM_INDICES_ENABLED_KEY;
+import static org.opensearch.test.framework.TestSecurityConfig.Role.ALL_ACCESS;
+import static org.opensearch.test.framework.TestSecurityConfig.User.USER_ADMIN;
+
+@RunWith(com.carrotsearch.randomizedtesting.RandomizedRunner.class)
+@ThreadLeakScope(ThreadLeakScope.Scope.NONE)
+public class SecurePluginTests {
+
+ public static final AuthcDomain AUTHC_DOMAIN = new AuthcDomain("basic", 0).httpAuthenticatorWithChallenge("basic").backend("internal");
+
+ @ClassRule
+ public static final LocalCluster cluster = new LocalCluster.Builder().clusterManager(ClusterManager.SINGLENODE)
+ .anonymousAuth(false)
+ .authc(AUTHC_DOMAIN)
+ .users(USER_ADMIN)
+ .plugin(PainlessModulePlugin.class)
+ .plugin(
+ new PluginInfo(
+ SampleResourcePlugin.class.getName(),
+ "classpath plugin",
+ "NA",
+ Version.CURRENT,
+ "1.8",
+ SampleResourcePlugin.class.getName(),
+ null,
+ List.of(OpenSearchSecurityPlugin.class.getName()),
+ false
+ )
+ )
+ .nodeSettings(
+ Map.of(
+ SECURITY_RESTAPI_ROLES_ENABLED,
+ List.of("user_" + USER_ADMIN.getName() + "__" + ALL_ACCESS.getName()),
+ SECURITY_SYSTEM_INDICES_ENABLED_KEY,
+ true
+ )
+ )
+ .build();
+
+ @Test
+ public void testRunClusterHealthWithPluginSubject() {
+ try (TestRestClient client = cluster.getRestClient(USER_ADMIN)) {
+ HttpResponse response = client.postJson(SAMPLE_PLUGIN_PREFIX + "/run_action", """
+ {
+ "action": "cluster:monitor/health"
+ }
+ """);
+
+ assertThat(response.getStatusCode(), equalTo(RestStatus.OK.getStatus()));
+ assertThat(response.getBody(), containsString("number_of_nodes"));
+ }
+ }
+
+ @Test
+ public void testRunCreateIndexWithPluginSubject() {
+ try (TestRestClient client = cluster.getRestClient(USER_ADMIN)) {
+ HttpResponse response = client.postJson(SAMPLE_PLUGIN_PREFIX + "/run_action", """
+ {
+ "action": "indices:admin/create",
+ "index": "test-index"
+ }
+ """);
+
+ System.out.println("body: " + response.getBody());
+
+ assertThat(response.getStatusCode(), equalTo(RestStatus.OK.getStatus()));
+ }
+ }
+}
diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/SampleResourcePlugin.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/SampleResourcePlugin.java
index 338f8b9acf..2a3eba7069 100644
--- a/sample-resource-plugin/src/main/java/org/opensearch/sample/SampleResourcePlugin.java
+++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/SampleResourcePlugin.java
@@ -30,8 +30,10 @@
import org.opensearch.core.xcontent.NamedXContentRegistry;
import org.opensearch.env.Environment;
import org.opensearch.env.NodeEnvironment;
+import org.opensearch.identity.PluginSubject;
import org.opensearch.indices.SystemIndexDescriptor;
import org.opensearch.plugins.ActionPlugin;
+import org.opensearch.plugins.IdentityAwarePlugin;
import org.opensearch.plugins.Plugin;
import org.opensearch.plugins.SystemIndexPlugin;
import org.opensearch.repositories.RepositoriesService;
@@ -54,6 +56,10 @@
import org.opensearch.sample.resource.actions.transport.RevokeResourceAccessTransportAction;
import org.opensearch.sample.resource.actions.transport.ShareResourceTransportAction;
import org.opensearch.sample.resource.actions.transport.UpdateResourceTransportAction;
+import org.opensearch.sample.secure.actions.rest.create.SecurePluginAction;
+import org.opensearch.sample.secure.actions.rest.create.SecurePluginRestAction;
+import org.opensearch.sample.secure.actions.transport.SecurePluginTransportAction;
+import org.opensearch.sample.utils.RunAsSubjectClient;
import org.opensearch.script.ScriptService;
import org.opensearch.threadpool.ThreadPool;
import org.opensearch.transport.client.Client;
@@ -68,13 +74,12 @@
* It uses ".sample_resource_sharing_plugin" index to manage its resources, and exposes few REST APIs that manage CRUD operations on sample resources.
*
*/
-public class SampleResourcePlugin extends Plugin implements ActionPlugin, SystemIndexPlugin {
+public class SampleResourcePlugin extends Plugin implements ActionPlugin, SystemIndexPlugin, IdentityAwarePlugin {
private static final Logger log = LogManager.getLogger(SampleResourcePlugin.class);
- private boolean isResourceSharingEnabled = false;
- public SampleResourcePlugin(final Settings settings) {
- isResourceSharingEnabled = settings.getAsBoolean(OPENSEARCH_RESOURCE_SHARING_ENABLED, OPENSEARCH_RESOURCE_SHARING_ENABLED_DEFAULT);
- }
+ private RunAsSubjectClient pluginClient;
+
+ public SampleResourcePlugin() {}
@Override
public Collection