From 561e294d87e57fb6fef680eb5482e9c17ca0bff4 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Mon, 11 Nov 2024 13:23:30 -0500 Subject: [PATCH 01/19] Adds a sample resource plugin to demonstrate resource access control in action Signed-off-by: Darshit Chanpura --- sample-resource-plugin/build.gradle | 166 ++++++++++++++++ .../java/org/opensearch/sample/Resource.java | 19 ++ .../sample/SampleResourcePlugin.java | 182 ++++++++++++++++++ .../sample/SampleResourceScope.java | 33 ++++ .../actions/create/CreateResourceAction.java | 29 +++ .../actions/create/CreateResourceRequest.java | 50 +++++ .../create/CreateResourceResponse.java | 55 ++++++ .../create/CreateResourceRestAction.java | 55 ++++++ .../sample/actions/create/SampleResource.java | 56 ++++++ .../list/ListAccessibleResourcesAction.java | 29 +++ .../list/ListAccessibleResourcesRequest.java | 39 ++++ .../list/ListAccessibleResourcesResponse.java | 46 +++++ .../ListAccessibleResourcesRestAction.java | 44 +++++ .../actions/share/ShareResourceAction.java | 26 +++ .../actions/share/ShareResourceRequest.java | 52 +++++ .../actions/share/ShareResourceResponse.java | 52 +++++ .../share/ShareResourceRestAction.java | 51 +++++ .../verify/VerifyResourceAccessAction.java | 25 +++ .../verify/VerifyResourceAccessRequest.java | 69 +++++++ .../verify/VerifyResourceAccessResponse.java | 52 +++++ .../VerifyResourceAccessRestAction.java | 52 +++++ .../CreateResourceTransportAction.java | 99 ++++++++++ ...istAccessibleResourcesTransportAction.java | 56 ++++++ .../ShareResourceTransportAction.java | 65 +++++++ .../VerifyResourceAccessTransportAction.java | 58 ++++++ .../plugin-metadata/plugin-security.policy | 3 + .../org.opensearch.plugins.ResourcePlugin | 1 + .../test/resources/security/esnode-key.pem | 28 +++ .../src/test/resources/security/esnode.pem | 25 +++ .../src/test/resources/security/kirk-key.pem | 28 +++ .../src/test/resources/security/kirk.pem | 27 +++ .../src/test/resources/security/root-ca.pem | 28 +++ .../src/test/resources/security/sample.pem | 25 +++ .../src/test/resources/security/test-kirk.jks | Bin 0 -> 3766 bytes settings.gradle | 3 + 35 files changed, 1628 insertions(+) create mode 100644 sample-resource-plugin/build.gradle create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/Resource.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/SampleResourcePlugin.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/SampleResourceScope.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceAction.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceRequest.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceResponse.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceRestAction.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/SampleResource.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesAction.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesRequest.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesResponse.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesRestAction.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceAction.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceRequest.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceResponse.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceRestAction.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessAction.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessRequest.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessResponse.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessRestAction.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/transport/CreateResourceTransportAction.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/transport/ListAccessibleResourcesTransportAction.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/transport/ShareResourceTransportAction.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/transport/VerifyResourceAccessTransportAction.java create mode 100644 sample-resource-plugin/src/main/plugin-metadata/plugin-security.policy create mode 100644 sample-resource-plugin/src/main/resources/META-INF/services/org.opensearch.plugins.ResourcePlugin create mode 100644 sample-resource-plugin/src/test/resources/security/esnode-key.pem create mode 100644 sample-resource-plugin/src/test/resources/security/esnode.pem create mode 100644 sample-resource-plugin/src/test/resources/security/kirk-key.pem create mode 100644 sample-resource-plugin/src/test/resources/security/kirk.pem create mode 100644 sample-resource-plugin/src/test/resources/security/root-ca.pem create mode 100644 sample-resource-plugin/src/test/resources/security/sample.pem create mode 100644 sample-resource-plugin/src/test/resources/security/test-kirk.jks diff --git a/sample-resource-plugin/build.gradle b/sample-resource-plugin/build.gradle new file mode 100644 index 0000000000..e9822c1f22 --- /dev/null +++ b/sample-resource-plugin/build.gradle @@ -0,0 +1,166 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +apply plugin: 'opensearch.opensearchplugin' +apply plugin: 'opensearch.testclusters' +apply plugin: 'opensearch.java-rest-test' + +import org.opensearch.gradle.test.RestIntegTestTask + + +opensearchplugin { + name 'opensearch-sample-resource-plugin' + description 'Sample plugin that extends OpenSearch Resource Plugin' + classname 'org.opensearch.sample.SampleResourcePlugin' +} + +ext { + projectSubstitutions = [:] + licenseFile = rootProject.file('LICENSE.txt') + noticeFile = rootProject.file('NOTICE.txt') +} + +repositories { + mavenLocal() + mavenCentral() + maven { url "https://aws.oss.sonatype.org/content/repositories/snapshots" } +} + +dependencies { +} + +def es_tmp_dir = rootProject.file('build/private/es_tmp').absoluteFile +es_tmp_dir.mkdirs() + +File repo = file("$buildDir/testclusters/repo") +def _numNodes = findProperty('numNodes') as Integer ?: 1 + +licenseHeaders.enabled = true +validateNebulaPom.enabled = false +testingConventions.enabled = false +loggerUsageCheck.enabled = false + +javaRestTest.dependsOn(rootProject.assemble) +javaRestTest { + systemProperty 'tests.security.manager', 'false' +} +testClusters.javaRestTest { + testDistribution = 'INTEG_TEST' +} + +task integTest(type: RestIntegTestTask) { + description = "Run tests against a cluster" + testClassesDirs = sourceSets.test.output.classesDirs + classpath = sourceSets.test.runtimeClasspath +} +tasks.named("check").configure { dependsOn(integTest) } + +integTest { + if (project.hasProperty('excludeTests')) { + project.properties['excludeTests']?.replaceAll('\\s', '')?.split('[,;]')?.each { + exclude "${it}" + } + } + systemProperty 'tests.security.manager', 'false' + systemProperty 'java.io.tmpdir', es_tmp_dir.absolutePath + + systemProperty "https", System.getProperty("https") + systemProperty "user", System.getProperty("user") + systemProperty "password", System.getProperty("password") + // Tell the test JVM if the cluster JVM is running under a debugger so that tests can use longer timeouts for + // requests. The 'doFirst' delays reading the debug setting on the cluster till execution time. + doFirst { + // Tell the test JVM if the cluster JVM is running under a debugger so that tests can + // use longer timeouts for requests. + def isDebuggingCluster = getDebug() || System.getProperty("test.debug") != null + systemProperty 'cluster.debug', isDebuggingCluster + // Set number of nodes system property to be used in tests + systemProperty 'cluster.number_of_nodes', "${_numNodes}" + // There seems to be an issue when running multi node run or integ tasks with unicast_hosts + // not being written, the waitForAllConditions ensures it's written + getClusters().forEach { cluster -> + cluster.waitForAllConditions() + } + } + + // The -Dcluster.debug option makes the cluster debuggable; this makes the tests debuggable + if (System.getProperty("test.debug") != null) { + jvmArgs '-agentlib:jdwp=transport=dt_socket,server=n,suspend=y,address=8000' + } + if (System.getProperty("tests.rest.bwcsuite") == null) { + filter { + excludeTestsMatching "org.opensearch.security.sampleextension.bwc.*IT" + } + } +} +project.getTasks().getByName('bundlePlugin').dependsOn(rootProject.tasks.getByName('build')) +Zip bundle = (Zip) project.getTasks().getByName("bundlePlugin"); +Zip rootBundle = (Zip) rootProject.getTasks().getByName("bundlePlugin"); +integTest.dependsOn(bundle) +integTest.getClusters().forEach{c -> { + c.plugin(rootProject.getObjects().fileProperty().value(rootBundle.getArchiveFile())) + c.plugin(project.getObjects().fileProperty().value(bundle.getArchiveFile())) +}} + +testClusters.integTest { + testDistribution = 'INTEG_TEST' + + // Cluster shrink exception thrown if we try to set numberOfNodes to 1, so only apply if > 1 + if (_numNodes > 1) numberOfNodes = _numNodes + // When running integration tests it doesn't forward the --debug-jvm to the cluster anymore + // i.e. we have to use a custom property to flag when we want to debug OpenSearch JVM + // since we also support multi node integration tests we increase debugPort per node + if (System.getProperty("cluster.debug") != null) { + def debugPort = 5005 + nodes.forEach { node -> + node.jvmArgs("-agentlib:jdwp=transport=dt_socket,server=n,suspend=y,address=*:${debugPort}") + debugPort += 1 + } + } + setting 'path.repo', repo.absolutePath +} + +afterEvaluate { + testClusters.integTest.nodes.each { node -> + def plugins = node.plugins + def firstPlugin = plugins.get(0) + if (firstPlugin.provider == project.bundlePlugin.archiveFile) { + plugins.remove(0) + plugins.add(firstPlugin) + } + + node.extraConfigFile("kirk.pem", file("src/test/resources/security/kirk.pem")) + node.extraConfigFile("kirk-key.pem", file("src/test/resources/security/kirk-key.pem")) + node.extraConfigFile("esnode.pem", file("src/test/resources/security/esnode.pem")) + node.extraConfigFile("esnode-key.pem", file("src/test/resources/security/esnode-key.pem")) + node.extraConfigFile("root-ca.pem", file("src/test/resources/security/root-ca.pem")) + node.setting("plugins.security.ssl.transport.pemcert_filepath", "esnode.pem") + node.setting("plugins.security.ssl.transport.pemkey_filepath", "esnode-key.pem") + node.setting("plugins.security.ssl.transport.pemtrustedcas_filepath", "root-ca.pem") + node.setting("plugins.security.ssl.transport.enforce_hostname_verification", "false") + node.setting("plugins.security.ssl.http.enabled", "true") + node.setting("plugins.security.ssl.http.pemcert_filepath", "esnode.pem") + node.setting("plugins.security.ssl.http.pemkey_filepath", "esnode-key.pem") + node.setting("plugins.security.ssl.http.pemtrustedcas_filepath", "root-ca.pem") + node.setting("plugins.security.allow_unsafe_democertificates", "true") + node.setting("plugins.security.allow_default_init_securityindex", "true") + node.setting("plugins.security.authcz.admin_dn", "\n - CN=kirk,OU=client,O=client,L=test,C=de") + node.setting("plugins.security.audit.type", "internal_opensearch") + node.setting("plugins.security.enable_snapshot_restore_privilege", "true") + node.setting("plugins.security.check_snapshot_restore_write_privileges", "true") + node.setting("plugins.security.restapi.roles_enabled", "[\"all_access\", \"security_rest_api_access\"]") + } +} + +run { + doFirst { + // There seems to be an issue when running multi node run or integ tasks with unicast_hosts + // not being written, the waitForAllConditions ensures it's written + getClusters().forEach { cluster -> + cluster.waitForAllConditions() + } + } + useCluster testClusters.integTest +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/Resource.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/Resource.java new file mode 100644 index 0000000000..36e74f1624 --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/Resource.java @@ -0,0 +1,19 @@ +/* + * 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. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +package org.opensearch.sample; + +import org.opensearch.core.common.io.stream.NamedWriteable; +import org.opensearch.core.xcontent.ToXContentFragment; + +public abstract class Resource implements NamedWriteable, ToXContentFragment { + protected abstract String getResourceIndex(); +} 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 new file mode 100644 index 0000000000..74a8378887 --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/SampleResourcePlugin.java @@ -0,0 +1,182 @@ +/* + * 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; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.opensearch.accesscontrol.resources.ResourceService; +import org.opensearch.action.ActionRequest; +import org.opensearch.client.Client; +import org.opensearch.cluster.metadata.IndexNameExpressionResolver; +import org.opensearch.cluster.node.DiscoveryNodes; +import org.opensearch.cluster.service.ClusterService; +import org.opensearch.common.inject.Inject; +import org.opensearch.common.lifecycle.Lifecycle; +import org.opensearch.common.lifecycle.LifecycleComponent; +import org.opensearch.common.lifecycle.LifecycleListener; +import org.opensearch.common.settings.ClusterSettings; +import org.opensearch.common.settings.IndexScopedSettings; +import org.opensearch.common.settings.Settings; +import org.opensearch.common.settings.SettingsFilter; +import org.opensearch.core.action.ActionResponse; +import org.opensearch.core.common.io.stream.NamedWriteableRegistry; +import org.opensearch.core.xcontent.NamedXContentRegistry; +import org.opensearch.env.Environment; +import org.opensearch.env.NodeEnvironment; +import org.opensearch.indices.SystemIndexDescriptor; +import org.opensearch.plugins.ActionPlugin; +import org.opensearch.plugins.Plugin; +import org.opensearch.plugins.ResourcePlugin; +import org.opensearch.plugins.SystemIndexPlugin; +import org.opensearch.repositories.RepositoriesService; +import org.opensearch.rest.RestController; +import org.opensearch.rest.RestHandler; +import org.opensearch.sample.actions.create.CreateResourceAction; +import org.opensearch.sample.actions.create.CreateResourceRestAction; +import org.opensearch.sample.actions.list.ListAccessibleResourcesAction; +import org.opensearch.sample.actions.list.ListAccessibleResourcesRestAction; +import org.opensearch.sample.actions.share.ShareResourceAction; +import org.opensearch.sample.actions.share.ShareResourceRestAction; +import org.opensearch.sample.actions.verify.VerifyResourceAccessAction; +import org.opensearch.sample.actions.verify.VerifyResourceAccessRestAction; +import org.opensearch.sample.transport.CreateResourceTransportAction; +import org.opensearch.sample.transport.ListAccessibleResourcesTransportAction; +import org.opensearch.sample.transport.ShareResourceTransportAction; +import org.opensearch.sample.transport.VerifyResourceAccessTransportAction; +import org.opensearch.script.ScriptService; +import org.opensearch.threadpool.ThreadPool; +import org.opensearch.watcher.ResourceWatcherService; + +/** + * Sample Resource plugin. + * It uses ".sample_resources" index to manage its resources, and exposes a REST API + * + */ +public class SampleResourcePlugin extends Plugin implements ActionPlugin, SystemIndexPlugin, ResourcePlugin { + private static final Logger log = LogManager.getLogger(SampleResourcePlugin.class); + + public static final String RESOURCE_INDEX_NAME = ".sample_resource_sharing_plugin"; + + public final static Map INDEX_SETTINGS = Map.of("index.number_of_shards", 1, "index.auto_expand_replicas", "0-all"); + + private Client client; + + @Override + public Collection createComponents( + Client client, + ClusterService clusterService, + ThreadPool threadPool, + ResourceWatcherService resourceWatcherService, + ScriptService scriptService, + NamedXContentRegistry xContentRegistry, + Environment environment, + NodeEnvironment nodeEnvironment, + NamedWriteableRegistry namedWriteableRegistry, + IndexNameExpressionResolver indexNameExpressionResolver, + Supplier repositoriesServiceSupplier + ) { + this.client = client; + log.info("Loaded SampleResourcePlugin components."); + return Collections.emptyList(); + } + + @Override + public List getRestHandlers( + Settings settings, + RestController restController, + ClusterSettings clusterSettings, + IndexScopedSettings indexScopedSettings, + SettingsFilter settingsFilter, + IndexNameExpressionResolver indexNameExpressionResolver, + Supplier nodesInCluster + ) { + return List.of( + new CreateResourceRestAction(), + new ListAccessibleResourcesRestAction(), + new VerifyResourceAccessRestAction(), + new ShareResourceRestAction() + ); + } + + @Override + public List> getActions() { + return List.of( + new ActionHandler<>(CreateResourceAction.INSTANCE, CreateResourceTransportAction.class), + new ActionHandler<>(ListAccessibleResourcesAction.INSTANCE, ListAccessibleResourcesTransportAction.class), + new ActionHandler<>(ShareResourceAction.INSTANCE, ShareResourceTransportAction.class), + new ActionHandler<>(VerifyResourceAccessAction.INSTANCE, VerifyResourceAccessTransportAction.class) + ); + } + + @Override + public Collection getSystemIndexDescriptors(Settings settings) { + final SystemIndexDescriptor systemIndexDescriptor = new SystemIndexDescriptor(RESOURCE_INDEX_NAME, "Example index with resources"); + return Collections.singletonList(systemIndexDescriptor); + } + + @Override + public String getResourceType() { + return ""; + } + + @Override + public String getResourceIndex() { + return RESOURCE_INDEX_NAME; + } + + @Override + public Collection> getGuiceServiceClasses() { + final List> services = new ArrayList<>(1); + services.add(GuiceHolder.class); + return services; + } + + public static class GuiceHolder implements LifecycleComponent { + + private static ResourceService resourceService; + + @Inject + public GuiceHolder(final ResourceService resourceService) { + GuiceHolder.resourceService = resourceService; + } + + public static ResourceService getResourceService() { + return resourceService; + } + + @Override + public void close() {} + + @Override + public Lifecycle.State lifecycleState() { + return null; + } + + @Override + public void addLifecycleListener(LifecycleListener listener) {} + + @Override + public void removeLifecycleListener(LifecycleListener listener) {} + + @Override + public void start() {} + + @Override + public void stop() {} + + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/SampleResourceScope.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/SampleResourceScope.java new file mode 100644 index 0000000000..90df0d3764 --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/SampleResourceScope.java @@ -0,0 +1,33 @@ +/* + * 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. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +package org.opensearch.sample; + +import org.opensearch.accesscontrol.resources.ResourceAccessScope; + +/** + * This class demonstrates a sample implementation of Basic Access Scopes to fit each plugin's use-case. + * The plugin then uses this scope when seeking access evaluation for a user on a particular resource. + */ +public enum SampleResourceScope implements ResourceAccessScope { + + SAMPLE_FULL_ACCESS("sample_full_access"); + + private final String name; + + SampleResourceScope(String scopeName) { + this.name = scopeName; + } + + public String getName() { + return name; + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceAction.java new file mode 100644 index 0000000000..e7c02278ab --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceAction.java @@ -0,0 +1,29 @@ +/* + * 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.actions.create; + +import org.opensearch.action.ActionType; + +/** + * Action to create a sample resource + */ +public class CreateResourceAction extends ActionType { + /** + * Create sample resource action instance + */ + public static final CreateResourceAction INSTANCE = new CreateResourceAction(); + /** + * Create sample resource action name + */ + public static final String NAME = "cluster:admin/sample-resource-plugin/create"; + + private CreateResourceAction() { + super(NAME, CreateResourceResponse::new); + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceRequest.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceRequest.java new file mode 100644 index 0000000000..b31a4b7f2b --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceRequest.java @@ -0,0 +1,50 @@ +/* + * 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.actions.create; + +import java.io.IOException; + +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 org.opensearch.sample.Resource; + +/** + * Request object for CreateSampleResource transport action + */ +public class CreateResourceRequest extends ActionRequest { + + private final Resource resource; + + /** + * Default constructor + */ + public CreateResourceRequest(Resource resource) { + this.resource = resource; + } + + public CreateResourceRequest(StreamInput in) throws IOException { + this.resource = in.readNamedWriteable(Resource.class); + } + + @Override + public void writeTo(final StreamOutput out) throws IOException { + resource.writeTo(out); + } + + @Override + public ActionRequestValidationException validate() { + return null; + } + + public Resource getResource() { + return this.resource; + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceResponse.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceResponse.java new file mode 100644 index 0000000000..6b966ed08d --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceResponse.java @@ -0,0 +1,55 @@ +/* + * 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.actions.create; + +import java.io.IOException; + +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; + +/** + * Response to a CreateSampleResourceRequest + */ +public class CreateResourceResponse extends ActionResponse implements ToXContentObject { + private final String message; + + /** + * Default constructor + * + * @param message The message + */ + public CreateResourceResponse(String message) { + this.message = message; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(message); + } + + /** + * Constructor with StreamInput + * + * @param in the stream input + */ + public CreateResourceResponse(final StreamInput in) throws IOException { + message = in.readString(); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.field("message", message); + builder.endObject(); + return builder; + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceRestAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceRestAction.java new file mode 100644 index 0000000000..86346cc279 --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceRestAction.java @@ -0,0 +1,55 @@ +/* + * 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.actions.create; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import org.opensearch.client.node.NodeClient; +import org.opensearch.core.xcontent.XContentParser; +import org.opensearch.rest.BaseRestHandler; +import org.opensearch.rest.RestRequest; +import org.opensearch.rest.action.RestToXContentListener; + +import static java.util.Collections.singletonList; +import static org.opensearch.rest.RestRequest.Method.POST; + +public class CreateResourceRestAction extends BaseRestHandler { + + public CreateResourceRestAction() {} + + @Override + public List routes() { + return singletonList(new Route(POST, "/_plugins/sample_resource_sharing/resource")); + } + + @Override + public String getName() { + return "create_sample_resource"; + } + + @Override + public RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + Map source; + try (XContentParser parser = request.contentParser()) { + source = parser.map(); + } + + String name = (String) source.get("name"); + SampleResource resource = new SampleResource(); + resource.setName(name); + final CreateResourceRequest createSampleResourceRequest = new CreateResourceRequest(resource); + return channel -> client.executeLocally( + CreateResourceAction.INSTANCE, + createSampleResourceRequest, + new RestToXContentListener<>(channel) + ); + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/SampleResource.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/SampleResource.java new file mode 100644 index 0000000000..1566abfe69 --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/SampleResource.java @@ -0,0 +1,56 @@ +/* + * 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. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +package org.opensearch.sample.actions.create; + +import java.io.IOException; + +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.xcontent.XContentBuilder; +import org.opensearch.sample.Resource; + +import static org.opensearch.sample.SampleResourcePlugin.RESOURCE_INDEX_NAME; + +public class SampleResource extends Resource { + + private String name; + + public SampleResource() {} + + SampleResource(StreamInput in) throws IOException { + this.name = in.readString(); + } + + @Override + public String getResourceIndex() { + return RESOURCE_INDEX_NAME; + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + return builder.startObject().field("name", name).endObject(); + } + + @Override + public void writeTo(StreamOutput streamOutput) throws IOException { + streamOutput.writeString(name); + } + + @Override + public String getWriteableName() { + return "sample_resource"; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesAction.java new file mode 100644 index 0000000000..b4e9e29e22 --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesAction.java @@ -0,0 +1,29 @@ +/* + * 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.actions.list; + +import org.opensearch.action.ActionType; + +/** + * Action to list sample resources + */ +public class ListAccessibleResourcesAction extends ActionType { + /** + * List sample resource action instance + */ + public static final ListAccessibleResourcesAction INSTANCE = new ListAccessibleResourcesAction(); + /** + * List sample resource action name + */ + public static final String NAME = "cluster:admin/sample-resource-plugin/list"; + + private ListAccessibleResourcesAction() { + super(NAME, ListAccessibleResourcesResponse::new); + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesRequest.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesRequest.java new file mode 100644 index 0000000000..b4c0961774 --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesRequest.java @@ -0,0 +1,39 @@ +/* + * 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.actions.list; + +import java.io.IOException; + +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; + +/** + * Request object for ListSampleResource transport action + */ +public class ListAccessibleResourcesRequest extends ActionRequest { + + public ListAccessibleResourcesRequest() {} + + /** + * Constructor with stream input + * @param in the stream input + * @throws IOException IOException + */ + public ListAccessibleResourcesRequest(final StreamInput in) throws IOException {} + + @Override + public void writeTo(final StreamOutput out) throws IOException {} + + @Override + public ActionRequestValidationException validate() { + return null; + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesResponse.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesResponse.java new file mode 100644 index 0000000000..47a8f88e4e --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesResponse.java @@ -0,0 +1,46 @@ +/* + * 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.actions.list; + +import java.io.IOException; +import java.util.List; + +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; + +/** + * Response to a ListAccessibleResourcesRequest + */ +public class ListAccessibleResourcesResponse extends ActionResponse implements ToXContentObject { + private final List resourceIds; + + public ListAccessibleResourcesResponse(List resourceIds) { + this.resourceIds = resourceIds; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeStringArray(resourceIds.toArray(new String[0])); + } + + public ListAccessibleResourcesResponse(final StreamInput in) throws IOException { + resourceIds = in.readStringList(); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.field("resource-ids", resourceIds); + builder.endObject(); + return builder; + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesRestAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesRestAction.java new file mode 100644 index 0000000000..bb921fce00 --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesRestAction.java @@ -0,0 +1,44 @@ +/* + * 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.actions.list; + +import java.util.List; + +import org.opensearch.client.node.NodeClient; +import org.opensearch.rest.BaseRestHandler; +import org.opensearch.rest.RestRequest; +import org.opensearch.rest.action.RestToXContentListener; + +import static java.util.Collections.singletonList; +import static org.opensearch.rest.RestRequest.Method.GET; + +public class ListAccessibleResourcesRestAction extends BaseRestHandler { + + public ListAccessibleResourcesRestAction() {} + + @Override + public List routes() { + return singletonList(new Route(GET, "/_plugins/sample_resource_sharing/resource")); + } + + @Override + public String getName() { + return "list_sample_resources"; + } + + @Override + public RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) { + final ListAccessibleResourcesRequest listAccessibleResourcesRequest = new ListAccessibleResourcesRequest(); + return channel -> client.executeLocally( + ListAccessibleResourcesAction.INSTANCE, + listAccessibleResourcesRequest, + new RestToXContentListener<>(channel) + ); + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceAction.java new file mode 100644 index 0000000000..d362b1927c --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceAction.java @@ -0,0 +1,26 @@ +/* + * 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.actions.share; + +import org.opensearch.action.ActionType; + +public class ShareResourceAction extends ActionType { + /** + * List sample resource action instance + */ + public static final ShareResourceAction INSTANCE = new ShareResourceAction(); + /** + * List sample resource action name + */ + public static final String NAME = "cluster:admin/sample-resource-plugin/share"; + + private ShareResourceAction() { + super(NAME, ShareResourceResponse::new); + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceRequest.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceRequest.java new file mode 100644 index 0000000000..01866fd516 --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceRequest.java @@ -0,0 +1,52 @@ +/* + * 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.actions.share; + +import java.io.IOException; + +import org.opensearch.accesscontrol.resources.ShareWith; +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; + +public class ShareResourceRequest extends ActionRequest { + + private final String resourceId; + private final ShareWith shareWith; + + public ShareResourceRequest(String resourceId, ShareWith shareWith) { + this.resourceId = resourceId; + this.shareWith = shareWith; + } + + public ShareResourceRequest(StreamInput in) throws IOException { + this.resourceId = in.readString(); + this.shareWith = in.readNamedWriteable(ShareWith.class); + } + + @Override + public void writeTo(final StreamOutput out) throws IOException { + out.writeString(resourceId); + out.writeNamedWriteable(shareWith); + } + + @Override + public ActionRequestValidationException validate() { + return null; + } + + public String getResourceId() { + return resourceId; + } + + public ShareWith getShareWith() { + return shareWith; + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceResponse.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceResponse.java new file mode 100644 index 0000000000..a6a85d206d --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceResponse.java @@ -0,0 +1,52 @@ +/* + * 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.actions.share; + +import java.io.IOException; + +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; + +public class ShareResourceResponse extends ActionResponse implements ToXContentObject { + private final String message; + + /** + * Default constructor + * + * @param message The message + */ + public ShareResourceResponse(String message) { + this.message = message; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(message); + } + + /** + * Constructor with StreamInput + * + * @param in the stream input + */ + public ShareResourceResponse(final StreamInput in) throws IOException { + message = in.readString(); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.field("message", message); + builder.endObject(); + return builder; + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceRestAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceRestAction.java new file mode 100644 index 0000000000..347fb49e68 --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceRestAction.java @@ -0,0 +1,51 @@ +/* + * 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.actions.share; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import org.opensearch.accesscontrol.resources.ShareWith; +import org.opensearch.client.node.NodeClient; +import org.opensearch.core.xcontent.XContentParser; +import org.opensearch.rest.BaseRestHandler; +import org.opensearch.rest.RestRequest; +import org.opensearch.rest.action.RestToXContentListener; + +import static java.util.Collections.singletonList; +import static org.opensearch.rest.RestRequest.Method.GET; + +public class ShareResourceRestAction extends BaseRestHandler { + + public ShareResourceRestAction() {} + + @Override + public List routes() { + return singletonList(new Route(GET, "/_plugins/sample_resource_sharing/share/{resource_id}")); + } + + @Override + public String getName() { + return "share_sample_resources"; + } + + @Override + public RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + Map source; + try (XContentParser parser = request.contentParser()) { + source = parser.map(); + } + + String resourceId = (String) source.get("resource_id"); + ShareWith shareWith = (ShareWith) source.get("share_with"); + final ShareResourceRequest shareResourceRequest = new ShareResourceRequest(resourceId, shareWith); + return channel -> client.executeLocally(ShareResourceAction.INSTANCE, shareResourceRequest, new RestToXContentListener<>(channel)); + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessAction.java new file mode 100644 index 0000000000..1378d561f5 --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessAction.java @@ -0,0 +1,25 @@ +/* + * 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.actions.verify; + +import org.opensearch.action.ActionType; + +/** + * Action to verify resource access for current user + */ +public class VerifyResourceAccessAction extends ActionType { + + public static final VerifyResourceAccessAction INSTANCE = new VerifyResourceAccessAction(); + + public static final String NAME = "cluster:admin/sample-resource-plugin/verify/resource_access"; + + private VerifyResourceAccessAction() { + super(NAME, VerifyResourceAccessResponse::new); + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessRequest.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessRequest.java new file mode 100644 index 0000000000..e9b20118db --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessRequest.java @@ -0,0 +1,69 @@ +/* + * 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.actions.verify; + +import java.io.IOException; + +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; + +public class VerifyResourceAccessRequest extends ActionRequest { + + private final String resourceId; + + private final String sourceIdx; + + private final String scope; + + /** + * Default constructor + */ + public VerifyResourceAccessRequest(String resourceId, String sourceIdx, String scope) { + this.resourceId = resourceId; + this.sourceIdx = sourceIdx; + this.scope = scope; + } + + /** + * Constructor with stream input + * @param in the stream input + * @throws IOException IOException + */ + public VerifyResourceAccessRequest(final StreamInput in) throws IOException { + this.resourceId = in.readString(); + this.sourceIdx = in.readString(); + this.scope = in.readString(); + } + + @Override + public void writeTo(final StreamOutput out) throws IOException { + out.writeString(resourceId); + out.writeString(sourceIdx); + out.writeString(scope); + } + + @Override + public ActionRequestValidationException validate() { + return null; + } + + public String getResourceId() { + return resourceId; + } + + public String getSourceIdx() { + return sourceIdx; + } + + public String getScope() { + return scope; + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessResponse.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessResponse.java new file mode 100644 index 0000000000..660ac03f71 --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessResponse.java @@ -0,0 +1,52 @@ +/* + * 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.actions.verify; + +import java.io.IOException; + +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; + +public class VerifyResourceAccessResponse extends ActionResponse implements ToXContentObject { + private final String message; + + /** + * Default constructor + * + * @param message The message + */ + public VerifyResourceAccessResponse(String message) { + this.message = message; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(message); + } + + /** + * Constructor with StreamInput + * + * @param in the stream input + */ + public VerifyResourceAccessResponse(final StreamInput in) throws IOException { + message = in.readString(); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.field("message", message); + builder.endObject(); + return builder; + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessRestAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessRestAction.java new file mode 100644 index 0000000000..34bfed4e9f --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessRestAction.java @@ -0,0 +1,52 @@ +/* + * 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.actions.verify; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import org.opensearch.client.node.NodeClient; +import org.opensearch.core.xcontent.XContentParser; +import org.opensearch.rest.BaseRestHandler; +import org.opensearch.rest.RestRequest; +import org.opensearch.rest.action.RestToXContentListener; + +import static java.util.Collections.singletonList; +import static org.opensearch.rest.RestRequest.Method.POST; + +public class VerifyResourceAccessRestAction extends BaseRestHandler { + + public VerifyResourceAccessRestAction() {} + + @Override + public List routes() { + return singletonList(new Route(POST, "/_plugins/sample_resource_sharing/verify_resource_access")); + } + + @Override + public String getName() { + return "verify_resource_access"; + } + + @Override + public RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + Map source; + try (XContentParser parser = request.contentParser()) { + source = parser.map(); + } + + String resourceIdx = (String) source.get("resource_idx"); + String sourceIdx = (String) source.get("source_idx"); + String scope = (String) source.get("scope"); + + // final CreateResourceRequest createSampleResourceRequest = new CreateResourceRequest<>(resource); + return channel -> client.executeLocally(VerifyResourceAccessAction.INSTANCE, null, new RestToXContentListener<>(channel)); + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/CreateResourceTransportAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/CreateResourceTransportAction.java new file mode 100644 index 0000000000..8bff7b44a3 --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/CreateResourceTransportAction.java @@ -0,0 +1,99 @@ +/* + * 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.transport; + +import java.io.IOException; +import java.util.List; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.opensearch.accesscontrol.resources.ResourceService; +import org.opensearch.accesscontrol.resources.ResourceSharing; +import org.opensearch.accesscontrol.resources.ShareWith; +import org.opensearch.accesscontrol.resources.SharedWithScope; +import org.opensearch.action.index.IndexRequest; +import org.opensearch.action.index.IndexResponse; +import org.opensearch.action.support.ActionFilters; +import org.opensearch.action.support.HandledTransportAction; +import org.opensearch.action.support.WriteRequest; +import org.opensearch.client.Client; +import org.opensearch.common.inject.Inject; +import org.opensearch.common.util.concurrent.ThreadContext; +import org.opensearch.core.action.ActionListener; +import org.opensearch.core.xcontent.ToXContent; +import org.opensearch.sample.Resource; +import org.opensearch.sample.SampleResourcePlugin; +import org.opensearch.sample.SampleResourceScope; +import org.opensearch.sample.actions.create.CreateResourceAction; +import org.opensearch.sample.actions.create.CreateResourceRequest; +import org.opensearch.sample.actions.create.CreateResourceResponse; +import org.opensearch.tasks.Task; +import org.opensearch.transport.TransportService; + +import static org.opensearch.common.xcontent.XContentFactory.jsonBuilder; +import static org.opensearch.sample.SampleResourcePlugin.RESOURCE_INDEX_NAME; + +/** + * Transport action for CreateSampleResource. + */ +public class CreateResourceTransportAction extends HandledTransportAction { + private static final Logger log = LogManager.getLogger(CreateResourceTransportAction.class); + + private final TransportService transportService; + private final Client nodeClient; + + @Inject + public CreateResourceTransportAction(TransportService transportService, ActionFilters actionFilters, Client nodeClient) { + super(CreateResourceAction.NAME, transportService, actionFilters, CreateResourceRequest::new); + this.transportService = transportService; + this.nodeClient = nodeClient; + } + + @Override + protected void doExecute(Task task, CreateResourceRequest request, ActionListener listener) { + try (ThreadContext.StoredContext ignore = transportService.getThreadPool().getThreadContext().stashContext()) { + createResource(request, listener); + listener.onResponse(new CreateResourceResponse("Resource " + request.getResource() + " created successfully.")); + } catch (Exception e) { + log.info("Failed to create resource", e); + listener.onFailure(e); + } + } + + private void createResource(CreateResourceRequest request, ActionListener listener) { + Resource sample = request.getResource(); + try { + IndexRequest ir = nodeClient.prepareIndex(RESOURCE_INDEX_NAME) + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .setSource(sample.toXContent(jsonBuilder(), ToXContent.EMPTY_PARAMS)) + .request(); + + log.warn("Index Request: {}", ir.toString()); + + ActionListener irListener = getIndexResponseActionListener(listener); + nodeClient.index(ir, irListener); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static ActionListener getIndexResponseActionListener(ActionListener listener) { + SharedWithScope.SharedWithPerScope sharedWithPerScope = new SharedWithScope.SharedWithPerScope(List.of(), List.of(), List.of()); + SharedWithScope sharedWithScope = new SharedWithScope(SampleResourceScope.SAMPLE_FULL_ACCESS.getName(), sharedWithPerScope); + ShareWith shareWith = new ShareWith(List.of(sharedWithScope)); + return ActionListener.wrap(idxResponse -> { + log.info("Created resource: {}", idxResponse.toString()); + ResourceService rs = SampleResourcePlugin.GuiceHolder.getResourceService(); + ResourceSharing sharing = rs.getResourceAccessControlPlugin().shareWith(idxResponse.getId(), idxResponse.getIndex(), shareWith); + log.info("Created resource sharing entry: {}", sharing.toString()); + }, listener::onFailure); + } + +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/ListAccessibleResourcesTransportAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/ListAccessibleResourcesTransportAction.java new file mode 100644 index 0000000000..d56eb6d291 --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/ListAccessibleResourcesTransportAction.java @@ -0,0 +1,56 @@ +/* + * 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.transport; + +import java.util.List; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.opensearch.accesscontrol.resources.ResourceService; +import org.opensearch.action.support.ActionFilters; +import org.opensearch.action.support.HandledTransportAction; +import org.opensearch.common.inject.Inject; +import org.opensearch.core.action.ActionListener; +import org.opensearch.sample.SampleResourcePlugin; +import org.opensearch.sample.actions.list.ListAccessibleResourcesAction; +import org.opensearch.sample.actions.list.ListAccessibleResourcesRequest; +import org.opensearch.sample.actions.list.ListAccessibleResourcesResponse; +import org.opensearch.tasks.Task; +import org.opensearch.transport.TransportService; + +import static org.opensearch.sample.SampleResourcePlugin.RESOURCE_INDEX_NAME; + +/** + * Transport action for ListSampleResource. + */ +public class ListAccessibleResourcesTransportAction extends HandledTransportAction< + ListAccessibleResourcesRequest, + ListAccessibleResourcesResponse> { + private static final Logger log = LogManager.getLogger(ListAccessibleResourcesTransportAction.class); + + @Inject + public ListAccessibleResourcesTransportAction(TransportService transportService, ActionFilters actionFilters) { + super(ListAccessibleResourcesAction.NAME, transportService, actionFilters, ListAccessibleResourcesRequest::new); + } + + @Override + protected void doExecute(Task task, ListAccessibleResourcesRequest request, ActionListener listener) { + try { + ResourceService rs = SampleResourcePlugin.GuiceHolder.getResourceService(); + List resourceIds = rs.getResourceAccessControlPlugin().listAccessibleResourcesInPlugin(RESOURCE_INDEX_NAME); + log.info("Successfully fetched accessible resources for current user"); + listener.onResponse(new ListAccessibleResourcesResponse(resourceIds)); + } catch (Exception e) { + log.info("Failed to list accessible resources for current user: ", e); + listener.onFailure(e); + } + + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/ShareResourceTransportAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/ShareResourceTransportAction.java new file mode 100644 index 0000000000..ccbfc31b78 --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/ShareResourceTransportAction.java @@ -0,0 +1,65 @@ +/* + * 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.transport; + +import java.util.List; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.opensearch.accesscontrol.resources.ResourceService; +import org.opensearch.accesscontrol.resources.ResourceSharing; +import org.opensearch.accesscontrol.resources.ShareWith; +import org.opensearch.action.support.ActionFilters; +import org.opensearch.action.support.HandledTransportAction; +import org.opensearch.common.inject.Inject; +import org.opensearch.core.action.ActionListener; +import org.opensearch.sample.SampleResourcePlugin; +import org.opensearch.sample.actions.share.ShareResourceAction; +import org.opensearch.sample.actions.share.ShareResourceRequest; +import org.opensearch.sample.actions.share.ShareResourceResponse; +import org.opensearch.tasks.Task; +import org.opensearch.transport.TransportService; + +import static org.opensearch.sample.SampleResourcePlugin.RESOURCE_INDEX_NAME; + +/** + * Transport action for CreateSampleResource. + */ +public class ShareResourceTransportAction extends HandledTransportAction { + private static final Logger log = LogManager.getLogger(ShareResourceTransportAction.class); + + @Inject + public ShareResourceTransportAction(TransportService transportService, ActionFilters actionFilters) { + super(ShareResourceAction.NAME, transportService, actionFilters, ShareResourceRequest::new); + } + + @Override + protected void doExecute(Task task, ShareResourceRequest request, ActionListener listener) { + try { + shareResource(request); + listener.onResponse(new ShareResourceResponse("Resource " + request.getResourceId() + " shared successfully.")); + } catch (Exception e) { + listener.onFailure(e); + } + } + + private void shareResource(ShareResourceRequest request) { + try { + ShareWith shareWith = new ShareWith(List.of()); + ResourceService rs = SampleResourcePlugin.GuiceHolder.getResourceService(); + ResourceSharing sharing = rs.getResourceAccessControlPlugin() + .shareWith(request.getResourceId(), RESOURCE_INDEX_NAME, shareWith); + log.info("Shared resource : {} with {}", request.getResourceId(), sharing.toString()); + } catch (Exception e) { + log.info("Failed to share resource {}", request.getResourceId(), e); + throw e; + } + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/VerifyResourceAccessTransportAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/VerifyResourceAccessTransportAction.java new file mode 100644 index 0000000000..947dcec59e --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/VerifyResourceAccessTransportAction.java @@ -0,0 +1,58 @@ +/* + * 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.transport; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.opensearch.accesscontrol.resources.ResourceService; +import org.opensearch.action.support.ActionFilters; +import org.opensearch.action.support.HandledTransportAction; +import org.opensearch.client.Client; +import org.opensearch.common.inject.Inject; +import org.opensearch.core.action.ActionListener; +import org.opensearch.sample.SampleResourcePlugin; +import org.opensearch.sample.actions.verify.VerifyResourceAccessAction; +import org.opensearch.sample.actions.verify.VerifyResourceAccessRequest; +import org.opensearch.sample.actions.verify.VerifyResourceAccessResponse; +import org.opensearch.tasks.Task; +import org.opensearch.transport.TransportService; + +public class VerifyResourceAccessTransportAction extends HandledTransportAction { + private static final Logger log = LogManager.getLogger(VerifyResourceAccessTransportAction.class); + + @Inject + public VerifyResourceAccessTransportAction(TransportService transportService, ActionFilters actionFilters, Client nodeClient) { + super(VerifyResourceAccessAction.NAME, transportService, actionFilters, VerifyResourceAccessRequest::new); + } + + @Override + protected void doExecute(Task task, VerifyResourceAccessRequest request, ActionListener listener) { + try { + ResourceService rs = SampleResourcePlugin.GuiceHolder.getResourceService(); + boolean hasRequestedScopeAccess = rs.getResourceAccessControlPlugin() + .hasPermission(request.getResourceId(), request.getSourceIdx(), request.getScope()); + + StringBuilder sb = new StringBuilder(); + sb.append("User does"); + sb.append(hasRequestedScopeAccess ? " " : " not "); + sb.append("have requested scope "); + sb.append(request.getScope()); + sb.append(" access to "); + sb.append(request.getResourceId()); + + log.info(sb.toString()); + listener.onResponse(new VerifyResourceAccessResponse(sb.toString())); + } catch (Exception e) { + log.info("Failed to check user permissions for resource {}", request.getResourceId(), e); + listener.onFailure(e); + } + } + +} diff --git a/sample-resource-plugin/src/main/plugin-metadata/plugin-security.policy b/sample-resource-plugin/src/main/plugin-metadata/plugin-security.policy new file mode 100644 index 0000000000..a5dfc33a87 --- /dev/null +++ b/sample-resource-plugin/src/main/plugin-metadata/plugin-security.policy @@ -0,0 +1,3 @@ +grant { + permission java.lang.RuntimePermission "getClassLoader"; +}; \ No newline at end of file diff --git a/sample-resource-plugin/src/main/resources/META-INF/services/org.opensearch.plugins.ResourcePlugin b/sample-resource-plugin/src/main/resources/META-INF/services/org.opensearch.plugins.ResourcePlugin new file mode 100644 index 0000000000..1ca89eaf74 --- /dev/null +++ b/sample-resource-plugin/src/main/resources/META-INF/services/org.opensearch.plugins.ResourcePlugin @@ -0,0 +1 @@ +org.opensearch.sample.SampleResourcePlugin \ No newline at end of file diff --git a/sample-resource-plugin/src/test/resources/security/esnode-key.pem b/sample-resource-plugin/src/test/resources/security/esnode-key.pem new file mode 100644 index 0000000000..e90562be43 --- /dev/null +++ b/sample-resource-plugin/src/test/resources/security/esnode-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCm93kXteDQHMAv +bUPNPW5pyRHKDD42XGWSgq0k1D29C/UdyL21HLzTJa49ZU2ldIkSKs9JqbkHdyK0 +o8MO6L8dotLoYbxDWbJFW8bp1w6tDTU0HGkn47XVu3EwbfrTENg3jFu+Oem6a/50 +1SzITzJWtS0cn2dIFOBimTVpT/4Zv5qrXA6Cp4biOmoTYWhi/qQl8d0IaADiqoZ1 +MvZbZ6x76qTrRAbg+UWkpTEXoH1xTc8ndibR7+HP6OTqCKvo1NhE8uP4pY+fWd6b +6l+KLo3IKpfTbAIJXIO+M67FLtWKtttDao94B069skzKk6FPgW/OZh6PRCD0oxOa +vV+ld2SjAgMBAAECggEAQK1+uAOZeaSZggW2jQut+MaN4JHLi61RH2cFgU3COLgo +FIiNjFn8f2KKU3gpkt1It8PjlmprpYut4wHI7r6UQfuv7ZrmncRiPWHm9PB82+ZQ +5MXYqj4YUxoQJ62Cyz4sM6BobZDrjG6HHGTzuwiKvHHkbsEE9jQ4E5m7yfbVvM0O +zvwrSOM1tkZihKSTpR0j2+taji914tjBssbn12TMZQL5ItGnhR3luY8mEwT9MNkZ +xg0VcREoAH+pu9FE0vPUgLVzhJ3be7qZTTSRqv08bmW+y1plu80GbppePcgYhEow +dlW4l6XPJaHVSn1lSFHE6QAx6sqiAnBz0NoTPIaLyQKBgQDZqDOlhCRciMRicSXn +7yid9rhEmdMkySJHTVFOidFWwlBcp0fGxxn8UNSBcXdSy7GLlUtH41W9PWl8tp9U +hQiiXORxOJ7ZcB80uNKXF01hpPj2DpFPWyHFxpDkWiTAYpZl68rOlYujxZUjJIej +VvcykBC2BlEOG9uZv2kxcqLyJwKBgQDEYULTxaTuLIa17wU3nAhaainKB3vHxw9B +Ksy5p3ND43UNEKkQm7K/WENx0q47TA1mKD9i+BhaLod98mu0YZ+BCUNgWKcBHK8c +uXpauvM/pLhFLXZ2jvEJVpFY3J79FSRK8bwE9RgKfVKMMgEk4zOyZowS8WScOqiy +hnQn1vKTJQKBgElhYuAnl9a2qXcC7KOwRsJS3rcKIVxijzL4xzOyVShp5IwIPbOv +hnxBiBOH/JGmaNpFYBcBdvORE9JfA4KMQ2fx53agfzWRjoPI1/7mdUk5RFI4gRb/ +A3jZRBoopgFSe6ArCbnyQxzYzToG48/Wzwp19ZxYrtUR4UyJct6f5n27AoGBAJDh +KIpQQDOvCdtjcbfrF4aM2DPCfaGPzENJriwxy6oEPzDaX8Bu/dqI5Ykt43i/zQrX +GpyLaHvv4+oZVTiI5UIvcVO9U8hQPyiz9f7F+fu0LHZs6f7hyhYXlbe3XFxeop3f +5dTKdWgXuTTRF2L9dABkA2deS9mutRKwezWBMQk5AoGBALPtX0FrT1zIosibmlud +tu49A/0KZu4PBjrFMYTSEWGNJez3Fb2VsJwylVl6HivwbP61FhlYfyksCzQQFU71 ++x7Nmybp7PmpEBECr3deoZKQ/acNHn0iwb0It+YqV5+TquQebqgwK6WCLsMuiYKT +bg/ch9Rhxbq22yrVgWHh6epp +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/sample-resource-plugin/src/test/resources/security/esnode.pem b/sample-resource-plugin/src/test/resources/security/esnode.pem new file mode 100644 index 0000000000..44101f0b37 --- /dev/null +++ b/sample-resource-plugin/src/test/resources/security/esnode.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEPDCCAySgAwIBAgIUaYSlET3nzsotWTrWueVPPh10yLYwDQYJKoZIhvcNAQEL +BQAwgY8xEzARBgoJkiaJk/IsZAEZFgNjb20xFzAVBgoJkiaJk/IsZAEZFgdleGFt +cGxlMRkwFwYDVQQKDBBFeGFtcGxlIENvbSBJbmMuMSEwHwYDVQQLDBhFeGFtcGxl +IENvbSBJbmMuIFJvb3QgQ0ExITAfBgNVBAMMGEV4YW1wbGUgQ29tIEluYy4gUm9v +dCBDQTAeFw0yNDAyMjAxNzAzMjVaFw0zNDAyMTcxNzAzMjVaMFcxCzAJBgNVBAYT +AmRlMQ0wCwYDVQQHDAR0ZXN0MQ0wCwYDVQQKDARub2RlMQ0wCwYDVQQLDARub2Rl +MRswGQYDVQQDDBJub2RlLTAuZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCm93kXteDQHMAvbUPNPW5pyRHKDD42XGWSgq0k1D29C/Ud +yL21HLzTJa49ZU2ldIkSKs9JqbkHdyK0o8MO6L8dotLoYbxDWbJFW8bp1w6tDTU0 +HGkn47XVu3EwbfrTENg3jFu+Oem6a/501SzITzJWtS0cn2dIFOBimTVpT/4Zv5qr +XA6Cp4biOmoTYWhi/qQl8d0IaADiqoZ1MvZbZ6x76qTrRAbg+UWkpTEXoH1xTc8n +dibR7+HP6OTqCKvo1NhE8uP4pY+fWd6b6l+KLo3IKpfTbAIJXIO+M67FLtWKtttD +ao94B069skzKk6FPgW/OZh6PRCD0oxOavV+ld2SjAgMBAAGjgcYwgcMwRwYDVR0R +BEAwPogFKgMEBQWCEm5vZGUtMC5leGFtcGxlLmNvbYIJbG9jYWxob3N0hxAAAAAA +AAAAAAAAAAAAAAABhwR/AAABMAsGA1UdDwQEAwIF4DAdBgNVHSUEFjAUBggrBgEF +BQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU0/qDQaY10jIo +wCjLUpz/HfQXyt8wHwYDVR0jBBgwFoAUF4ffoFrrZhKn1dD4uhJFPLcrAJwwDQYJ +KoZIhvcNAQELBQADggEBAGbij5WyF0dKhQodQfTiFDb73ygU6IyeJkFSnxF67gDz +pQJZKFvXuVBa3cGP5e7Qp3TK50N+blXGH0xXeIV9lXeYUk4hVfBlp9LclZGX8tGi +7Xa2enMvIt5q/Yg3Hh755ZxnDYxCoGkNOXUmnMusKstE0YzvZ5Gv6fcRKFBUgZLh +hUBqIEAYly1EqH/y45APiRt3Nor1yF6zEI4TnL0yNrHw6LyQkUNCHIGMJLfnJQ9L +camMGIXOx60kXNMTigF9oXXwixWAnDM9y3QT8QXA7hej/4zkbO+vIeV/7lGUdkyg +PAi92EvyxmsliEMyMR0VINl8emyobvfwa7oMeWMR+hg= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/sample-resource-plugin/src/test/resources/security/kirk-key.pem b/sample-resource-plugin/src/test/resources/security/kirk-key.pem new file mode 100644 index 0000000000..1949c26139 --- /dev/null +++ b/sample-resource-plugin/src/test/resources/security/kirk-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCVXDgEJQorgfXp +gpY0TgF55bD2xuzxN5Dc9rDfgWxrsOvOloMpd7k6FR71bKWjJi1KptSmM/cDElky +AWYKSfYWGiGxsQ+EQW+6kwCfEOHXQldn+0+JcWqP+osSPjtJfwRvRN5kRqP69MPo +7U0N2kdqenqMWjmG1chDGLRSOEGU5HIBiDxsZtOcvMaJ8b1eaW0lvS+6gFQ80AvB +GBkDDCOHHLtDXBylrZk2CQP8AzxNicIZ4B8G3CG3OHA8+nBtEtxZoIihrrkqlMt+ +b/5N8u8zB0Encew0kdrc4R/2wS//ahr6U+9Siq8T7WsUtGwKj3BJClg6OyDJRhlu +y2gFnxoPAgMBAAECggEAP5TOycDkx+megAWVoHV2fmgvgZXkBrlzQwUG/VZQi7V4 +ZGzBMBVltdqI38wc5MtbK3TCgHANnnKgor9iq02Z4wXDwytPIiti/ycV9CDRKvv0 +TnD2hllQFjN/IUh5n4thHWbRTxmdM7cfcNgX3aZGkYbLBVVhOMtn4VwyYu/Mxy8j +xClZT2xKOHkxqwmWPmdDTbAeZIbSv7RkIGfrKuQyUGUaWhrPslvYzFkYZ0umaDgQ +OAthZew5Bz3OfUGOMPLH61SVPuJZh9zN1hTWOvT65WFWfsPd2yStI+WD/5PU1Doo +1RyeHJO7s3ug8JPbtNJmaJwHe9nXBb/HXFdqb976yQKBgQDNYhpu+MYSYupaYqjs +9YFmHQNKpNZqgZ4ceRFZ6cMJoqpI5dpEMqToFH7tpor72Lturct2U9nc2WR0HeEs +/6tiptyMPTFEiMFb1opQlXF2ae7LeJllntDGN0Q6vxKnQV+7VMcXA0Y8F7tvGDy3 +qJu5lfvB1mNM2I6y/eMxjBuQhwKBgQC6K41DXMFro0UnoO879pOQYMydCErJRmjG +/tZSy3Wj4KA/QJsDSViwGfvdPuHZRaG9WtxdL6kn0w1exM9Rb0bBKl36lvi7o7xv +M+Lw9eyXMkww8/F5d7YYH77gIhGo+RITkKI3+5BxeBaUnrGvmHrpmpgRXWmINqr0 +0jsnN3u0OQKBgCf45vIgItSjQb8zonLz2SpZjTFy4XQ7I92gxnq8X0Q5z3B+o7tQ +K/4rNwTju/sGFHyXAJlX+nfcK4vZ4OBUJjP+C8CTjEotX4yTNbo3S6zjMyGQqDI5 +9aIOUY4pb+TzeUFJX7If5gR+DfGyQubvvtcg1K3GHu9u2l8FwLj87sRzAoGAflQF +RHuRiG+/AngTPnZAhc0Zq0kwLkpH2Rid6IrFZhGLy8AUL/O6aa0IGoaMDLpSWUJp +nBY2S57MSM11/MVslrEgGmYNnI4r1K25xlaqV6K6ztEJv6n69327MS4NG8L/gCU5 +3pEm38hkUi8pVYU7in7rx4TCkrq94OkzWJYurAkCgYATQCL/rJLQAlJIGulp8s6h +mQGwy8vIqMjAdHGLrCS35sVYBXG13knS52LJHvbVee39AbD5/LlWvjJGlQMzCLrw +F7oILW5kXxhb8S73GWcuMbuQMFVHFONbZAZgn+C9FW4l7XyRdkrbR1MRZ2km8YMs +/AHmo368d4PSNRMMzLHw8Q== +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/sample-resource-plugin/src/test/resources/security/kirk.pem b/sample-resource-plugin/src/test/resources/security/kirk.pem new file mode 100644 index 0000000000..36b7e19a75 --- /dev/null +++ b/sample-resource-plugin/src/test/resources/security/kirk.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEmDCCA4CgAwIBAgIUaYSlET3nzsotWTrWueVPPh10yLcwDQYJKoZIhvcNAQEL +BQAwgY8xEzARBgoJkiaJk/IsZAEZFgNjb20xFzAVBgoJkiaJk/IsZAEZFgdleGFt +cGxlMRkwFwYDVQQKDBBFeGFtcGxlIENvbSBJbmMuMSEwHwYDVQQLDBhFeGFtcGxl +IENvbSBJbmMuIFJvb3QgQ0ExITAfBgNVBAMMGEV4YW1wbGUgQ29tIEluYy4gUm9v +dCBDQTAeFw0yNDAyMjAxNzA0MjRaFw0zNDAyMTcxNzA0MjRaME0xCzAJBgNVBAYT +AmRlMQ0wCwYDVQQHDAR0ZXN0MQ8wDQYDVQQKDAZjbGllbnQxDzANBgNVBAsMBmNs +aWVudDENMAsGA1UEAwwEa2lyazCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAJVcOAQlCiuB9emCljROAXnlsPbG7PE3kNz2sN+BbGuw686Wgyl3uToVHvVs +paMmLUqm1KYz9wMSWTIBZgpJ9hYaIbGxD4RBb7qTAJ8Q4ddCV2f7T4lxao/6ixI+ +O0l/BG9E3mRGo/r0w+jtTQ3aR2p6eoxaOYbVyEMYtFI4QZTkcgGIPGxm05y8xonx +vV5pbSW9L7qAVDzQC8EYGQMMI4ccu0NcHKWtmTYJA/wDPE2JwhngHwbcIbc4cDz6 +cG0S3FmgiKGuuSqUy35v/k3y7zMHQSdx7DSR2tzhH/bBL/9qGvpT71KKrxPtaxS0 +bAqPcEkKWDo7IMlGGW7LaAWfGg8CAwEAAaOCASswggEnMAwGA1UdEwEB/wQCMAAw +DgYDVR0PAQH/BAQDAgXgMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMCMB0GA1UdDgQW +BBSjMS8tgguX/V7KSGLoGg7K6XMzIDCBzwYDVR0jBIHHMIHEgBQXh9+gWutmEqfV +0Pi6EkU8tysAnKGBlaSBkjCBjzETMBEGCgmSJomT8ixkARkWA2NvbTEXMBUGCgmS +JomT8ixkARkWB2V4YW1wbGUxGTAXBgNVBAoMEEV4YW1wbGUgQ29tIEluYy4xITAf +BgNVBAsMGEV4YW1wbGUgQ29tIEluYy4gUm9vdCBDQTEhMB8GA1UEAwwYRXhhbXBs +ZSBDb20gSW5jLiBSb290IENBghQNZAmZZn3EFOxBR4630XlhI+mo4jANBgkqhkiG +9w0BAQsFAAOCAQEACEUPPE66/Ot3vZqRGpjDjPHAdtOq+ebaglQhvYcnDw8LOZm8 +Gbh9M88CiO6UxC8ipQLTPh2yyeWArkpJzJK/Pi1eoF1XLiAa0sQ/RaJfQWPm9dvl +1ZQeK5vfD4147b3iBobwEV+CR04SKow0YeEEzAJvzr8YdKI6jqr+2GjjVqzxvRBy +KRVHWCFiR7bZhHGLq3br8hSu0hwjb3oGa1ZI8dui6ujyZt6nm6BoEkau3G/6+zq9 +E6vX3+8Fj4HKCAL6i0SwfGmEpTNp5WUhqibK/fMhhmMT4Mx6MxkT+OFnIjdUU0S/ +e3kgnG8qjficUr38CyEli1U0M7koIXUZI7r+LQ== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/sample-resource-plugin/src/test/resources/security/root-ca.pem b/sample-resource-plugin/src/test/resources/security/root-ca.pem new file mode 100644 index 0000000000..d33f5f7216 --- /dev/null +++ b/sample-resource-plugin/src/test/resources/security/root-ca.pem @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIExjCCA66gAwIBAgIUDWQJmWZ9xBTsQUeOt9F5YSPpqOIwDQYJKoZIhvcNAQEL +BQAwgY8xEzARBgoJkiaJk/IsZAEZFgNjb20xFzAVBgoJkiaJk/IsZAEZFgdleGFt +cGxlMRkwFwYDVQQKDBBFeGFtcGxlIENvbSBJbmMuMSEwHwYDVQQLDBhFeGFtcGxl +IENvbSBJbmMuIFJvb3QgQ0ExITAfBgNVBAMMGEV4YW1wbGUgQ29tIEluYy4gUm9v +dCBDQTAeFw0yNDAyMjAxNzAwMzZaFw0zNDAyMTcxNzAwMzZaMIGPMRMwEQYKCZIm +iZPyLGQBGRYDY29tMRcwFQYKCZImiZPyLGQBGRYHZXhhbXBsZTEZMBcGA1UECgwQ +RXhhbXBsZSBDb20gSW5jLjEhMB8GA1UECwwYRXhhbXBsZSBDb20gSW5jLiBSb290 +IENBMSEwHwYDVQQDDBhFeGFtcGxlIENvbSBJbmMuIFJvb3QgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDEPyN7J9VGPyJcQmCBl5TGwfSzvVdWwoQU +j9aEsdfFJ6pBCDQSsj8Lv4RqL0dZra7h7SpZLLX/YZcnjikrYC+rP5OwsI9xEE/4 +U98CsTBPhIMgqFK6SzNE5494BsAk4cL72dOOc8tX19oDS/PvBULbNkthQ0aAF1dg +vbrHvu7hq7LisB5ZRGHVE1k/AbCs2PaaKkn2jCw/b+U0Ml9qPuuEgz2mAqJDGYoA +WSR4YXrOcrmPuRqbws464YZbJW898/0Pn/U300ed+4YHiNYLLJp51AMkR4YEw969 +VRPbWIvLrd0PQBooC/eLrL6rvud/GpYhdQEUx8qcNCKd4bz3OaQ5AgMBAAGjggEW +MIIBEjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQU +F4ffoFrrZhKn1dD4uhJFPLcrAJwwgc8GA1UdIwSBxzCBxIAUF4ffoFrrZhKn1dD4 +uhJFPLcrAJyhgZWkgZIwgY8xEzARBgoJkiaJk/IsZAEZFgNjb20xFzAVBgoJkiaJ +k/IsZAEZFgdleGFtcGxlMRkwFwYDVQQKDBBFeGFtcGxlIENvbSBJbmMuMSEwHwYD +VQQLDBhFeGFtcGxlIENvbSBJbmMuIFJvb3QgQ0ExITAfBgNVBAMMGEV4YW1wbGUg +Q29tIEluYy4gUm9vdCBDQYIUDWQJmWZ9xBTsQUeOt9F5YSPpqOIwDQYJKoZIhvcN +AQELBQADggEBAL3Q3AHUhMiLUy6OlLSt8wX9I2oNGDKbBu0atpUNDztk/0s3YLQC +YuXgN4KrIcMXQIuAXCx407c+pIlT/T1FNn+VQXwi56PYzxQKtlpoKUL3oPQE1d0V +6EoiNk+6UodvyZqpdQu7fXVentRMk1QX7D9otmiiNuX+GSxJhJC2Lyzw65O9EUgG +1yVJon6RkUGtqBqKIuLksKwEr//ELnjmXit4LQKSnqKr0FTCB7seIrKJNyb35Qnq +qy9a/Unhokrmdda1tr6MbqU8l7HmxLuSd/Ky+L0eDNtYv6YfMewtjg0TtAnFyQov +rdXmeq1dy9HLo3Ds4AFz3Gx9076TxcRS/iI= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/sample-resource-plugin/src/test/resources/security/sample.pem b/sample-resource-plugin/src/test/resources/security/sample.pem new file mode 100644 index 0000000000..44101f0b37 --- /dev/null +++ b/sample-resource-plugin/src/test/resources/security/sample.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEPDCCAySgAwIBAgIUaYSlET3nzsotWTrWueVPPh10yLYwDQYJKoZIhvcNAQEL +BQAwgY8xEzARBgoJkiaJk/IsZAEZFgNjb20xFzAVBgoJkiaJk/IsZAEZFgdleGFt +cGxlMRkwFwYDVQQKDBBFeGFtcGxlIENvbSBJbmMuMSEwHwYDVQQLDBhFeGFtcGxl +IENvbSBJbmMuIFJvb3QgQ0ExITAfBgNVBAMMGEV4YW1wbGUgQ29tIEluYy4gUm9v +dCBDQTAeFw0yNDAyMjAxNzAzMjVaFw0zNDAyMTcxNzAzMjVaMFcxCzAJBgNVBAYT +AmRlMQ0wCwYDVQQHDAR0ZXN0MQ0wCwYDVQQKDARub2RlMQ0wCwYDVQQLDARub2Rl +MRswGQYDVQQDDBJub2RlLTAuZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCm93kXteDQHMAvbUPNPW5pyRHKDD42XGWSgq0k1D29C/Ud +yL21HLzTJa49ZU2ldIkSKs9JqbkHdyK0o8MO6L8dotLoYbxDWbJFW8bp1w6tDTU0 +HGkn47XVu3EwbfrTENg3jFu+Oem6a/501SzITzJWtS0cn2dIFOBimTVpT/4Zv5qr +XA6Cp4biOmoTYWhi/qQl8d0IaADiqoZ1MvZbZ6x76qTrRAbg+UWkpTEXoH1xTc8n +dibR7+HP6OTqCKvo1NhE8uP4pY+fWd6b6l+KLo3IKpfTbAIJXIO+M67FLtWKtttD +ao94B069skzKk6FPgW/OZh6PRCD0oxOavV+ld2SjAgMBAAGjgcYwgcMwRwYDVR0R +BEAwPogFKgMEBQWCEm5vZGUtMC5leGFtcGxlLmNvbYIJbG9jYWxob3N0hxAAAAAA +AAAAAAAAAAAAAAABhwR/AAABMAsGA1UdDwQEAwIF4DAdBgNVHSUEFjAUBggrBgEF +BQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU0/qDQaY10jIo +wCjLUpz/HfQXyt8wHwYDVR0jBBgwFoAUF4ffoFrrZhKn1dD4uhJFPLcrAJwwDQYJ +KoZIhvcNAQELBQADggEBAGbij5WyF0dKhQodQfTiFDb73ygU6IyeJkFSnxF67gDz +pQJZKFvXuVBa3cGP5e7Qp3TK50N+blXGH0xXeIV9lXeYUk4hVfBlp9LclZGX8tGi +7Xa2enMvIt5q/Yg3Hh755ZxnDYxCoGkNOXUmnMusKstE0YzvZ5Gv6fcRKFBUgZLh +hUBqIEAYly1EqH/y45APiRt3Nor1yF6zEI4TnL0yNrHw6LyQkUNCHIGMJLfnJQ9L +camMGIXOx60kXNMTigF9oXXwixWAnDM9y3QT8QXA7hej/4zkbO+vIeV/7lGUdkyg +PAi92EvyxmsliEMyMR0VINl8emyobvfwa7oMeWMR+hg= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/sample-resource-plugin/src/test/resources/security/test-kirk.jks b/sample-resource-plugin/src/test/resources/security/test-kirk.jks new file mode 100644 index 0000000000000000000000000000000000000000..6c8c5ef77e20980f8c78295b159256b805da6a28 GIT binary patch literal 3766 zcmd^=c{r47AIImJ%`(PV###wuU&o%k$xbMgr4m`Pk2Tv-j4?=zEwY?!X|aVw)I`=A zPAY52Rt6yODkPjhAQ%WsfbL*f;mp!-018Nf*#Q6sf)b!}Nv;s_8gzOC@mTmi+D9F}jyYkhL=#Xk3eYM2csmxKA&W!xAdE{tZ2mEGS z;L%QU`DHcrbdbw$3GsKUvmfQu0Z^?sH7B)!W)eLbG*fXB^G$&6CbCnj4~ z*J>Rkut6vL1EvT!JqAq#X=O~#!JHQ#QVSPuOGlnLrXXB~{{FsGRq?o?I;>^GFEhMB zw;z!v1sXap8nq3zz&+prKs-DRPm*XsS4BaP6Z{8tM~n@m|rxMA=p6*i(w=7 z*2&*Yg-uWU$5|W>>g5h)Fn{3B={`skAJ5_wXB5pDwyj{vG1_{{Y-`wB_i^B!5PA|= zrx=_>rprb&75BQ=J)SKPAJI;?(D#46)o+a?SsR^-&qJjXY2ER8S*1ZvU`t7~M6?NKULuzlAZ8C#X9>8j2;WDY z(TY-^!`&0%67`u|U_-Y(knWVcSlh-kwZQ6KG@S?L`W!iVl>Gyd(LnpMc@C!QeY{(E z)uAwF_CcqH#00}jer2dQk3}R|p^87XCxR8`n4c@g9rASTt9$8}SuGW!!+QQ&w&G!P zvv5Mft<&pzv^&XuuQAj&ieoa*3nI-hx}0`4kym=(cd>?v6yM3v43y@5@;yPeJ_N{@ z622W$@5Z4VqliMF3GAf_RcB;$HX^%cwTCgxg^4)5I0?*&oW|giBB@nUNBO+IX=iON zo~;L}HOwhyeqH4GHvAQ5i=|0c+_5*661aDyT_tr=I#+Zog%!9nRiuBb8m&SS4qp2fv7HJMG zwJFuqV*Hoq3`|Mayml;So|9W4Um6Lu8(k+(Hc2}p@&>?!7!7H~9*O%@BrKNAOa-~e z$e6#G)fJ+wNz5x9zU;#>&V}d z?!F1W_eNN;&LI9$!kWa0Zqa)0CVM4D=x(r>aXgW=XQ)PTRsJJ&MC?WjjoMwLRh`-I z8yD|^&(r#NU|pRpRF%wn&t%X`)8HQe%uxEKnXxIu9yui1s$eH0*YZ^Wvt25yOg6{5 zPefKstjqam-PRDz=&-BVb^xZe>{C{$cza!_sV&3M*l0ocMJVr!l~TlJi4JChDn9Nn zc&la1caY}0P&Ho=r;)l;mKBf$V<6A*R6XC}s98g%I7ZIAFI=e6SqQ4;oevw)nw0%^ zKq9#$;{3R0zJv}#mr7@}e+5-(`{C?^vEE#xb7uBY=X#_1v+@~@l?W@Zaq+Yo9bpu& zR<0us_T`(Q6qp1xYb)Rq;tJ|aTZ&y5xqx<_j-|>1$SEi@3!A|| z9YH<3ub_#ai=2WG_V9iQ!NU8mB|$4ZK3Gr>_s15;6W-XV-*##3TjwoMP&yb zq!L{!sQoUn<_ZWb)BbzloM2Zs1tb=+FBn*$!EQmp3Ml#oe;g0);^XP&_osni`NR1A z0SL>FG{F)8;h%d#4-g0eK+%&0UD-=ghUr~yDQ?!lNE5tKiJ_rjY{@`Q1vjbVAFU;|?Qs;w|1hFx_ z`*jR7rVAU>9*yRSpD1)#aOb!)@ak(5hk;guG$_9)=K8Ie^uOP<63|FjrX2UEcJw07 zD5c?bxHD${?)1+CMgPg@0|kH>4NzJZO*;#rl-xA_8*SHCS}ygKZP7*uHbRtmaTE%n zp7Vt7QIt|IIN?)fyS#8IxKHO$?TeY{DpQl5^kyAd$HH^Aa)SJC+I0!ULR znF7*z6R6~{CCW6M^qKuU!N`I`>YB3i6toA7f7#3%T&$5&wm0nY{&d9(g)LB$%g9dX zf>HfjVn9;)rG-^=)tiGDd<5M4wDHPl@yEGU_whSh78l$%S*WCqjvj^Xt?_VKp0T{pQGU!F;?_^4EMT$__$E zH0hMGQlo@W2p^_tPZsnirl@pGb<#0a^*g5ihYtSzKKx%Wg;i4h8B_c6Z+PPWM!I%g zOr-dLp|0@RV@@&InVrwRJfPT~ZY840gT$Jl4)HP^qcTUWE~1&}C2wS3Sv9pJWiRva zyK}a9ilnrYe7SB$bu~GF&GM`D1h@ukNsJY|Yt>|?q(4gzgSUuGwSIfsmlD)%J2V0@ zTU&-58&x%P)-#Oev2~&}bv^wwRbD$?Enu(jJiuwM3shGOZ{$juY+RGk#m^`!p7+vO zAjWFn1{dq`T?N^TggHmN3~VGf^5?a_)R-cj5yfk-?V<|S)%uKn{YGL)7(~eAhWA56 zj7ZS7amp#qQM;t>%6F)v{1S-Gq>88IPiL?2X9=q_r$vhc4{Pd3$WssBMbZaV2W zu&8||{U99-3!x+JudoA1KSAx^0qg$*YLr)FKtJ($lC@k)W?khPY!~B&3F~Xnxs_WH)b*(MC{~@>r={U4@A6+2p8il>0lojdT`r8~C>rA6;jw^lZK9gk<_y!v za(Rbclc{1;TFBtT`lr|YO0}|UXzh>FLsx6RQUq8=?V4{NR#=oxL2}kHb-ZAfuN Date: Wed, 27 Nov 2024 11:16:19 -0500 Subject: [PATCH 02/19] Cleans up create action Signed-off-by: Darshit Chanpura --- .../sample/SampleResourcePlugin.java | 4 --- .../CreateResourceTransportAction.java | 32 ++++++------------- 2 files changed, 9 insertions(+), 27 deletions(-) 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 74a8378887..6ba4b82b4a 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 @@ -12,7 +12,6 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.Map; import java.util.function.Supplier; import org.apache.logging.log4j.LogManager; @@ -70,9 +69,6 @@ public class SampleResourcePlugin extends Plugin implements ActionPlugin, System private static final Logger log = LogManager.getLogger(SampleResourcePlugin.class); public static final String RESOURCE_INDEX_NAME = ".sample_resource_sharing_plugin"; - - public final static Map INDEX_SETTINGS = Map.of("index.number_of_shards", 1, "index.auto_expand_replicas", "0-all"); - private Client client; @Override diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/CreateResourceTransportAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/CreateResourceTransportAction.java index 8bff7b44a3..53e251c5b6 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/CreateResourceTransportAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/CreateResourceTransportAction.java @@ -9,15 +9,10 @@ package org.opensearch.sample.transport; import java.io.IOException; -import java.util.List; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.opensearch.accesscontrol.resources.ResourceService; -import org.opensearch.accesscontrol.resources.ResourceSharing; -import org.opensearch.accesscontrol.resources.ShareWith; -import org.opensearch.accesscontrol.resources.SharedWithScope; import org.opensearch.action.index.IndexRequest; import org.opensearch.action.index.IndexResponse; import org.opensearch.action.support.ActionFilters; @@ -28,9 +23,8 @@ import org.opensearch.common.util.concurrent.ThreadContext; import org.opensearch.core.action.ActionListener; import org.opensearch.core.xcontent.ToXContent; +import org.opensearch.core.xcontent.XContentBuilder; import org.opensearch.sample.Resource; -import org.opensearch.sample.SampleResourcePlugin; -import org.opensearch.sample.SampleResourceScope; import org.opensearch.sample.actions.create.CreateResourceAction; import org.opensearch.sample.actions.create.CreateResourceRequest; import org.opensearch.sample.actions.create.CreateResourceResponse; @@ -58,7 +52,8 @@ public CreateResourceTransportAction(TransportService transportService, ActionFi @Override protected void doExecute(Task task, CreateResourceRequest request, ActionListener listener) { - try (ThreadContext.StoredContext ignore = transportService.getThreadPool().getThreadContext().stashContext()) { + ThreadContext threadContext = transportService.getThreadPool().getThreadContext(); + try (ThreadContext.StoredContext ignore = threadContext.stashContext()) { createResource(request, listener); listener.onResponse(new CreateResourceResponse("Resource " + request.getResource() + " created successfully.")); } catch (Exception e) { @@ -69,31 +64,22 @@ protected void doExecute(Task task, CreateResourceRequest request, ActionListene private void createResource(CreateResourceRequest request, ActionListener listener) { Resource sample = request.getResource(); - try { + try (XContentBuilder builder = jsonBuilder()) { IndexRequest ir = nodeClient.prepareIndex(RESOURCE_INDEX_NAME) .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) - .setSource(sample.toXContent(jsonBuilder(), ToXContent.EMPTY_PARAMS)) + .setSource(sample.toXContent(builder, ToXContent.EMPTY_PARAMS)) .request(); - log.warn("Index Request: {}", ir.toString()); + log.info("Index Request: {}", ir.toString()); - ActionListener irListener = getIndexResponseActionListener(listener); - nodeClient.index(ir, irListener); + nodeClient.index(ir, getIndexResponseActionListener(listener)); } catch (IOException e) { - throw new RuntimeException(e); + listener.onFailure(new RuntimeException(e)); } } private static ActionListener getIndexResponseActionListener(ActionListener listener) { - SharedWithScope.SharedWithPerScope sharedWithPerScope = new SharedWithScope.SharedWithPerScope(List.of(), List.of(), List.of()); - SharedWithScope sharedWithScope = new SharedWithScope(SampleResourceScope.SAMPLE_FULL_ACCESS.getName(), sharedWithPerScope); - ShareWith shareWith = new ShareWith(List.of(sharedWithScope)); - return ActionListener.wrap(idxResponse -> { - log.info("Created resource: {}", idxResponse.toString()); - ResourceService rs = SampleResourcePlugin.GuiceHolder.getResourceService(); - ResourceSharing sharing = rs.getResourceAccessControlPlugin().shareWith(idxResponse.getId(), idxResponse.getIndex(), shareWith); - log.info("Created resource sharing entry: {}", sharing.toString()); - }, listener::onFailure); + return ActionListener.wrap(idxResponse -> { log.info("Created resource: {}", idxResponse.toString()); }, listener::onFailure); } } From d68f349d43bc7a1eb3f496d75817be8f67880aa0 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Wed, 27 Nov 2024 14:26:21 -0500 Subject: [PATCH 03/19] Fixes create API Signed-off-by: Darshit Chanpura --- .../transport/CreateResourceTransportAction.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/CreateResourceTransportAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/CreateResourceTransportAction.java index 53e251c5b6..f5deeb961d 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/CreateResourceTransportAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/CreateResourceTransportAction.java @@ -14,7 +14,6 @@ import org.apache.logging.log4j.Logger; import org.opensearch.action.index.IndexRequest; -import org.opensearch.action.index.IndexResponse; import org.opensearch.action.support.ActionFilters; import org.opensearch.action.support.HandledTransportAction; import org.opensearch.action.support.WriteRequest; @@ -72,14 +71,12 @@ private void createResource(CreateResourceRequest request, ActionListener { log.info("Created resource: {}", idxResponse.toString()); }, listener::onFailure) + ); } catch (IOException e) { listener.onFailure(new RuntimeException(e)); } } - - private static ActionListener getIndexResponseActionListener(ActionListener listener) { - return ActionListener.wrap(idxResponse -> { log.info("Created resource: {}", idxResponse.toString()); }, listener::onFailure); - } - } From 04605491b15ec19c598639e21c29818e124d99ea Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Tue, 3 Dec 2024 17:37:12 -0500 Subject: [PATCH 04/19] Adds Revoke API and cleans up existing APIs Signed-off-by: Darshit Chanpura --- .../java/org/opensearch/sample/Resource.java | 6 +- .../sample/SampleResourcePlugin.java | 12 ++-- .../create/CreateResourceRestAction.java | 2 +- .../sample/actions/create/SampleResource.java | 9 ++- .../revoke/RevokeResourceAccessAction.java | 21 +++++++ .../revoke/RevokeResourceAccessRequest.java | 58 +++++++++++++++++++ .../revoke/RevokeResourceAccessResponse.java | 42 ++++++++++++++ .../RevokeResourceAccessRestAction.java | 55 ++++++++++++++++++ .../actions/share/ShareResourceRequest.java | 16 +++++ .../share/ShareResourceRestAction.java | 30 +++++++++- .../verify/VerifyResourceAccessRequest.java | 22 +++---- .../VerifyResourceAccessRestAction.java | 15 +++-- .../CreateResourceTransportAction.java | 10 ++-- ...istAccessibleResourcesTransportAction.java | 7 +-- .../RevokeResourceAccessTransportAction.java | 58 +++++++++++++++++++ .../ShareResourceTransportAction.java | 11 +--- .../VerifyResourceAccessTransportAction.java | 10 ++-- .../opensearch/sample/utils/Constants.java | 13 +++++ 18 files changed, 345 insertions(+), 52 deletions(-) create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessAction.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessRequest.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessResponse.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessRestAction.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/transport/RevokeResourceAccessTransportAction.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/utils/Constants.java diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/Resource.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/Resource.java index 36e74f1624..4ddb56f395 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/Resource.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/Resource.java @@ -14,6 +14,8 @@ import org.opensearch.core.common.io.stream.NamedWriteable; import org.opensearch.core.xcontent.ToXContentFragment; -public abstract class Resource implements NamedWriteable, ToXContentFragment { - protected abstract String getResourceIndex(); +public interface Resource extends NamedWriteable, ToXContentFragment { + String getResourceIndex(); + + String getResourceName(); } 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 6ba4b82b4a..753803ddaf 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 @@ -48,18 +48,19 @@ import org.opensearch.sample.actions.create.CreateResourceRestAction; import org.opensearch.sample.actions.list.ListAccessibleResourcesAction; import org.opensearch.sample.actions.list.ListAccessibleResourcesRestAction; +import org.opensearch.sample.actions.revoke.RevokeResourceAccessAction; +import org.opensearch.sample.actions.revoke.RevokeResourceAccessRestAction; import org.opensearch.sample.actions.share.ShareResourceAction; import org.opensearch.sample.actions.share.ShareResourceRestAction; import org.opensearch.sample.actions.verify.VerifyResourceAccessAction; import org.opensearch.sample.actions.verify.VerifyResourceAccessRestAction; -import org.opensearch.sample.transport.CreateResourceTransportAction; -import org.opensearch.sample.transport.ListAccessibleResourcesTransportAction; -import org.opensearch.sample.transport.ShareResourceTransportAction; -import org.opensearch.sample.transport.VerifyResourceAccessTransportAction; +import org.opensearch.sample.transport.*; import org.opensearch.script.ScriptService; import org.opensearch.threadpool.ThreadPool; import org.opensearch.watcher.ResourceWatcherService; +import static org.opensearch.sample.utils.Constants.RESOURCE_INDEX_NAME; + /** * Sample Resource plugin. * It uses ".sample_resources" index to manage its resources, and exposes a REST API @@ -68,7 +69,6 @@ public class SampleResourcePlugin extends Plugin implements ActionPlugin, SystemIndexPlugin, ResourcePlugin { private static final Logger log = LogManager.getLogger(SampleResourcePlugin.class); - public static final String RESOURCE_INDEX_NAME = ".sample_resource_sharing_plugin"; private Client client; @Override @@ -104,6 +104,7 @@ public List getRestHandlers( new CreateResourceRestAction(), new ListAccessibleResourcesRestAction(), new VerifyResourceAccessRestAction(), + new RevokeResourceAccessRestAction(), new ShareResourceRestAction() ); } @@ -114,6 +115,7 @@ public List getRestHandlers( new ActionHandler<>(CreateResourceAction.INSTANCE, CreateResourceTransportAction.class), new ActionHandler<>(ListAccessibleResourcesAction.INSTANCE, ListAccessibleResourcesTransportAction.class), new ActionHandler<>(ShareResourceAction.INSTANCE, ShareResourceTransportAction.class), + new ActionHandler<>(RevokeResourceAccessAction.INSTANCE, RevokeResourceAccessTransportAction.class), new ActionHandler<>(VerifyResourceAccessAction.INSTANCE, VerifyResourceAccessTransportAction.class) ); } diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceRestAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceRestAction.java index 86346cc279..7a9265a6b5 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceRestAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceRestAction.java @@ -27,7 +27,7 @@ public CreateResourceRestAction() {} @Override public List routes() { - return singletonList(new Route(POST, "/_plugins/sample_resource_sharing/resource")); + return singletonList(new Route(POST, "/_plugins/sample_resource_sharing/create")); } @Override diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/SampleResource.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/SampleResource.java index 1566abfe69..af3388ca14 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/SampleResource.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/SampleResource.java @@ -18,9 +18,9 @@ import org.opensearch.core.xcontent.XContentBuilder; import org.opensearch.sample.Resource; -import static org.opensearch.sample.SampleResourcePlugin.RESOURCE_INDEX_NAME; +import static org.opensearch.sample.utils.Constants.RESOURCE_INDEX_NAME; -public class SampleResource extends Resource { +public class SampleResource implements Resource { private String name; @@ -35,6 +35,11 @@ public String getResourceIndex() { return RESOURCE_INDEX_NAME; } + @Override + public String getResourceName() { + return this.name; + } + @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { return builder.startObject().field("name", name).endObject(); diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessAction.java new file mode 100644 index 0000000000..9261d5ad83 --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessAction.java @@ -0,0 +1,21 @@ +/* + * 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.actions.revoke; + +import org.opensearch.action.ActionType; + +public class RevokeResourceAccessAction extends ActionType { + public static final RevokeResourceAccessAction INSTANCE = new RevokeResourceAccessAction(); + + public static final String NAME = "cluster:admin/sample-resource-plugin/revoke"; + + private RevokeResourceAccessAction() { + super(NAME, RevokeResourceAccessResponse::new); + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessRequest.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessRequest.java new file mode 100644 index 0000000000..504b651f8b --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessRequest.java @@ -0,0 +1,58 @@ +/* + * 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.actions.revoke; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import org.opensearch.accesscontrol.resources.EntityType; +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; + +public class RevokeResourceAccessRequest extends ActionRequest { + + private final String resourceId; + private final Map> revokeAccess; + + public RevokeResourceAccessRequest(String resourceId, Map> revokeAccess) { + this.resourceId = resourceId; + this.revokeAccess = revokeAccess; + } + + public RevokeResourceAccessRequest(StreamInput in) throws IOException { + this.resourceId = in.readString(); + this.revokeAccess = in.readMap(input -> EntityType.valueOf(input.readString()), StreamInput::readStringList); + } + + @Override + public void writeTo(final StreamOutput out) throws IOException { + out.writeString(resourceId); + out.writeMap( + revokeAccess, + (streamOutput, entityType) -> streamOutput.writeString(entityType.name()), + StreamOutput::writeStringCollection + ); + } + + @Override + public ActionRequestValidationException validate() { + return null; + } + + public String getResourceId() { + return resourceId; + } + + public Map> getRevokeAccess() { + return revokeAccess; + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessResponse.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessResponse.java new file mode 100644 index 0000000000..1236be267e --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessResponse.java @@ -0,0 +1,42 @@ +/* + * 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.actions.revoke; + +import java.io.IOException; + +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; + +public class RevokeResourceAccessResponse extends ActionResponse implements ToXContentObject { + private final String message; + + public RevokeResourceAccessResponse(String message) { + this.message = message; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(message); + } + + public RevokeResourceAccessResponse(final StreamInput in) throws IOException { + message = in.readString(); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.field("message", message); + builder.endObject(); + return builder; + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessRestAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessRestAction.java new file mode 100644 index 0000000000..b5fb28ab30 --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessRestAction.java @@ -0,0 +1,55 @@ +/* + * 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.actions.revoke; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import org.opensearch.accesscontrol.resources.EntityType; +import org.opensearch.client.node.NodeClient; +import org.opensearch.core.xcontent.XContentParser; +import org.opensearch.rest.BaseRestHandler; +import org.opensearch.rest.RestRequest; +import org.opensearch.rest.action.RestToXContentListener; + +import static java.util.Collections.singletonList; +import static org.opensearch.rest.RestRequest.Method.GET; + +public class RevokeResourceAccessRestAction extends BaseRestHandler { + + public RevokeResourceAccessRestAction() {} + + @Override + public List routes() { + return singletonList(new Route(GET, "/_plugins/sample_resource_sharing/revoke")); + } + + @Override + public String getName() { + return "revoke_sample_resources_access"; + } + + @Override + public RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + Map source; + try (XContentParser parser = request.contentParser()) { + source = parser.map(); + } + + String resourceId = (String) source.get("resource_id"); + Map> revoke = (Map>) source.get("revoke"); + final RevokeResourceAccessRequest revokeResourceAccessRequest = new RevokeResourceAccessRequest(resourceId, revoke); + return channel -> client.executeLocally( + RevokeResourceAccessAction.INSTANCE, + revokeResourceAccessRequest, + new RestToXContentListener<>(channel) + ); + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceRequest.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceRequest.java index 01866fd516..3c9b2cd77a 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceRequest.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceRequest.java @@ -9,12 +9,15 @@ package org.opensearch.sample.actions.share; import java.io.IOException; +import java.util.Arrays; import org.opensearch.accesscontrol.resources.ShareWith; +import org.opensearch.accesscontrol.resources.SharedWithScope; 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 org.opensearch.sample.SampleResourceScope; public class ShareResourceRequest extends ActionRequest { @@ -39,6 +42,19 @@ public void writeTo(final StreamOutput out) throws IOException { @Override public ActionRequestValidationException validate() { + + for (SharedWithScope s : shareWith.getSharedWithScopes()) { + try { + SampleResourceScope.valueOf(s.getScope()); + } catch (IllegalArgumentException | NullPointerException e) { + ActionRequestValidationException exception = new ActionRequestValidationException(); + exception.addValidationError( + "Invalid scope: " + s.getScope() + ". Scope must be one of: " + Arrays.toString(SampleResourceScope.values()) + ); + return exception; + } + return null; + } return null; } diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceRestAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceRestAction.java index 347fb49e68..d15901c96a 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceRestAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceRestAction.java @@ -14,13 +14,17 @@ import org.opensearch.accesscontrol.resources.ShareWith; import org.opensearch.client.node.NodeClient; +import org.opensearch.common.xcontent.LoggingDeprecationHandler; +import org.opensearch.common.xcontent.XContentFactory; +import org.opensearch.common.xcontent.XContentType; +import org.opensearch.core.xcontent.NamedXContentRegistry; import org.opensearch.core.xcontent.XContentParser; import org.opensearch.rest.BaseRestHandler; import org.opensearch.rest.RestRequest; import org.opensearch.rest.action.RestToXContentListener; import static java.util.Collections.singletonList; -import static org.opensearch.rest.RestRequest.Method.GET; +import static org.opensearch.rest.RestRequest.Method.POST; public class ShareResourceRestAction extends BaseRestHandler { @@ -28,7 +32,7 @@ public ShareResourceRestAction() {} @Override public List routes() { - return singletonList(new Route(GET, "/_plugins/sample_resource_sharing/share/{resource_id}")); + return singletonList(new Route(POST, "/_plugins/sample_resource_sharing/share")); } @Override @@ -44,8 +48,28 @@ public RestChannelConsumer prepareRequest(RestRequest request, NodeClient client } String resourceId = (String) source.get("resource_id"); - ShareWith shareWith = (ShareWith) source.get("share_with"); + + ShareWith shareWith = parseShareWith(source); final ShareResourceRequest shareResourceRequest = new ShareResourceRequest(resourceId, shareWith); return channel -> client.executeLocally(ShareResourceAction.INSTANCE, shareResourceRequest, new RestToXContentListener<>(channel)); } + + private ShareWith parseShareWith(Map source) throws IOException { + @SuppressWarnings("unchecked") + Map shareWithMap = (Map) source.get("share_with"); + if (shareWithMap == null || shareWithMap.isEmpty()) { + throw new IllegalArgumentException("share_with is required and cannot be empty"); + } + + String jsonString = XContentFactory.jsonBuilder().map(shareWithMap).toString(); + + try ( + XContentParser parser = XContentType.JSON.xContent() + .createParser(NamedXContentRegistry.EMPTY, LoggingDeprecationHandler.INSTANCE, jsonString) + ) { + return ShareWith.fromXContent(parser); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Invalid share_with structure: " + e.getMessage(), e); + } + } } diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessRequest.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessRequest.java index e9b20118db..f46ebf2ce6 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessRequest.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessRequest.java @@ -9,26 +9,25 @@ package org.opensearch.sample.actions.verify; import java.io.IOException; +import java.util.Arrays; 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 org.opensearch.sample.SampleResourceScope; public class VerifyResourceAccessRequest extends ActionRequest { private final String resourceId; - private final String sourceIdx; - private final String scope; /** * Default constructor */ - public VerifyResourceAccessRequest(String resourceId, String sourceIdx, String scope) { + public VerifyResourceAccessRequest(String resourceId, String scope) { this.resourceId = resourceId; - this.sourceIdx = sourceIdx; this.scope = scope; } @@ -39,19 +38,26 @@ public VerifyResourceAccessRequest(String resourceId, String sourceIdx, String s */ public VerifyResourceAccessRequest(final StreamInput in) throws IOException { this.resourceId = in.readString(); - this.sourceIdx = in.readString(); this.scope = in.readString(); } @Override public void writeTo(final StreamOutput out) throws IOException { out.writeString(resourceId); - out.writeString(sourceIdx); out.writeString(scope); } @Override public ActionRequestValidationException validate() { + try { + SampleResourceScope.valueOf(scope); + } catch (IllegalArgumentException | NullPointerException e) { + ActionRequestValidationException exception = new ActionRequestValidationException(); + exception.addValidationError( + "Invalid scope: " + scope + ". Scope must be one of: " + Arrays.toString(SampleResourceScope.values()) + ); + return exception; + } return null; } @@ -59,10 +65,6 @@ public String getResourceId() { return resourceId; } - public String getSourceIdx() { - return sourceIdx; - } - public String getScope() { return scope; } diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessRestAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessRestAction.java index 34bfed4e9f..0d48137369 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessRestAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessRestAction.java @@ -19,7 +19,7 @@ import org.opensearch.rest.action.RestToXContentListener; import static java.util.Collections.singletonList; -import static org.opensearch.rest.RestRequest.Method.POST; +import static org.opensearch.rest.RestRequest.Method.GET; public class VerifyResourceAccessRestAction extends BaseRestHandler { @@ -27,7 +27,7 @@ public VerifyResourceAccessRestAction() {} @Override public List routes() { - return singletonList(new Route(POST, "/_plugins/sample_resource_sharing/verify_resource_access")); + return singletonList(new Route(GET, "/_plugins/sample_resource_sharing/verify_resource_access")); } @Override @@ -42,11 +42,14 @@ public RestChannelConsumer prepareRequest(RestRequest request, NodeClient client source = parser.map(); } - String resourceIdx = (String) source.get("resource_idx"); - String sourceIdx = (String) source.get("source_idx"); + String resourceId = (String) source.get("resource_id"); String scope = (String) source.get("scope"); - // final CreateResourceRequest createSampleResourceRequest = new CreateResourceRequest<>(resource); - return channel -> client.executeLocally(VerifyResourceAccessAction.INSTANCE, null, new RestToXContentListener<>(channel)); + final VerifyResourceAccessRequest verifyResourceAccessRequest = new VerifyResourceAccessRequest(resourceId, scope); + return channel -> client.executeLocally( + VerifyResourceAccessAction.INSTANCE, + verifyResourceAccessRequest, + new RestToXContentListener<>(channel) + ); } } diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/CreateResourceTransportAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/CreateResourceTransportAction.java index f5deeb961d..4b5889153e 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/CreateResourceTransportAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/CreateResourceTransportAction.java @@ -31,11 +31,8 @@ import org.opensearch.transport.TransportService; import static org.opensearch.common.xcontent.XContentFactory.jsonBuilder; -import static org.opensearch.sample.SampleResourcePlugin.RESOURCE_INDEX_NAME; +import static org.opensearch.sample.utils.Constants.RESOURCE_INDEX_NAME; -/** - * Transport action for CreateSampleResource. - */ public class CreateResourceTransportAction extends HandledTransportAction { private static final Logger log = LogManager.getLogger(CreateResourceTransportAction.class); @@ -54,7 +51,9 @@ protected void doExecute(Task task, CreateResourceRequest request, ActionListene ThreadContext threadContext = transportService.getThreadPool().getThreadContext(); try (ThreadContext.StoredContext ignore = threadContext.stashContext()) { createResource(request, listener); - listener.onResponse(new CreateResourceResponse("Resource " + request.getResource() + " created successfully.")); + listener.onResponse( + new CreateResourceResponse("Resource " + request.getResource().getResourceName() + " created successfully.") + ); } catch (Exception e) { log.info("Failed to create resource", e); listener.onFailure(e); @@ -65,6 +64,7 @@ private void createResource(CreateResourceRequest request, ActionListener { @@ -45,7 +42,7 @@ protected void doExecute(Task task, ListAccessibleResourcesRequest request, Acti try { ResourceService rs = SampleResourcePlugin.GuiceHolder.getResourceService(); List resourceIds = rs.getResourceAccessControlPlugin().listAccessibleResourcesInPlugin(RESOURCE_INDEX_NAME); - log.info("Successfully fetched accessible resources for current user"); + log.info("Successfully fetched accessible resources for current user : {}", resourceIds); listener.onResponse(new ListAccessibleResourcesResponse(resourceIds)); } catch (Exception e) { log.info("Failed to list accessible resources for current user: ", e); diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/RevokeResourceAccessTransportAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/RevokeResourceAccessTransportAction.java new file mode 100644 index 0000000000..fb73bccc8b --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/RevokeResourceAccessTransportAction.java @@ -0,0 +1,58 @@ +/* + * 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.transport; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.opensearch.accesscontrol.resources.ResourceService; +import org.opensearch.accesscontrol.resources.ResourceSharing; +import org.opensearch.action.support.ActionFilters; +import org.opensearch.action.support.HandledTransportAction; +import org.opensearch.common.inject.Inject; +import org.opensearch.core.action.ActionListener; +import org.opensearch.sample.SampleResourcePlugin; +import org.opensearch.sample.actions.revoke.RevokeResourceAccessAction; +import org.opensearch.sample.actions.revoke.RevokeResourceAccessRequest; +import org.opensearch.sample.actions.revoke.RevokeResourceAccessResponse; +import org.opensearch.tasks.Task; +import org.opensearch.transport.TransportService; + +import static org.opensearch.sample.utils.Constants.RESOURCE_INDEX_NAME; + +public class RevokeResourceAccessTransportAction extends HandledTransportAction { + private static final Logger log = LogManager.getLogger(RevokeResourceAccessTransportAction.class); + + @Inject + public RevokeResourceAccessTransportAction(TransportService transportService, ActionFilters actionFilters) { + super(RevokeResourceAccessAction.NAME, transportService, actionFilters, RevokeResourceAccessRequest::new); + } + + @Override + protected void doExecute(Task task, RevokeResourceAccessRequest request, ActionListener listener) { + try { + revokeAccess(request); + listener.onResponse(new RevokeResourceAccessResponse("Resource " + request.getResourceId() + " access revoked successfully.")); + } catch (Exception e) { + listener.onFailure(e); + } + } + + private void revokeAccess(RevokeResourceAccessRequest request) { + try { + ResourceService rs = SampleResourcePlugin.GuiceHolder.getResourceService(); + ResourceSharing revoke = rs.getResourceAccessControlPlugin() + .revokeAccess(request.getResourceId(), RESOURCE_INDEX_NAME, request.getRevokeAccess()); + log.info("Revoked resource access for resource: {} with {}", request.getResourceId(), revoke.toString()); + } catch (Exception e) { + log.info("Failed to revoke access for resource {}", request.getResourceId(), e); + throw e; + } + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/ShareResourceTransportAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/ShareResourceTransportAction.java index ccbfc31b78..5bd681e510 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/ShareResourceTransportAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/ShareResourceTransportAction.java @@ -8,14 +8,11 @@ package org.opensearch.sample.transport; -import java.util.List; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.opensearch.accesscontrol.resources.ResourceService; import org.opensearch.accesscontrol.resources.ResourceSharing; -import org.opensearch.accesscontrol.resources.ShareWith; import org.opensearch.action.support.ActionFilters; import org.opensearch.action.support.HandledTransportAction; import org.opensearch.common.inject.Inject; @@ -27,11 +24,8 @@ import org.opensearch.tasks.Task; import org.opensearch.transport.TransportService; -import static org.opensearch.sample.SampleResourcePlugin.RESOURCE_INDEX_NAME; +import static org.opensearch.sample.utils.Constants.RESOURCE_INDEX_NAME; -/** - * Transport action for CreateSampleResource. - */ public class ShareResourceTransportAction extends HandledTransportAction { private static final Logger log = LogManager.getLogger(ShareResourceTransportAction.class); @@ -52,10 +46,9 @@ protected void doExecute(Task task, ShareResourceRequest request, ActionListener private void shareResource(ShareResourceRequest request) { try { - ShareWith shareWith = new ShareWith(List.of()); ResourceService rs = SampleResourcePlugin.GuiceHolder.getResourceService(); ResourceSharing sharing = rs.getResourceAccessControlPlugin() - .shareWith(request.getResourceId(), RESOURCE_INDEX_NAME, shareWith); + .shareWith(request.getResourceId(), RESOURCE_INDEX_NAME, request.getShareWith()); log.info("Shared resource : {} with {}", request.getResourceId(), sharing.toString()); } catch (Exception e) { log.info("Failed to share resource {}", request.getResourceId(), e); diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/VerifyResourceAccessTransportAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/VerifyResourceAccessTransportAction.java index 947dcec59e..9ec528d205 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/VerifyResourceAccessTransportAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/VerifyResourceAccessTransportAction.java @@ -24,6 +24,8 @@ import org.opensearch.tasks.Task; import org.opensearch.transport.TransportService; +import static org.opensearch.sample.utils.Constants.RESOURCE_INDEX_NAME; + public class VerifyResourceAccessTransportAction extends HandledTransportAction { private static final Logger log = LogManager.getLogger(VerifyResourceAccessTransportAction.class); @@ -37,12 +39,12 @@ protected void doExecute(Task task, VerifyResourceAccessRequest request, ActionL try { ResourceService rs = SampleResourcePlugin.GuiceHolder.getResourceService(); boolean hasRequestedScopeAccess = rs.getResourceAccessControlPlugin() - .hasPermission(request.getResourceId(), request.getSourceIdx(), request.getScope()); + .hasPermission(request.getResourceId(), RESOURCE_INDEX_NAME, request.getScope()); StringBuilder sb = new StringBuilder(); - sb.append("User does"); - sb.append(hasRequestedScopeAccess ? " " : " not "); - sb.append("have requested scope "); + sb.append("User "); + sb.append(hasRequestedScopeAccess ? "has" : "does not have"); + sb.append(" requested scope "); sb.append(request.getScope()); sb.append(" access to "); sb.append(request.getResourceId()); diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/utils/Constants.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/utils/Constants.java new file mode 100644 index 0000000000..ff7404d2cd --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/utils/Constants.java @@ -0,0 +1,13 @@ +/* + * 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.utils; + +public class Constants { + public static final String RESOURCE_INDEX_NAME = ".sample_resource_sharing_plugin"; +} From 46960ea341e602c575037bc36e40131d63b181f4 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Thu, 5 Dec 2024 08:58:44 -0500 Subject: [PATCH 05/19] Adds delete API and refactors package structure Signed-off-by: Darshit Chanpura --- .../sample/SampleResourcePlugin.java | 35 +++++---- .../list/ListAccessibleResourcesAction.java | 2 +- .../list/ListAccessibleResourcesRequest.java | 2 +- .../list/ListAccessibleResourcesResponse.java | 2 +- .../ListAccessibleResourcesRestAction.java | 4 +- .../revoke/RevokeResourceAccessAction.java | 2 +- .../revoke/RevokeResourceAccessRequest.java | 2 +- .../revoke/RevokeResourceAccessResponse.java | 2 +- .../RevokeResourceAccessRestAction.java | 23 ++++-- .../share/ShareResourceAction.java | 2 +- .../share/ShareResourceRequest.java | 2 +- .../share/ShareResourceResponse.java | 2 +- .../share/ShareResourceRestAction.java | 4 +- .../verify/VerifyResourceAccessAction.java | 2 +- .../verify/VerifyResourceAccessRequest.java | 2 +- .../verify/VerifyResourceAccessResponse.java | 2 +- .../VerifyResourceAccessRestAction.java | 4 +- .../create/CreateResourceAction.java | 2 +- .../create/CreateResourceRequest.java | 2 +- .../create/CreateResourceResponse.java | 2 +- .../create/CreateResourceRestAction.java | 4 +- .../{ => resource}/create/SampleResource.java | 2 +- .../resource/delete/DeleteResourceAction.java | 29 +++++++ .../delete/DeleteResourceRequest.java | 49 ++++++++++++ .../delete/DeleteResourceResponse.java | 52 +++++++++++++ .../delete/DeleteResourceRestAction.java | 49 ++++++++++++ ...istAccessibleResourcesTransportAction.java | 8 +- .../RevokeResourceAccessTransportAction.java | 8 +- .../ShareResourceTransportAction.java | 13 ++-- .../VerifyResourceAccessTransportAction.java | 8 +- .../CreateResourceTransportAction.java | 8 +- .../DeleteResourceTransportAction.java | 76 +++++++++++++++++++ 32 files changed, 343 insertions(+), 63 deletions(-) rename sample-resource-plugin/src/main/java/org/opensearch/sample/actions/{ => access}/list/ListAccessibleResourcesAction.java (94%) rename sample-resource-plugin/src/main/java/org/opensearch/sample/actions/{ => access}/list/ListAccessibleResourcesRequest.java (95%) rename sample-resource-plugin/src/main/java/org/opensearch/sample/actions/{ => access}/list/ListAccessibleResourcesResponse.java (96%) rename sample-resource-plugin/src/main/java/org/opensearch/sample/actions/{ => access}/list/ListAccessibleResourcesRestAction.java (89%) rename sample-resource-plugin/src/main/java/org/opensearch/sample/actions/{ => access}/revoke/RevokeResourceAccessAction.java (92%) rename sample-resource-plugin/src/main/java/org/opensearch/sample/actions/{ => access}/revoke/RevokeResourceAccessRequest.java (97%) rename sample-resource-plugin/src/main/java/org/opensearch/sample/actions/{ => access}/revoke/RevokeResourceAccessResponse.java (95%) rename sample-resource-plugin/src/main/java/org/opensearch/sample/actions/{ => access}/revoke/RevokeResourceAccessRestAction.java (59%) rename sample-resource-plugin/src/main/java/org/opensearch/sample/actions/{ => access}/share/ShareResourceAction.java (93%) rename sample-resource-plugin/src/main/java/org/opensearch/sample/actions/{ => access}/share/ShareResourceRequest.java (97%) rename sample-resource-plugin/src/main/java/org/opensearch/sample/actions/{ => access}/share/ShareResourceResponse.java (96%) rename sample-resource-plugin/src/main/java/org/opensearch/sample/actions/{ => access}/share/ShareResourceRestAction.java (94%) rename sample-resource-plugin/src/main/java/org/opensearch/sample/actions/{ => access}/verify/VerifyResourceAccessAction.java (93%) rename sample-resource-plugin/src/main/java/org/opensearch/sample/actions/{ => access}/verify/VerifyResourceAccessRequest.java (97%) rename sample-resource-plugin/src/main/java/org/opensearch/sample/actions/{ => access}/verify/VerifyResourceAccessResponse.java (96%) rename sample-resource-plugin/src/main/java/org/opensearch/sample/actions/{ => access}/verify/VerifyResourceAccessRestAction.java (90%) rename sample-resource-plugin/src/main/java/org/opensearch/sample/actions/{ => resource}/create/CreateResourceAction.java (93%) rename sample-resource-plugin/src/main/java/org/opensearch/sample/actions/{ => resource}/create/CreateResourceRequest.java (95%) rename sample-resource-plugin/src/main/java/org/opensearch/sample/actions/{ => resource}/create/CreateResourceResponse.java (96%) rename sample-resource-plugin/src/main/java/org/opensearch/sample/actions/{ => resource}/create/CreateResourceRestAction.java (90%) rename sample-resource-plugin/src/main/java/org/opensearch/sample/actions/{ => resource}/create/SampleResource.java (96%) create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/delete/DeleteResourceAction.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/delete/DeleteResourceRequest.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/delete/DeleteResourceResponse.java create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/delete/DeleteResourceRestAction.java rename sample-resource-plugin/src/main/java/org/opensearch/sample/transport/{ => access}/ListAccessibleResourcesTransportAction.java (87%) rename sample-resource-plugin/src/main/java/org/opensearch/sample/transport/{ => access}/RevokeResourceAccessTransportAction.java (89%) rename sample-resource-plugin/src/main/java/org/opensearch/sample/transport/{ => access}/ShareResourceTransportAction.java (81%) rename sample-resource-plugin/src/main/java/org/opensearch/sample/transport/{ => access}/VerifyResourceAccessTransportAction.java (89%) rename sample-resource-plugin/src/main/java/org/opensearch/sample/transport/{ => resource}/CreateResourceTransportAction.java (92%) create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/transport/resource/DeleteResourceTransportAction.java 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 753803ddaf..90a62f7286 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 @@ -44,17 +44,24 @@ import org.opensearch.repositories.RepositoriesService; import org.opensearch.rest.RestController; import org.opensearch.rest.RestHandler; -import org.opensearch.sample.actions.create.CreateResourceAction; -import org.opensearch.sample.actions.create.CreateResourceRestAction; -import org.opensearch.sample.actions.list.ListAccessibleResourcesAction; -import org.opensearch.sample.actions.list.ListAccessibleResourcesRestAction; -import org.opensearch.sample.actions.revoke.RevokeResourceAccessAction; -import org.opensearch.sample.actions.revoke.RevokeResourceAccessRestAction; -import org.opensearch.sample.actions.share.ShareResourceAction; -import org.opensearch.sample.actions.share.ShareResourceRestAction; -import org.opensearch.sample.actions.verify.VerifyResourceAccessAction; -import org.opensearch.sample.actions.verify.VerifyResourceAccessRestAction; -import org.opensearch.sample.transport.*; +import org.opensearch.sample.actions.access.list.ListAccessibleResourcesAction; +import org.opensearch.sample.actions.access.list.ListAccessibleResourcesRestAction; +import org.opensearch.sample.actions.access.revoke.RevokeResourceAccessAction; +import org.opensearch.sample.actions.access.revoke.RevokeResourceAccessRestAction; +import org.opensearch.sample.actions.access.share.ShareResourceAction; +import org.opensearch.sample.actions.access.share.ShareResourceRestAction; +import org.opensearch.sample.actions.access.verify.VerifyResourceAccessAction; +import org.opensearch.sample.actions.access.verify.VerifyResourceAccessRestAction; +import org.opensearch.sample.actions.resource.create.CreateResourceAction; +import org.opensearch.sample.actions.resource.create.CreateResourceRestAction; +import org.opensearch.sample.actions.resource.delete.DeleteResourceAction; +import org.opensearch.sample.actions.resource.delete.DeleteResourceRestAction; +import org.opensearch.sample.transport.access.ListAccessibleResourcesTransportAction; +import org.opensearch.sample.transport.access.RevokeResourceAccessTransportAction; +import org.opensearch.sample.transport.access.ShareResourceTransportAction; +import org.opensearch.sample.transport.access.VerifyResourceAccessTransportAction; +import org.opensearch.sample.transport.resource.CreateResourceTransportAction; +import org.opensearch.sample.transport.resource.DeleteResourceTransportAction; import org.opensearch.script.ScriptService; import org.opensearch.threadpool.ThreadPool; import org.opensearch.watcher.ResourceWatcherService; @@ -105,7 +112,8 @@ public List getRestHandlers( new ListAccessibleResourcesRestAction(), new VerifyResourceAccessRestAction(), new RevokeResourceAccessRestAction(), - new ShareResourceRestAction() + new ShareResourceRestAction(), + new DeleteResourceRestAction() ); } @@ -116,7 +124,8 @@ public List getRestHandlers( new ActionHandler<>(ListAccessibleResourcesAction.INSTANCE, ListAccessibleResourcesTransportAction.class), new ActionHandler<>(ShareResourceAction.INSTANCE, ShareResourceTransportAction.class), new ActionHandler<>(RevokeResourceAccessAction.INSTANCE, RevokeResourceAccessTransportAction.class), - new ActionHandler<>(VerifyResourceAccessAction.INSTANCE, VerifyResourceAccessTransportAction.class) + new ActionHandler<>(VerifyResourceAccessAction.INSTANCE, VerifyResourceAccessTransportAction.class), + new ActionHandler<>(DeleteResourceAction.INSTANCE, DeleteResourceTransportAction.class) ); } diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/list/ListAccessibleResourcesAction.java similarity index 94% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesAction.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/list/ListAccessibleResourcesAction.java index b4e9e29e22..3bea515a19 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/list/ListAccessibleResourcesAction.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.sample.actions.list; +package org.opensearch.sample.actions.access.list; import org.opensearch.action.ActionType; diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesRequest.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/list/ListAccessibleResourcesRequest.java similarity index 95% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesRequest.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/list/ListAccessibleResourcesRequest.java index b4c0961774..4a9315bfd9 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesRequest.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/list/ListAccessibleResourcesRequest.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.sample.actions.list; +package org.opensearch.sample.actions.access.list; import java.io.IOException; diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesResponse.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/list/ListAccessibleResourcesResponse.java similarity index 96% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesResponse.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/list/ListAccessibleResourcesResponse.java index 47a8f88e4e..5c3715d143 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesResponse.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/list/ListAccessibleResourcesResponse.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.sample.actions.list; +package org.opensearch.sample.actions.access.list; import java.io.IOException; import java.util.List; diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesRestAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/list/ListAccessibleResourcesRestAction.java similarity index 89% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesRestAction.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/list/ListAccessibleResourcesRestAction.java index bb921fce00..2eee67e0f1 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/list/ListAccessibleResourcesRestAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/list/ListAccessibleResourcesRestAction.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.sample.actions.list; +package org.opensearch.sample.actions.access.list; import java.util.List; @@ -33,7 +33,7 @@ public String getName() { } @Override - public RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) { + protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) { final ListAccessibleResourcesRequest listAccessibleResourcesRequest = new ListAccessibleResourcesRequest(); return channel -> client.executeLocally( ListAccessibleResourcesAction.INSTANCE, diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessAction.java similarity index 92% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessAction.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessAction.java index 9261d5ad83..a040cb0732 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessAction.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.sample.actions.revoke; +package org.opensearch.sample.actions.access.revoke; import org.opensearch.action.ActionType; diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessRequest.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRequest.java similarity index 97% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessRequest.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRequest.java index 504b651f8b..c59fc721f2 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessRequest.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRequest.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.sample.actions.revoke; +package org.opensearch.sample.actions.access.revoke; import java.io.IOException; import java.util.List; diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessResponse.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessResponse.java similarity index 95% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessResponse.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessResponse.java index 1236be267e..4cfd3d74e5 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessResponse.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessResponse.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.sample.actions.revoke; +package org.opensearch.sample.actions.access.revoke; import java.io.IOException; diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessRestAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRestAction.java similarity index 59% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessRestAction.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRestAction.java index b5fb28ab30..01e1b7591c 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/revoke/RevokeResourceAccessRestAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRestAction.java @@ -6,11 +6,13 @@ * compatible open source license. */ -package org.opensearch.sample.actions.revoke; +package org.opensearch.sample.actions.access.revoke; import java.io.IOException; +import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import org.opensearch.accesscontrol.resources.EntityType; import org.opensearch.client.node.NodeClient; @@ -20,7 +22,7 @@ import org.opensearch.rest.action.RestToXContentListener; import static java.util.Collections.singletonList; -import static org.opensearch.rest.RestRequest.Method.GET; +import static org.opensearch.rest.RestRequest.Method.POST; public class RevokeResourceAccessRestAction extends BaseRestHandler { @@ -28,7 +30,7 @@ public RevokeResourceAccessRestAction() {} @Override public List routes() { - return singletonList(new Route(GET, "/_plugins/sample_resource_sharing/revoke")); + return singletonList(new Route(POST, "/_plugins/sample_resource_sharing/revoke")); } @Override @@ -37,14 +39,25 @@ public String getName() { } @Override - public RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { Map source; try (XContentParser parser = request.contentParser()) { source = parser.map(); } String resourceId = (String) source.get("resource_id"); - Map> revoke = (Map>) source.get("revoke"); + @SuppressWarnings("unchecked") + Map> revokeSource = (Map>) source.get("revoke"); + Map> revoke = revokeSource.entrySet().stream().collect(Collectors.toMap(entry -> { + try { + return EntityType.fromValue(entry.getKey()); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException( + "Invalid entity type: " + entry.getKey() + ". Valid values are: " + Arrays.toString(EntityType.values()) + ); + } + }, Map.Entry::getValue)); + final RevokeResourceAccessRequest revokeResourceAccessRequest = new RevokeResourceAccessRequest(resourceId, revoke); return channel -> client.executeLocally( RevokeResourceAccessAction.INSTANCE, diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/share/ShareResourceAction.java similarity index 93% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceAction.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/share/ShareResourceAction.java index d362b1927c..768a811e27 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/share/ShareResourceAction.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.sample.actions.share; +package org.opensearch.sample.actions.access.share; import org.opensearch.action.ActionType; diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceRequest.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/share/ShareResourceRequest.java similarity index 97% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceRequest.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/share/ShareResourceRequest.java index 3c9b2cd77a..b222364c0c 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceRequest.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/share/ShareResourceRequest.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.sample.actions.share; +package org.opensearch.sample.actions.access.share; import java.io.IOException; import java.util.Arrays; diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceResponse.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/share/ShareResourceResponse.java similarity index 96% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceResponse.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/share/ShareResourceResponse.java index a6a85d206d..035a9a245e 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceResponse.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/share/ShareResourceResponse.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.sample.actions.share; +package org.opensearch.sample.actions.access.share; import java.io.IOException; diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceRestAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/share/ShareResourceRestAction.java similarity index 94% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceRestAction.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/share/ShareResourceRestAction.java index d15901c96a..0db4208c05 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/share/ShareResourceRestAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/share/ShareResourceRestAction.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.sample.actions.share; +package org.opensearch.sample.actions.access.share; import java.io.IOException; import java.util.List; @@ -41,7 +41,7 @@ public String getName() { } @Override - public RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { Map source; try (XContentParser parser = request.contentParser()) { source = parser.map(); diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/verify/VerifyResourceAccessAction.java similarity index 93% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessAction.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/verify/VerifyResourceAccessAction.java index 1378d561f5..466cc901c6 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/verify/VerifyResourceAccessAction.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.sample.actions.verify; +package org.opensearch.sample.actions.access.verify; import org.opensearch.action.ActionType; diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessRequest.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/verify/VerifyResourceAccessRequest.java similarity index 97% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessRequest.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/verify/VerifyResourceAccessRequest.java index f46ebf2ce6..87c5b5a7f0 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessRequest.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/verify/VerifyResourceAccessRequest.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.sample.actions.verify; +package org.opensearch.sample.actions.access.verify; import java.io.IOException; import java.util.Arrays; diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessResponse.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/verify/VerifyResourceAccessResponse.java similarity index 96% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessResponse.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/verify/VerifyResourceAccessResponse.java index 660ac03f71..f7c419b9d1 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessResponse.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/verify/VerifyResourceAccessResponse.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.sample.actions.verify; +package org.opensearch.sample.actions.access.verify; import java.io.IOException; diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessRestAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/verify/VerifyResourceAccessRestAction.java similarity index 90% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessRestAction.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/verify/VerifyResourceAccessRestAction.java index 0d48137369..3118fd54e6 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/verify/VerifyResourceAccessRestAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/verify/VerifyResourceAccessRestAction.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.sample.actions.verify; +package org.opensearch.sample.actions.access.verify; import java.io.IOException; import java.util.List; @@ -36,7 +36,7 @@ public String getName() { } @Override - public RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { Map source; try (XContentParser parser = request.contentParser()) { source = parser.map(); diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/CreateResourceAction.java similarity index 93% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceAction.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/CreateResourceAction.java index e7c02278ab..a2b91185e1 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/CreateResourceAction.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.sample.actions.create; +package org.opensearch.sample.actions.resource.create; import org.opensearch.action.ActionType; diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceRequest.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/CreateResourceRequest.java similarity index 95% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceRequest.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/CreateResourceRequest.java index b31a4b7f2b..3f330d9719 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceRequest.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/CreateResourceRequest.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.sample.actions.create; +package org.opensearch.sample.actions.resource.create; import java.io.IOException; diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceResponse.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/CreateResourceResponse.java similarity index 96% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceResponse.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/CreateResourceResponse.java index 6b966ed08d..6b980c9912 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceResponse.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/CreateResourceResponse.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.sample.actions.create; +package org.opensearch.sample.actions.resource.create; import java.io.IOException; diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceRestAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/CreateResourceRestAction.java similarity index 90% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceRestAction.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/CreateResourceRestAction.java index 7a9265a6b5..171c539a7c 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/CreateResourceRestAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/CreateResourceRestAction.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.sample.actions.create; +package org.opensearch.sample.actions.resource.create; import java.io.IOException; import java.util.List; @@ -36,7 +36,7 @@ public String getName() { } @Override - public RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { Map source; try (XContentParser parser = request.contentParser()) { source = parser.map(); diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/SampleResource.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/SampleResource.java similarity index 96% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/SampleResource.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/SampleResource.java index af3388ca14..db475b7018 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/create/SampleResource.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/SampleResource.java @@ -9,7 +9,7 @@ * GitHub history for details. */ -package org.opensearch.sample.actions.create; +package org.opensearch.sample.actions.resource.create; import java.io.IOException; diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/delete/DeleteResourceAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/delete/DeleteResourceAction.java new file mode 100644 index 0000000000..ccb31f7ab2 --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/delete/DeleteResourceAction.java @@ -0,0 +1,29 @@ +/* + * 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.actions.resource.delete; + +import org.opensearch.action.ActionType; + +/** + * Action to create a sample resource + */ +public class DeleteResourceAction extends ActionType { + /** + * Create sample resource action instance + */ + public static final DeleteResourceAction INSTANCE = new DeleteResourceAction(); + /** + * Create sample resource action name + */ + public static final String NAME = "cluster:admin/sample-resource-plugin/delete"; + + private DeleteResourceAction() { + super(NAME, DeleteResourceResponse::new); + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/delete/DeleteResourceRequest.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/delete/DeleteResourceRequest.java new file mode 100644 index 0000000000..1cb58989d3 --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/delete/DeleteResourceRequest.java @@ -0,0 +1,49 @@ +/* + * 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.actions.resource.delete; + +import java.io.IOException; + +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; + +/** + * Request object for CreateSampleResource transport action + */ +public class DeleteResourceRequest extends ActionRequest { + + private final String resourceId; + + /** + * Default constructor + */ + public DeleteResourceRequest(String resourceId) { + this.resourceId = resourceId; + } + + public DeleteResourceRequest(StreamInput in) throws IOException { + this.resourceId = in.readString(); + } + + @Override + public void writeTo(final StreamOutput out) throws IOException { + out.writeString(this.resourceId); + } + + @Override + public ActionRequestValidationException validate() { + return null; + } + + public String getResourceId() { + return this.resourceId; + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/delete/DeleteResourceResponse.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/delete/DeleteResourceResponse.java new file mode 100644 index 0000000000..ba3cddc04b --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/delete/DeleteResourceResponse.java @@ -0,0 +1,52 @@ +/* + * 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.actions.resource.delete; + +import java.io.IOException; + +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; + +public class DeleteResourceResponse extends ActionResponse implements ToXContentObject { + private final String message; + + /** + * Default constructor + * + * @param message The message + */ + public DeleteResourceResponse(String message) { + this.message = message; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(message); + } + + /** + * Constructor with StreamInput + * + * @param in the stream input + */ + public DeleteResourceResponse(final StreamInput in) throws IOException { + message = in.readString(); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.field("message", message); + builder.endObject(); + return builder; + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/delete/DeleteResourceRestAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/delete/DeleteResourceRestAction.java new file mode 100644 index 0000000000..9a10ca2a62 --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/delete/DeleteResourceRestAction.java @@ -0,0 +1,49 @@ +/* + * 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.actions.resource.delete; + +import java.util.List; + +import org.opensearch.client.node.NodeClient; +import org.opensearch.core.common.Strings; +import org.opensearch.rest.BaseRestHandler; +import org.opensearch.rest.RestRequest; +import org.opensearch.rest.action.RestToXContentListener; + +import static java.util.Collections.singletonList; +import static org.opensearch.rest.RestRequest.Method.DELETE; + +public class DeleteResourceRestAction extends BaseRestHandler { + + public DeleteResourceRestAction() {} + + @Override + public List routes() { + return singletonList(new Route(DELETE, "/_plugins/sample_resource_sharing/delete/{resource_id}")); + } + + @Override + public String getName() { + return "delete_sample_resource"; + } + + @Override + protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) { + String resourceId = request.param("resource_id"); + if (Strings.isNullOrEmpty(resourceId)) { + throw new IllegalArgumentException("resource_id parameter is required"); + } + final DeleteResourceRequest createSampleResourceRequest = new DeleteResourceRequest(resourceId); + return channel -> client.executeLocally( + DeleteResourceAction.INSTANCE, + createSampleResourceRequest, + new RestToXContentListener<>(channel) + ); + } +} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/ListAccessibleResourcesTransportAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/ListAccessibleResourcesTransportAction.java similarity index 87% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/transport/ListAccessibleResourcesTransportAction.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/ListAccessibleResourcesTransportAction.java index 7ef71e4e42..794675d3f3 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/ListAccessibleResourcesTransportAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/ListAccessibleResourcesTransportAction.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.sample.transport; +package org.opensearch.sample.transport.access; import java.util.List; @@ -19,9 +19,9 @@ import org.opensearch.common.inject.Inject; import org.opensearch.core.action.ActionListener; import org.opensearch.sample.SampleResourcePlugin; -import org.opensearch.sample.actions.list.ListAccessibleResourcesAction; -import org.opensearch.sample.actions.list.ListAccessibleResourcesRequest; -import org.opensearch.sample.actions.list.ListAccessibleResourcesResponse; +import org.opensearch.sample.actions.access.list.ListAccessibleResourcesAction; +import org.opensearch.sample.actions.access.list.ListAccessibleResourcesRequest; +import org.opensearch.sample.actions.access.list.ListAccessibleResourcesResponse; import org.opensearch.tasks.Task; import org.opensearch.transport.TransportService; diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/RevokeResourceAccessTransportAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/RevokeResourceAccessTransportAction.java similarity index 89% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/transport/RevokeResourceAccessTransportAction.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/RevokeResourceAccessTransportAction.java index fb73bccc8b..14fa982e52 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/RevokeResourceAccessTransportAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/RevokeResourceAccessTransportAction.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.sample.transport; +package org.opensearch.sample.transport.access; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -18,9 +18,9 @@ import org.opensearch.common.inject.Inject; import org.opensearch.core.action.ActionListener; import org.opensearch.sample.SampleResourcePlugin; -import org.opensearch.sample.actions.revoke.RevokeResourceAccessAction; -import org.opensearch.sample.actions.revoke.RevokeResourceAccessRequest; -import org.opensearch.sample.actions.revoke.RevokeResourceAccessResponse; +import org.opensearch.sample.actions.access.revoke.RevokeResourceAccessAction; +import org.opensearch.sample.actions.access.revoke.RevokeResourceAccessRequest; +import org.opensearch.sample.actions.access.revoke.RevokeResourceAccessResponse; import org.opensearch.tasks.Task; import org.opensearch.transport.TransportService; diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/ShareResourceTransportAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/ShareResourceTransportAction.java similarity index 81% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/transport/ShareResourceTransportAction.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/ShareResourceTransportAction.java index 5bd681e510..e99a9abf24 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/ShareResourceTransportAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/ShareResourceTransportAction.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.sample.transport; +package org.opensearch.sample.transport.access; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -18,9 +18,9 @@ import org.opensearch.common.inject.Inject; import org.opensearch.core.action.ActionListener; import org.opensearch.sample.SampleResourcePlugin; -import org.opensearch.sample.actions.share.ShareResourceAction; -import org.opensearch.sample.actions.share.ShareResourceRequest; -import org.opensearch.sample.actions.share.ShareResourceResponse; +import org.opensearch.sample.actions.access.share.ShareResourceAction; +import org.opensearch.sample.actions.access.share.ShareResourceRequest; +import org.opensearch.sample.actions.access.share.ShareResourceResponse; import org.opensearch.tasks.Task; import org.opensearch.transport.TransportService; @@ -44,11 +44,14 @@ protected void doExecute(Task task, ShareResourceRequest request, ActionListener } } - private void shareResource(ShareResourceRequest request) { + private void shareResource(ShareResourceRequest request) throws Exception { try { ResourceService rs = SampleResourcePlugin.GuiceHolder.getResourceService(); ResourceSharing sharing = rs.getResourceAccessControlPlugin() .shareWith(request.getResourceId(), RESOURCE_INDEX_NAME, request.getShareWith()); + if (sharing == null) { + throw new Exception("Failed to share resource " + request.getResourceId()); + } log.info("Shared resource : {} with {}", request.getResourceId(), sharing.toString()); } catch (Exception e) { log.info("Failed to share resource {}", request.getResourceId(), e); diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/VerifyResourceAccessTransportAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/VerifyResourceAccessTransportAction.java similarity index 89% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/transport/VerifyResourceAccessTransportAction.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/VerifyResourceAccessTransportAction.java index 9ec528d205..681e4546cc 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/VerifyResourceAccessTransportAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/VerifyResourceAccessTransportAction.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.sample.transport; +package org.opensearch.sample.transport.access; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -18,9 +18,9 @@ import org.opensearch.common.inject.Inject; import org.opensearch.core.action.ActionListener; import org.opensearch.sample.SampleResourcePlugin; -import org.opensearch.sample.actions.verify.VerifyResourceAccessAction; -import org.opensearch.sample.actions.verify.VerifyResourceAccessRequest; -import org.opensearch.sample.actions.verify.VerifyResourceAccessResponse; +import org.opensearch.sample.actions.access.verify.VerifyResourceAccessAction; +import org.opensearch.sample.actions.access.verify.VerifyResourceAccessRequest; +import org.opensearch.sample.actions.access.verify.VerifyResourceAccessResponse; import org.opensearch.tasks.Task; import org.opensearch.transport.TransportService; diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/CreateResourceTransportAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/resource/CreateResourceTransportAction.java similarity index 92% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/transport/CreateResourceTransportAction.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/transport/resource/CreateResourceTransportAction.java index 4b5889153e..9a764b61de 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/CreateResourceTransportAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/resource/CreateResourceTransportAction.java @@ -6,7 +6,7 @@ * compatible open source license. */ -package org.opensearch.sample.transport; +package org.opensearch.sample.transport.resource; import java.io.IOException; @@ -24,9 +24,9 @@ import org.opensearch.core.xcontent.ToXContent; import org.opensearch.core.xcontent.XContentBuilder; import org.opensearch.sample.Resource; -import org.opensearch.sample.actions.create.CreateResourceAction; -import org.opensearch.sample.actions.create.CreateResourceRequest; -import org.opensearch.sample.actions.create.CreateResourceResponse; +import org.opensearch.sample.actions.resource.create.CreateResourceAction; +import org.opensearch.sample.actions.resource.create.CreateResourceRequest; +import org.opensearch.sample.actions.resource.create.CreateResourceResponse; import org.opensearch.tasks.Task; import org.opensearch.transport.TransportService; diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/resource/DeleteResourceTransportAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/resource/DeleteResourceTransportAction.java new file mode 100644 index 0000000000..bdc19ab8b3 --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/resource/DeleteResourceTransportAction.java @@ -0,0 +1,76 @@ +/* + * 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.transport.resource; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.opensearch.ResourceNotFoundException; +import org.opensearch.action.DocWriteResponse; +import org.opensearch.action.delete.DeleteRequest; +import org.opensearch.action.delete.DeleteResponse; +import org.opensearch.action.support.ActionFilters; +import org.opensearch.action.support.HandledTransportAction; +import org.opensearch.action.support.WriteRequest; +import org.opensearch.client.Client; +import org.opensearch.common.inject.Inject; +import org.opensearch.common.util.concurrent.ThreadContext; +import org.opensearch.core.action.ActionListener; +import org.opensearch.sample.actions.resource.delete.DeleteResourceAction; +import org.opensearch.sample.actions.resource.delete.DeleteResourceRequest; +import org.opensearch.sample.actions.resource.delete.DeleteResourceResponse; +import org.opensearch.tasks.Task; +import org.opensearch.transport.TransportService; + +import static org.opensearch.sample.utils.Constants.RESOURCE_INDEX_NAME; + +public class DeleteResourceTransportAction extends HandledTransportAction { + private static final Logger log = LogManager.getLogger(DeleteResourceTransportAction.class); + + private final TransportService transportService; + private final Client nodeClient; + + @Inject + public DeleteResourceTransportAction(TransportService transportService, ActionFilters actionFilters, Client nodeClient) { + super(DeleteResourceAction.NAME, transportService, actionFilters, DeleteResourceRequest::new); + this.transportService = transportService; + this.nodeClient = nodeClient; + } + + @Override + protected void doExecute(Task task, DeleteResourceRequest request, ActionListener listener) { + if (request.getResourceId() == null || request.getResourceId().isEmpty()) { + listener.onFailure(new IllegalArgumentException("Resource ID cannot be null or empty")); + return; + } + + ThreadContext threadContext = transportService.getThreadPool().getThreadContext(); + try (ThreadContext.StoredContext ignore = threadContext.stashContext()) { + deleteResource(request, ActionListener.wrap(deleteResponse -> { + if (deleteResponse.getResult() == DocWriteResponse.Result.NOT_FOUND) { + listener.onFailure(new ResourceNotFoundException("Resource " + request.getResourceId() + " not found")); + } else { + listener.onResponse(new DeleteResourceResponse("Resource " + request.getResourceId() + " deleted successfully")); + } + }, exception -> { + log.error("Failed to delete resource: " + request.getResourceId(), exception); + listener.onFailure(exception); + })); + } + } + + private void deleteResource(DeleteResourceRequest request, ActionListener listener) { + DeleteRequest deleteRequest = new DeleteRequest(RESOURCE_INDEX_NAME, request.getResourceId()).setRefreshPolicy( + WriteRequest.RefreshPolicy.IMMEDIATE + ); + + nodeClient.delete(deleteRequest, listener); + } + +} From bc67926c53ab7092b3de64302649668ae3a98a1d Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Thu, 5 Dec 2024 16:56:12 -0500 Subject: [PATCH 06/19] Updates Revoke request Signed-off-by: Darshit Chanpura --- .../access/revoke/RevokeResourceAccessRequest.java | 10 +++++++++- .../access/revoke/RevokeResourceAccessRestAction.java | 7 ++++--- .../access/RevokeResourceAccessTransportAction.java | 2 +- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRequest.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRequest.java index c59fc721f2..3b7b10f19a 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRequest.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRequest.java @@ -22,15 +22,18 @@ public class RevokeResourceAccessRequest extends ActionRequest { private final String resourceId; private final Map> revokeAccess; + private final List scopes; - public RevokeResourceAccessRequest(String resourceId, Map> revokeAccess) { + public RevokeResourceAccessRequest(String resourceId, Map> revokeAccess, List scopes) { this.resourceId = resourceId; this.revokeAccess = revokeAccess; + this.scopes = scopes; } public RevokeResourceAccessRequest(StreamInput in) throws IOException { this.resourceId = in.readString(); this.revokeAccess = in.readMap(input -> EntityType.valueOf(input.readString()), StreamInput::readStringList); + this.scopes = in.readStringList(); } @Override @@ -41,6 +44,7 @@ public void writeTo(final StreamOutput out) throws IOException { (streamOutput, entityType) -> streamOutput.writeString(entityType.name()), StreamOutput::writeStringCollection ); + out.writeStringCollection(scopes); } @Override @@ -55,4 +59,8 @@ public String getResourceId() { public Map> getRevokeAccess() { return revokeAccess; } + + public List getScopes() { + return scopes; + } } diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRestAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRestAction.java index 01e1b7591c..85a01d2234 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRestAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRestAction.java @@ -47,7 +47,7 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli String resourceId = (String) source.get("resource_id"); @SuppressWarnings("unchecked") - Map> revokeSource = (Map>) source.get("revoke"); + Map> revokeSource = (Map>) source.get("entities"); Map> revoke = revokeSource.entrySet().stream().collect(Collectors.toMap(entry -> { try { return EntityType.fromValue(entry.getKey()); @@ -57,8 +57,9 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli ); } }, Map.Entry::getValue)); - - final RevokeResourceAccessRequest revokeResourceAccessRequest = new RevokeResourceAccessRequest(resourceId, revoke); + @SuppressWarnings("unchecked") + List scopes = source.containsKey("scopes") ? (List) source.get("scopes") : List.of(); + final RevokeResourceAccessRequest revokeResourceAccessRequest = new RevokeResourceAccessRequest(resourceId, revoke, scopes); return channel -> client.executeLocally( RevokeResourceAccessAction.INSTANCE, revokeResourceAccessRequest, diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/RevokeResourceAccessTransportAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/RevokeResourceAccessTransportAction.java index 14fa982e52..dd7757e4f2 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/RevokeResourceAccessTransportAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/RevokeResourceAccessTransportAction.java @@ -48,7 +48,7 @@ private void revokeAccess(RevokeResourceAccessRequest request) { try { ResourceService rs = SampleResourcePlugin.GuiceHolder.getResourceService(); ResourceSharing revoke = rs.getResourceAccessControlPlugin() - .revokeAccess(request.getResourceId(), RESOURCE_INDEX_NAME, request.getRevokeAccess()); + .revokeAccess(request.getResourceId(), RESOURCE_INDEX_NAME, request.getRevokeAccess(), request.getScopes()); log.info("Revoked resource access for resource: {} with {}", request.getResourceId(), revoke.toString()); } catch (Exception e) { log.info("Failed to revoke access for resource {}", request.getResourceId(), e); From ccd5d07fb98c8ec586f87a513085cf67385a8d9e Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Thu, 5 Dec 2024 18:15:35 -0500 Subject: [PATCH 07/19] Convert sets to lists Signed-off-by: Darshit Chanpura --- .../list/ListAccessibleResourcesResponse.java | 8 ++--- .../revoke/RevokeResourceAccessRequest.java | 22 ++++++++----- .../RevokeResourceAccessRestAction.java | 7 ++-- .../access/share/ShareResourceRequest.java | 20 +++--------- .../verify/VerifyResourceAccessRequest.java | 15 ++------- ...istAccessibleResourcesTransportAction.java | 4 +-- .../opensearch/sample/utils/Validation.java | 32 +++++++++++++++++++ 7 files changed, 64 insertions(+), 44 deletions(-) create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/utils/Validation.java diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/list/ListAccessibleResourcesResponse.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/list/ListAccessibleResourcesResponse.java index 5c3715d143..fb1112bc1d 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/list/ListAccessibleResourcesResponse.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/list/ListAccessibleResourcesResponse.java @@ -9,7 +9,7 @@ package org.opensearch.sample.actions.access.list; import java.io.IOException; -import java.util.List; +import java.util.Set; import org.opensearch.core.action.ActionResponse; import org.opensearch.core.common.io.stream.StreamInput; @@ -21,9 +21,9 @@ * Response to a ListAccessibleResourcesRequest */ public class ListAccessibleResourcesResponse extends ActionResponse implements ToXContentObject { - private final List resourceIds; + private final Set resourceIds; - public ListAccessibleResourcesResponse(List resourceIds) { + public ListAccessibleResourcesResponse(Set resourceIds) { this.resourceIds = resourceIds; } @@ -33,7 +33,7 @@ public void writeTo(StreamOutput out) throws IOException { } public ListAccessibleResourcesResponse(final StreamInput in) throws IOException { - resourceIds = in.readStringList(); + resourceIds = in.readSet(StreamInput::readString); } @Override diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRequest.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRequest.java index 3b7b10f19a..e97a2d1244 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRequest.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRequest.java @@ -9,22 +9,23 @@ package org.opensearch.sample.actions.access.revoke; import java.io.IOException; -import java.util.List; import java.util.Map; +import java.util.Set; import org.opensearch.accesscontrol.resources.EntityType; 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 org.opensearch.sample.utils.Validation; public class RevokeResourceAccessRequest extends ActionRequest { private final String resourceId; - private final Map> revokeAccess; - private final List scopes; + private final Map> revokeAccess; + private final Set scopes; - public RevokeResourceAccessRequest(String resourceId, Map> revokeAccess, List scopes) { + public RevokeResourceAccessRequest(String resourceId, Map> revokeAccess, Set scopes) { this.resourceId = resourceId; this.revokeAccess = revokeAccess; this.scopes = scopes; @@ -32,8 +33,8 @@ public RevokeResourceAccessRequest(String resourceId, Map EntityType.valueOf(input.readString()), StreamInput::readStringList); - this.scopes = in.readStringList(); + this.revokeAccess = in.readMap(input -> EntityType.valueOf(input.readString()), input -> input.readSet(StreamInput::readString)); + this.scopes = in.readSet(StreamInput::readString); } @Override @@ -49,6 +50,11 @@ public void writeTo(final StreamOutput out) throws IOException { @Override public ActionRequestValidationException validate() { + + if (!(this.scopes == null)) { + return Validation.validateScopes(this.scopes); + } + return null; } @@ -56,11 +62,11 @@ public String getResourceId() { return resourceId; } - public Map> getRevokeAccess() { + public Map> getRevokeAccess() { return revokeAccess; } - public List getScopes() { + public Set getScopes() { return scopes; } } diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRestAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRestAction.java index 85a01d2234..3fe0a2329e 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRestAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRestAction.java @@ -12,6 +12,7 @@ import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; import org.opensearch.accesscontrol.resources.EntityType; @@ -47,8 +48,8 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli String resourceId = (String) source.get("resource_id"); @SuppressWarnings("unchecked") - Map> revokeSource = (Map>) source.get("entities"); - Map> revoke = revokeSource.entrySet().stream().collect(Collectors.toMap(entry -> { + Map> revokeSource = (Map>) source.get("entities"); + Map> revoke = revokeSource.entrySet().stream().collect(Collectors.toMap(entry -> { try { return EntityType.fromValue(entry.getKey()); } catch (IllegalArgumentException e) { @@ -58,7 +59,7 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli } }, Map.Entry::getValue)); @SuppressWarnings("unchecked") - List scopes = source.containsKey("scopes") ? (List) source.get("scopes") : List.of(); + Set scopes = source.containsKey("scopes") ? (Set) source.get("scopes") : Set.of(); final RevokeResourceAccessRequest revokeResourceAccessRequest = new RevokeResourceAccessRequest(resourceId, revoke, scopes); return channel -> client.executeLocally( RevokeResourceAccessAction.INSTANCE, diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/share/ShareResourceRequest.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/share/ShareResourceRequest.java index b222364c0c..6c2ed12e73 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/share/ShareResourceRequest.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/share/ShareResourceRequest.java @@ -9,7 +9,7 @@ package org.opensearch.sample.actions.access.share; import java.io.IOException; -import java.util.Arrays; +import java.util.stream.Collectors; import org.opensearch.accesscontrol.resources.ShareWith; import org.opensearch.accesscontrol.resources.SharedWithScope; @@ -17,7 +17,7 @@ import org.opensearch.action.ActionRequestValidationException; import org.opensearch.core.common.io.stream.StreamInput; import org.opensearch.core.common.io.stream.StreamOutput; -import org.opensearch.sample.SampleResourceScope; +import org.opensearch.sample.utils.Validation; public class ShareResourceRequest extends ActionRequest { @@ -43,19 +43,9 @@ public void writeTo(final StreamOutput out) throws IOException { @Override public ActionRequestValidationException validate() { - for (SharedWithScope s : shareWith.getSharedWithScopes()) { - try { - SampleResourceScope.valueOf(s.getScope()); - } catch (IllegalArgumentException | NullPointerException e) { - ActionRequestValidationException exception = new ActionRequestValidationException(); - exception.addValidationError( - "Invalid scope: " + s.getScope() + ". Scope must be one of: " + Arrays.toString(SampleResourceScope.values()) - ); - return exception; - } - return null; - } - return null; + return Validation.validateScopes( + shareWith.getSharedWithScopes().stream().map(SharedWithScope::getScope).collect(Collectors.toSet()) + ); } public String getResourceId() { diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/verify/VerifyResourceAccessRequest.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/verify/VerifyResourceAccessRequest.java index 87c5b5a7f0..b9ab4134c6 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/verify/VerifyResourceAccessRequest.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/verify/VerifyResourceAccessRequest.java @@ -9,13 +9,13 @@ package org.opensearch.sample.actions.access.verify; import java.io.IOException; -import java.util.Arrays; +import java.util.Set; 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 org.opensearch.sample.SampleResourceScope; +import org.opensearch.sample.utils.Validation; public class VerifyResourceAccessRequest extends ActionRequest { @@ -49,16 +49,7 @@ public void writeTo(final StreamOutput out) throws IOException { @Override public ActionRequestValidationException validate() { - try { - SampleResourceScope.valueOf(scope); - } catch (IllegalArgumentException | NullPointerException e) { - ActionRequestValidationException exception = new ActionRequestValidationException(); - exception.addValidationError( - "Invalid scope: " + scope + ". Scope must be one of: " + Arrays.toString(SampleResourceScope.values()) - ); - return exception; - } - return null; + return Validation.validateScopes(Set.of(scope)); } public String getResourceId() { diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/ListAccessibleResourcesTransportAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/ListAccessibleResourcesTransportAction.java index 794675d3f3..2ca748c7d5 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/ListAccessibleResourcesTransportAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/ListAccessibleResourcesTransportAction.java @@ -8,7 +8,7 @@ package org.opensearch.sample.transport.access; -import java.util.List; +import java.util.Set; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -41,7 +41,7 @@ public ListAccessibleResourcesTransportAction(TransportService transportService, protected void doExecute(Task task, ListAccessibleResourcesRequest request, ActionListener listener) { try { ResourceService rs = SampleResourcePlugin.GuiceHolder.getResourceService(); - List resourceIds = rs.getResourceAccessControlPlugin().listAccessibleResourcesInPlugin(RESOURCE_INDEX_NAME); + Set resourceIds = rs.getResourceAccessControlPlugin().listAccessibleResourcesInPlugin(RESOURCE_INDEX_NAME); log.info("Successfully fetched accessible resources for current user : {}", resourceIds); listener.onResponse(new ListAccessibleResourcesResponse(resourceIds)); } catch (Exception e) { diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/utils/Validation.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/utils/Validation.java new file mode 100644 index 0000000000..13d7761584 --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/utils/Validation.java @@ -0,0 +1,32 @@ +/* + * 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.utils; + +import java.util.Arrays; +import java.util.Set; + +import org.opensearch.action.ActionRequestValidationException; +import org.opensearch.sample.SampleResourceScope; + +public class Validation { + public static ActionRequestValidationException validateScopes(Set scopes) { + for (String s : scopes) { + try { + SampleResourceScope.valueOf(s); + } catch (IllegalArgumentException | NullPointerException e) { + ActionRequestValidationException exception = new ActionRequestValidationException(); + exception.addValidationError( + "Invalid scope: " + s + ". Scope must be one of: " + Arrays.toString(SampleResourceScope.values()) + ); + return exception; + } + } + return null; + } +} From bfc39ad849d3a6b583d4d5bb4ca83838ff838224 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Thu, 5 Dec 2024 19:05:07 -0500 Subject: [PATCH 08/19] Adds default scopes to validation list Signed-off-by: Darshit Chanpura --- .../opensearch/sample/utils/Validation.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/utils/Validation.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/utils/Validation.java index 13d7761584..a057d41eed 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/utils/Validation.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/utils/Validation.java @@ -8,22 +8,26 @@ package org.opensearch.sample.utils; -import java.util.Arrays; +import java.util.HashSet; import java.util.Set; +import org.opensearch.accesscontrol.resources.ResourceAccessScope; import org.opensearch.action.ActionRequestValidationException; import org.opensearch.sample.SampleResourceScope; public class Validation { public static ActionRequestValidationException validateScopes(Set scopes) { + Set validScopes = new HashSet<>(); + for (SampleResourceScope scope : SampleResourceScope.values()) { + validScopes.add(scope.name()); + } + validScopes.add(ResourceAccessScope.READ_ONLY); + validScopes.add(ResourceAccessScope.READ_WRITE); + for (String s : scopes) { - try { - SampleResourceScope.valueOf(s); - } catch (IllegalArgumentException | NullPointerException e) { + if (!validScopes.contains(s)) { ActionRequestValidationException exception = new ActionRequestValidationException(); - exception.addValidationError( - "Invalid scope: " + s + ". Scope must be one of: " + Arrays.toString(SampleResourceScope.values()) - ); + exception.addValidationError("Invalid scope: " + s + ". Scope must be one of: " + validScopes); return exception; } } From acc22c4ea9ca018916b1b619444b8aabfb0e0abe Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Thu, 5 Dec 2024 19:16:27 -0500 Subject: [PATCH 09/19] Fixes ClassCastException Signed-off-by: Darshit Chanpura --- .../access/revoke/RevokeResourceAccessRestAction.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRestAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRestAction.java index 3fe0a2329e..1145457863 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRestAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRestAction.java @@ -9,10 +9,7 @@ package org.opensearch.sample.actions.access.revoke; import java.io.IOException; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; import org.opensearch.accesscontrol.resources.EntityType; @@ -59,7 +56,7 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli } }, Map.Entry::getValue)); @SuppressWarnings("unchecked") - Set scopes = source.containsKey("scopes") ? (Set) source.get("scopes") : Set.of(); + Set scopes = new HashSet<>(source.containsKey("scopes") ? (List) source.get("scopes") : List.of()); final RevokeResourceAccessRequest revokeResourceAccessRequest = new RevokeResourceAccessRequest(resourceId, revoke, scopes); return channel -> client.executeLocally( RevokeResourceAccessAction.INSTANCE, From 4dc7597d452f0b3d799e46bd95506cb061fbea9d Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Sat, 7 Dec 2024 18:28:27 -0500 Subject: [PATCH 10/19] Adds plugin specific exception class Signed-off-by: Darshit Chanpura --- .../access/ShareResourceTransportAction.java | 27 +++++++++---------- .../utils/SampleResourcePluginException.java | 17 ++++++++++++ 2 files changed, 30 insertions(+), 14 deletions(-) create mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/utils/SampleResourcePluginException.java diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/ShareResourceTransportAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/ShareResourceTransportAction.java index e99a9abf24..3288352d0b 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/ShareResourceTransportAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/ShareResourceTransportAction.java @@ -21,6 +21,7 @@ import org.opensearch.sample.actions.access.share.ShareResourceAction; import org.opensearch.sample.actions.access.share.ShareResourceRequest; import org.opensearch.sample.actions.access.share.ShareResourceResponse; +import org.opensearch.sample.utils.SampleResourcePluginException; import org.opensearch.tasks.Task; import org.opensearch.transport.TransportService; @@ -36,26 +37,24 @@ public ShareResourceTransportAction(TransportService transportService, ActionFil @Override protected void doExecute(Task task, ShareResourceRequest request, ActionListener listener) { + ResourceSharing sharing = null; try { - shareResource(request); + sharing = shareResource(request); + if (sharing == null) { + log.error("Failed to share resource {}", request.getResourceId()); + SampleResourcePluginException se = new SampleResourcePluginException("Failed to share resource " + request.getResourceId()); + listener.onFailure(se); + return; + } + log.info("Shared resource : {} with {}", request.getResourceId(), sharing.toString()); listener.onResponse(new ShareResourceResponse("Resource " + request.getResourceId() + " shared successfully.")); } catch (Exception e) { listener.onFailure(e); } } - private void shareResource(ShareResourceRequest request) throws Exception { - try { - ResourceService rs = SampleResourcePlugin.GuiceHolder.getResourceService(); - ResourceSharing sharing = rs.getResourceAccessControlPlugin() - .shareWith(request.getResourceId(), RESOURCE_INDEX_NAME, request.getShareWith()); - if (sharing == null) { - throw new Exception("Failed to share resource " + request.getResourceId()); - } - log.info("Shared resource : {} with {}", request.getResourceId(), sharing.toString()); - } catch (Exception e) { - log.info("Failed to share resource {}", request.getResourceId(), e); - throw e; - } + private ResourceSharing shareResource(ShareResourceRequest request) throws Exception { + ResourceService rs = SampleResourcePlugin.GuiceHolder.getResourceService(); + return rs.getResourceAccessControlPlugin().shareWith(request.getResourceId(), RESOURCE_INDEX_NAME, request.getShareWith()); } } diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/utils/SampleResourcePluginException.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/utils/SampleResourcePluginException.java new file mode 100644 index 0000000000..1ac2baaaae --- /dev/null +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/utils/SampleResourcePluginException.java @@ -0,0 +1,17 @@ +/* + * 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.utils; + +import org.opensearch.OpenSearchException; + +public class SampleResourcePluginException extends OpenSearchException { + public SampleResourcePluginException(String msg, Object... args) { + super(msg, args); + } +} From 034953732f352d1a4cc4e87a71acbf6da197ea7a Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Sat, 7 Dec 2024 19:20:02 -0500 Subject: [PATCH 11/19] Fixes NPE Signed-off-by: Darshit Chanpura --- .../RevokeResourceAccessTransportAction.java | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/RevokeResourceAccessTransportAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/RevokeResourceAccessTransportAction.java index dd7757e4f2..027e1fffe3 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/RevokeResourceAccessTransportAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/RevokeResourceAccessTransportAction.java @@ -21,6 +21,7 @@ import org.opensearch.sample.actions.access.revoke.RevokeResourceAccessAction; import org.opensearch.sample.actions.access.revoke.RevokeResourceAccessRequest; import org.opensearch.sample.actions.access.revoke.RevokeResourceAccessResponse; +import org.opensearch.sample.utils.SampleResourcePluginException; import org.opensearch.tasks.Task; import org.opensearch.transport.TransportService; @@ -37,22 +38,25 @@ public RevokeResourceAccessTransportAction(TransportService transportService, Ac @Override protected void doExecute(Task task, RevokeResourceAccessRequest request, ActionListener listener) { try { - revokeAccess(request); + ResourceSharing revoke = revokeAccess(request); + if (revoke == null) { + log.error("Failed to revoke access to resource {}", request.getResourceId()); + SampleResourcePluginException se = new SampleResourcePluginException( + "Failed to revoke access to resource " + request.getResourceId() + ); + listener.onFailure(se); + return; + } + log.info("Revoked resource access for resource: {} with {}", request.getResourceId(), revoke.toString()); listener.onResponse(new RevokeResourceAccessResponse("Resource " + request.getResourceId() + " access revoked successfully.")); } catch (Exception e) { listener.onFailure(e); } } - private void revokeAccess(RevokeResourceAccessRequest request) { - try { - ResourceService rs = SampleResourcePlugin.GuiceHolder.getResourceService(); - ResourceSharing revoke = rs.getResourceAccessControlPlugin() - .revokeAccess(request.getResourceId(), RESOURCE_INDEX_NAME, request.getRevokeAccess(), request.getScopes()); - log.info("Revoked resource access for resource: {} with {}", request.getResourceId(), revoke.toString()); - } catch (Exception e) { - log.info("Failed to revoke access for resource {}", request.getResourceId(), e); - throw e; - } + private ResourceSharing revokeAccess(RevokeResourceAccessRequest request) { + ResourceService rs = SampleResourcePlugin.GuiceHolder.getResourceService(); + return rs.getResourceAccessControlPlugin() + .revokeAccess(request.getResourceId(), RESOURCE_INDEX_NAME, request.getRevokeAccess(), request.getScopes()); } } From 334b50d438853d61b5409abc77de190151b01cc2 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Wed, 11 Dec 2024 15:38:51 -0500 Subject: [PATCH 12/19] Updates method name to corresponding to changes in core Signed-off-by: Darshit Chanpura --- sample-resource-plugin/README.md | 146 ++++++++++++++++++ .../sample/SampleResourcePlugin.java | 5 +- ...istAccessibleResourcesTransportAction.java | 2 +- 3 files changed, 148 insertions(+), 5 deletions(-) create mode 100644 sample-resource-plugin/README.md diff --git a/sample-resource-plugin/README.md b/sample-resource-plugin/README.md new file mode 100644 index 0000000000..d40d792f68 --- /dev/null +++ b/sample-resource-plugin/README.md @@ -0,0 +1,146 @@ +# Resource Sharing and Access Control Plugin + +This plugin demonstrates resource sharing and access control functionality, providing APIs to create, manage, and verify access to resources. The plugin enables fine-grained permissions for sharing and accessing resources, making it suitable for systems requiring robust security and collaboration. + +## Features + +- Create and delete resources. +- Share resources with specific users, roles and/or backend_roles with specific scope(s). +- Revoke access to shared resources for a list of or all scopes. +- Verify access permissions for a given user within a given scope. +- List all resources accessible to current user. + +## API Endpoints + +The plugin exposes the following six API endpoints: + +### 1. Create Resource +- **Endpoint:** `POST /_plugins/sample_resource_sharing/create` +- **Description:** Creates a new resource. Also creates a resource sharing entry if security plugin is enabled. +- **Request Body:** + ```json + { + "name": "" + } + ``` +- **Response:** + ```json + { + "resource_id": "", + "status": "created" + } + ``` + +### 2. Delete Resource +- **Endpoint:** `DELETE /api/resource/{resource_id}` +- **Description:** Deletes a specified resource owned by the requesting user. +- **Response:** + ```json + { + "resource_id": "", + "status": "deleted" + } + ``` + +### 3. Share Resource +- **Endpoint:** `POST /api/resource/{resource_id}/share` +- **Description:** Shares a resource with specified users or roles with defined permissions. +- **Request Body:** + ```json + { + "share_with": [ + { "type": "user", "id": "user123", "permission": "read_write" }, + { "type": "role", "id": "admin", "permission": "read_only" } + ] + } + ``` +- **Response:** + ```json + { + "resource_id": "", + "status": "shared" + } + ``` + +### 4. Revoke Access +- **Endpoint:** `DELETE /api/resource/{resource_id}/revoke` +- **Description:** Revokes access to a resource for specified users or roles. +- **Request Body:** + ```json + { + "revoke_from": [ "user123", "role:admin" ] + } + ``` +- **Response:** + ```json + { + "resource_id": "", + "status": "access_revoked" + } + ``` + +### 5. Verify Access +- **Endpoint:** `GET /api/resource/{resource_id}/verify` +- **Description:** Verifies if a user or role has access to a specific resource. +- **Query Parameters:** + - `user_id` (optional): ID of the user. + - `role` (optional): Role to verify. +- **Response:** + ```json + { + "resource_id": "", + "access": true, + "permissions": "read_only" + } + ``` + +### 6. List Accessible Resources +- **Endpoint:** `GET /api/resources/accessible` +- **Description:** Lists all resources accessible to the requesting user or role. +- **Response:** + ```json + [ + { + "resource_id": "", + "name": "", + "permissions": "read_write" + }, + { + "resource_id": "", + "name": "", + "permissions": "read_only" + } + ] + ``` + +## Installation + +1. Clone the repository: + ```bash + git clone + ``` + +2. Navigate to the project directory: + ```bash + cd resource-access-plugin + ``` + +3. Build and deploy the plugin: + ```bash + + ``` + +4. Configure the plugin in your environment. + +## Configuration + +- Ensure that the appropriate access control settings are enabled in your system. +- Define user roles and permissions to match your use case. + +## License + +This code is licensed under the Apache 2.0 License. + +## Copyright + +Copyright OpenSearch Contributors. 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 90a62f7286..3119e2203a 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 @@ -76,8 +76,6 @@ public class SampleResourcePlugin extends Plugin implements ActionPlugin, SystemIndexPlugin, ResourcePlugin { private static final Logger log = LogManager.getLogger(SampleResourcePlugin.class); - private Client client; - @Override public Collection createComponents( Client client, @@ -92,7 +90,6 @@ public Collection createComponents( IndexNameExpressionResolver indexNameExpressionResolver, Supplier repositoriesServiceSupplier ) { - this.client = client; log.info("Loaded SampleResourcePlugin components."); return Collections.emptyList(); } @@ -131,7 +128,7 @@ public List getRestHandlers( @Override public Collection getSystemIndexDescriptors(Settings settings) { - final SystemIndexDescriptor systemIndexDescriptor = new SystemIndexDescriptor(RESOURCE_INDEX_NAME, "Example index with resources"); + final SystemIndexDescriptor systemIndexDescriptor = new SystemIndexDescriptor(RESOURCE_INDEX_NAME, "Sample index with resources"); return Collections.singletonList(systemIndexDescriptor); } diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/ListAccessibleResourcesTransportAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/ListAccessibleResourcesTransportAction.java index 2ca748c7d5..2c021d6c27 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/ListAccessibleResourcesTransportAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/ListAccessibleResourcesTransportAction.java @@ -41,7 +41,7 @@ public ListAccessibleResourcesTransportAction(TransportService transportService, protected void doExecute(Task task, ListAccessibleResourcesRequest request, ActionListener listener) { try { ResourceService rs = SampleResourcePlugin.GuiceHolder.getResourceService(); - Set resourceIds = rs.getResourceAccessControlPlugin().listAccessibleResourcesInPlugin(RESOURCE_INDEX_NAME); + Set resourceIds = rs.getResourceAccessControlPlugin().getAccessibleResourcesForCurrentUser(RESOURCE_INDEX_NAME); log.info("Successfully fetched accessible resources for current user : {}", resourceIds); listener.onResponse(new ListAccessibleResourcesResponse(resourceIds)); } catch (Exception e) { From 0f60c917a319356490fd277ef3228edec1ec7d5a Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Wed, 11 Dec 2024 16:09:31 -0500 Subject: [PATCH 13/19] Updates API route Signed-off-by: Darshit Chanpura --- .../actions/access/list/ListAccessibleResourcesRestAction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/list/ListAccessibleResourcesRestAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/list/ListAccessibleResourcesRestAction.java index 2eee67e0f1..c387eacf90 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/list/ListAccessibleResourcesRestAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/list/ListAccessibleResourcesRestAction.java @@ -24,7 +24,7 @@ public ListAccessibleResourcesRestAction() {} @Override public List routes() { - return singletonList(new Route(GET, "/_plugins/sample_resource_sharing/resource")); + return singletonList(new Route(GET, "/_plugins/sample_resource_sharing/list")); } @Override From 5ca5dec141e1a5aa0e2d05f84705db9eb023b0d7 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Wed, 11 Dec 2024 16:09:44 -0500 Subject: [PATCH 14/19] Adds README Signed-off-by: Darshit Chanpura --- sample-resource-plugin/README.md | 118 ++++++++++++++++--------------- 1 file changed, 62 insertions(+), 56 deletions(-) diff --git a/sample-resource-plugin/README.md b/sample-resource-plugin/README.md index d40d792f68..ccd73db983 100644 --- a/sample-resource-plugin/README.md +++ b/sample-resource-plugin/README.md @@ -26,117 +26,123 @@ The plugin exposes the following six API endpoints: - **Response:** ```json { - "resource_id": "", - "status": "created" + "message": "Resource created successfully." } ``` ### 2. Delete Resource -- **Endpoint:** `DELETE /api/resource/{resource_id}` +- **Endpoint:** `DELETE /_plugins/sample_resource_sharing/{resource_id}` - **Description:** Deletes a specified resource owned by the requesting user. - **Response:** ```json { - "resource_id": "", - "status": "deleted" + "message": "Resource deleted successfully." } ``` ### 3. Share Resource -- **Endpoint:** `POST /api/resource/{resource_id}/share` -- **Description:** Shares a resource with specified users or roles with defined permissions. +- **Endpoint:** `POST /_plugins/sample_resource_sharing/share` +- **Description:** Shares a resource with specified users or roles with defined scope. - **Request Body:** ```json - { - "share_with": [ - { "type": "user", "id": "user123", "permission": "read_write" }, - { "type": "role", "id": "admin", "permission": "read_only" } - ] - } + { + "resource_id" : "{{ADMIN_RESOURCE_ID}}", + "share_with" : { + "SAMPLE_FULL_ACCESS": { + "users": ["test"], + "roles": ["test_role"], + "backend_roles": ["test_backend_role"] + }, + "READ_ONLY": { + "users": ["test"], + "roles": ["test_role"], + "backend_roles": ["test_backend_role"] + }, + "READ_WRITE": { + "users": ["test"], + "roles": ["test_role"], + "backend_roles": ["test_backend_role"] + } + } + } ``` - **Response:** ```json - { - "resource_id": "", - "status": "shared" - } + { + "message": "Resource shared successfully." + } ``` ### 4. Revoke Access -- **Endpoint:** `DELETE /api/resource/{resource_id}/revoke` +- **Endpoint:** `POST /_plugins/sample_resource_sharing/revoke` - **Description:** Revokes access to a resource for specified users or roles. - **Request Body:** ```json - { - "revoke_from": [ "user123", "role:admin" ] - } + { + "resource_id" : "", + "entities" : { + "users": ["test", "admin"], + "roles": ["test_role", "all_access"], + "backend_roles": ["test_backend_role", "admin"] + }, + "scopes": ["SAMPLE_FULL_ACCESS", "READ_ONLY", "READ_WRITE"] + } ``` - **Response:** ```json - { - "resource_id": "", - "status": "access_revoked" - } + { + "message": "Resource access revoked successfully." + } ``` ### 5. Verify Access -- **Endpoint:** `GET /api/resource/{resource_id}/verify` -- **Description:** Verifies if a user or role has access to a specific resource. -- **Query Parameters:** - - `user_id` (optional): ID of the user. - - `role` (optional): Role to verify. +- **Endpoint:** `GET /_plugins/sample_resource_sharing/verify_resource_access` +- **Description:** Verifies if a user or role has access to a specific resource with a specific scope. +- **Request Body:** + ```json + { + "resource_id": "", + "scope": "SAMPLE_FULL_ACCESS" + } + ``` - **Response:** ```json { - "resource_id": "", - "access": true, - "permissions": "read_only" + "message": "User has requested scope SAMPLE_FULL_ACCESS access to " } ``` ### 6. List Accessible Resources -- **Endpoint:** `GET /api/resources/accessible` +- **Endpoint:** `GET /_plugins/sample_resource_sharing/list` - **Description:** Lists all resources accessible to the requesting user or role. - **Response:** ```json - [ - { - "resource_id": "", - "name": "", - "permissions": "read_write" - }, - { - "resource_id": "", - "name": "", - "permissions": "read_only" - } - ] + { + "resource-ids": [ + "", + "" + ] + } ``` ## Installation 1. Clone the repository: ```bash - git clone + git clone git@github.com:opensearch-project/security.git ``` 2. Navigate to the project directory: ```bash - cd resource-access-plugin + cd sample-resource-plugin ``` 3. Build and deploy the plugin: ```bash - + $ ./gradlew clean build -x test -x integrationTest -x spotbugsIntegrationTest + $ ./bin/opensearch-plugin install file: /sample-resource-plugin/build/distributions/opensearch-sample-resource-plugin-3.0.0.0-SNAPSHOT.zip ``` -4. Configure the plugin in your environment. - -## Configuration - -- Ensure that the appropriate access control settings are enabled in your system. -- Define user roles and permissions to match your use case. - ## License This code is licensed under the Apache 2.0 License. From ca377f6311b6b9adc0d44baeac3a8184c9c3d459 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Thu, 12 Dec 2024 17:25:45 -0500 Subject: [PATCH 15/19] Returns actual resource when listing the resource Signed-off-by: Darshit Chanpura --- .../resource/create => }/SampleResource.java | 5 ++--- .../list/ListAccessibleResourcesResponse.java | 13 +++++++------ .../resource/create/CreateResourceRestAction.java | 1 + .../ListAccessibleResourcesTransportAction.java | 8 +++++--- 4 files changed, 15 insertions(+), 12 deletions(-) rename sample-resource-plugin/src/main/java/org/opensearch/sample/{actions/resource/create => }/SampleResource.java (90%) diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/SampleResource.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/SampleResource.java similarity index 90% rename from sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/SampleResource.java rename to sample-resource-plugin/src/main/java/org/opensearch/sample/SampleResource.java index db475b7018..07441d96b8 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/SampleResource.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/SampleResource.java @@ -9,14 +9,13 @@ * GitHub history for details. */ -package org.opensearch.sample.actions.resource.create; +package org.opensearch.sample; import java.io.IOException; import org.opensearch.core.common.io.stream.StreamInput; import org.opensearch.core.common.io.stream.StreamOutput; import org.opensearch.core.xcontent.XContentBuilder; -import org.opensearch.sample.Resource; import static org.opensearch.sample.utils.Constants.RESOURCE_INDEX_NAME; @@ -26,7 +25,7 @@ public class SampleResource implements Resource { public SampleResource() {} - SampleResource(StreamInput in) throws IOException { + public SampleResource(StreamInput in) throws IOException { this.name = in.readString(); } diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/list/ListAccessibleResourcesResponse.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/list/ListAccessibleResourcesResponse.java index fb1112bc1d..9c5d2a3e8a 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/list/ListAccessibleResourcesResponse.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/list/ListAccessibleResourcesResponse.java @@ -16,30 +16,31 @@ import org.opensearch.core.common.io.stream.StreamOutput; import org.opensearch.core.xcontent.ToXContentObject; import org.opensearch.core.xcontent.XContentBuilder; +import org.opensearch.sample.SampleResource; /** * Response to a ListAccessibleResourcesRequest */ public class ListAccessibleResourcesResponse extends ActionResponse implements ToXContentObject { - private final Set resourceIds; + private final Set resources; - public ListAccessibleResourcesResponse(Set resourceIds) { - this.resourceIds = resourceIds; + public ListAccessibleResourcesResponse(Set resources) { + this.resources = resources; } @Override public void writeTo(StreamOutput out) throws IOException { - out.writeStringArray(resourceIds.toArray(new String[0])); + out.writeCollection(resources); } public ListAccessibleResourcesResponse(final StreamInput in) throws IOException { - resourceIds = in.readSet(StreamInput::readString); + this.resources = in.readSet(SampleResource::new); } @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(); - builder.field("resource-ids", resourceIds); + builder.field("resources", resources); builder.endObject(); return builder; } diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/CreateResourceRestAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/CreateResourceRestAction.java index 171c539a7c..f56f61d010 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/CreateResourceRestAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/CreateResourceRestAction.java @@ -17,6 +17,7 @@ import org.opensearch.rest.BaseRestHandler; import org.opensearch.rest.RestRequest; import org.opensearch.rest.action.RestToXContentListener; +import org.opensearch.sample.SampleResource; import static java.util.Collections.singletonList; import static org.opensearch.rest.RestRequest.Method.POST; diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/ListAccessibleResourcesTransportAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/ListAccessibleResourcesTransportAction.java index 2c021d6c27..57c2c7889f 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/ListAccessibleResourcesTransportAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/access/ListAccessibleResourcesTransportAction.java @@ -18,6 +18,7 @@ import org.opensearch.action.support.HandledTransportAction; import org.opensearch.common.inject.Inject; import org.opensearch.core.action.ActionListener; +import org.opensearch.sample.SampleResource; import org.opensearch.sample.SampleResourcePlugin; import org.opensearch.sample.actions.access.list.ListAccessibleResourcesAction; import org.opensearch.sample.actions.access.list.ListAccessibleResourcesRequest; @@ -41,9 +42,10 @@ public ListAccessibleResourcesTransportAction(TransportService transportService, protected void doExecute(Task task, ListAccessibleResourcesRequest request, ActionListener listener) { try { ResourceService rs = SampleResourcePlugin.GuiceHolder.getResourceService(); - Set resourceIds = rs.getResourceAccessControlPlugin().getAccessibleResourcesForCurrentUser(RESOURCE_INDEX_NAME); - log.info("Successfully fetched accessible resources for current user : {}", resourceIds); - listener.onResponse(new ListAccessibleResourcesResponse(resourceIds)); + Set resources = rs.getResourceAccessControlPlugin() + .getAccessibleResourcesForCurrentUser(RESOURCE_INDEX_NAME, SampleResource.class); + log.info("Successfully fetched accessible resources for current user : {}", resources); + listener.onResponse(new ListAccessibleResourcesResponse(resources)); } catch (Exception e) { log.info("Failed to list accessible resources for current user: ", e); listener.onFailure(e); From 8845812df90124f0e4043bf32daa752cc06d8623 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Fri, 13 Dec 2024 13:06:04 -0500 Subject: [PATCH 16/19] Updates SampleResource class structure Signed-off-by: Darshit Chanpura --- .../org/opensearch/sample/SampleResource.java | 21 ++++++++++++++++--- .../create/CreateResourceRestAction.java | 4 ++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/SampleResource.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/SampleResource.java index 07441d96b8..c384dc770e 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/SampleResource.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/SampleResource.java @@ -12,6 +12,7 @@ package org.opensearch.sample; import java.io.IOException; +import java.util.Map; import org.opensearch.core.common.io.stream.StreamInput; import org.opensearch.core.common.io.stream.StreamOutput; @@ -22,11 +23,15 @@ public class SampleResource implements Resource { private String name; + private String description; + private Map attributes; public SampleResource() {} public SampleResource(StreamInput in) throws IOException { this.name = in.readString(); + this.description = in.readString(); + this.attributes = in.readMap(StreamInput::readString, StreamInput::readString); } @Override @@ -41,12 +46,14 @@ public String getResourceName() { @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - return builder.startObject().field("name", name).endObject(); + return builder.startObject().field("name", name).field("description", description).field("attributes", attributes).endObject(); } @Override - public void writeTo(StreamOutput streamOutput) throws IOException { - streamOutput.writeString(name); + public void writeTo(StreamOutput out) throws IOException { + out.writeString(name); + out.writeString(description); + out.writeMap(attributes, StreamOutput::writeString, StreamOutput::writeString); } @Override @@ -57,4 +64,12 @@ public String getWriteableName() { public void setName(String name) { this.name = name; } + + public void setDescription(String description) { + this.description = description; + } + + public void setAttributes(Map attributes) { + this.attributes = attributes; + } } diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/CreateResourceRestAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/CreateResourceRestAction.java index f56f61d010..f7aa1c76b5 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/CreateResourceRestAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/CreateResourceRestAction.java @@ -44,8 +44,12 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli } String name = (String) source.get("name"); + String description = source.containsKey("description") ? (String) source.get("description") : null; + Map attributes = source.containsKey("attributes") ? (Map) source.get("attributes") : null; SampleResource resource = new SampleResource(); resource.setName(name); + resource.setDescription(description); + resource.setAttributes(attributes); final CreateResourceRequest createSampleResourceRequest = new CreateResourceRequest(resource); return channel -> client.executeLocally( CreateResourceAction.INSTANCE, From 6269d940dd817be2a4a55212e2ef38c5849af235 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Fri, 20 Dec 2024 12:02:32 -0500 Subject: [PATCH 17/19] Adds new scope named public Signed-off-by: Darshit Chanpura --- .../main/java/org/opensearch/sample/SampleResourceScope.java | 4 +++- .../transport/resource/DeleteResourceTransportAction.java | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/SampleResourceScope.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/SampleResourceScope.java index 90df0d3764..1d6de8c1f7 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/SampleResourceScope.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/SampleResourceScope.java @@ -19,7 +19,9 @@ */ public enum SampleResourceScope implements ResourceAccessScope { - SAMPLE_FULL_ACCESS("sample_full_access"); + SAMPLE_FULL_ACCESS("sample_full_access"), + + PUBLIC("public"); private final String name; diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/resource/DeleteResourceTransportAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/resource/DeleteResourceTransportAction.java index bdc19ab8b3..bb403e3704 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/resource/DeleteResourceTransportAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/resource/DeleteResourceTransportAction.java @@ -54,9 +54,9 @@ protected void doExecute(Task task, DeleteResourceRequest request, ActionListene try (ThreadContext.StoredContext ignore = threadContext.stashContext()) { deleteResource(request, ActionListener.wrap(deleteResponse -> { if (deleteResponse.getResult() == DocWriteResponse.Result.NOT_FOUND) { - listener.onFailure(new ResourceNotFoundException("Resource " + request.getResourceId() + " not found")); + listener.onFailure(new ResourceNotFoundException("Resource " + request.getResourceId() + " not found.")); } else { - listener.onResponse(new DeleteResourceResponse("Resource " + request.getResourceId() + " deleted successfully")); + listener.onResponse(new DeleteResourceResponse("Resource " + request.getResourceId() + " deleted successfully.")); } }, exception -> { log.error("Failed to delete resource: " + request.getResourceId(), exception); From d8969e57d4ac9abfd7fb0c90553d702663b554ab Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Fri, 20 Dec 2024 12:44:05 -0500 Subject: [PATCH 18/19] Updates Resource type Signed-off-by: Darshit Chanpura --- .../java/org/opensearch/sample/Resource.java | 21 ------------------- .../org/opensearch/sample/SampleResource.java | 18 ++++++---------- .../create/CreateResourceRequest.java | 2 +- .../CreateResourceTransportAction.java | 2 +- 4 files changed, 8 insertions(+), 35 deletions(-) delete mode 100644 sample-resource-plugin/src/main/java/org/opensearch/sample/Resource.java diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/Resource.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/Resource.java deleted file mode 100644 index 4ddb56f395..0000000000 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/Resource.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - * - * Modifications Copyright OpenSearch Contributors. See - * GitHub history for details. - */ - -package org.opensearch.sample; - -import org.opensearch.core.common.io.stream.NamedWriteable; -import org.opensearch.core.xcontent.ToXContentFragment; - -public interface Resource extends NamedWriteable, ToXContentFragment { - String getResourceIndex(); - - String getResourceName(); -} diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/SampleResource.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/SampleResource.java index c384dc770e..abef02ff35 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/SampleResource.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/SampleResource.java @@ -14,12 +14,11 @@ import java.io.IOException; import java.util.Map; +import org.opensearch.accesscontrol.resources.Resource; import org.opensearch.core.common.io.stream.StreamInput; import org.opensearch.core.common.io.stream.StreamOutput; import org.opensearch.core.xcontent.XContentBuilder; -import static org.opensearch.sample.utils.Constants.RESOURCE_INDEX_NAME; - public class SampleResource implements Resource { private String name; @@ -34,16 +33,6 @@ public SampleResource(StreamInput in) throws IOException { this.attributes = in.readMap(StreamInput::readString, StreamInput::readString); } - @Override - public String getResourceIndex() { - return RESOURCE_INDEX_NAME; - } - - @Override - public String getResourceName() { - return this.name; - } - @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { return builder.startObject().field("name", name).field("description", description).field("attributes", attributes).endObject(); @@ -72,4 +61,9 @@ public void setDescription(String description) { public void setAttributes(Map attributes) { this.attributes = attributes; } + + @Override + public String getResourceName() { + return name; + } } diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/CreateResourceRequest.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/CreateResourceRequest.java index 3f330d9719..abad5cd1c3 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/CreateResourceRequest.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/resource/create/CreateResourceRequest.java @@ -10,11 +10,11 @@ import java.io.IOException; +import org.opensearch.accesscontrol.resources.Resource; 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 org.opensearch.sample.Resource; /** * Request object for CreateSampleResource transport action diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/resource/CreateResourceTransportAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/resource/CreateResourceTransportAction.java index 9a764b61de..052783a90b 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/resource/CreateResourceTransportAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/transport/resource/CreateResourceTransportAction.java @@ -13,6 +13,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.opensearch.accesscontrol.resources.Resource; import org.opensearch.action.index.IndexRequest; import org.opensearch.action.support.ActionFilters; import org.opensearch.action.support.HandledTransportAction; @@ -23,7 +24,6 @@ import org.opensearch.core.action.ActionListener; import org.opensearch.core.xcontent.ToXContent; import org.opensearch.core.xcontent.XContentBuilder; -import org.opensearch.sample.Resource; import org.opensearch.sample.actions.resource.create.CreateResourceAction; import org.opensearch.sample.actions.resource.create.CreateResourceRequest; import org.opensearch.sample.actions.resource.create.CreateResourceResponse; From 413bb0b92ab353dcb4ac9fc5e244ad268dab4e43 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Mon, 30 Dec 2024 21:21:19 -0500 Subject: [PATCH 19/19] Conforms to changes in core Signed-off-by: Darshit Chanpura --- .../revoke/RevokeResourceAccessRequest.java | 12 ++++++------ .../revoke/RevokeResourceAccessRestAction.java | 15 +++++---------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRequest.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRequest.java index e97a2d1244..f7b4e7b5d7 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRequest.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRequest.java @@ -12,7 +12,7 @@ import java.util.Map; import java.util.Set; -import org.opensearch.accesscontrol.resources.EntityType; +import org.opensearch.accesscontrol.resources.RecipientType; import org.opensearch.action.ActionRequest; import org.opensearch.action.ActionRequestValidationException; import org.opensearch.core.common.io.stream.StreamInput; @@ -22,10 +22,10 @@ public class RevokeResourceAccessRequest extends ActionRequest { private final String resourceId; - private final Map> revokeAccess; + private final Map> revokeAccess; private final Set scopes; - public RevokeResourceAccessRequest(String resourceId, Map> revokeAccess, Set scopes) { + public RevokeResourceAccessRequest(String resourceId, Map> revokeAccess, Set scopes) { this.resourceId = resourceId; this.revokeAccess = revokeAccess; this.scopes = scopes; @@ -33,7 +33,7 @@ public RevokeResourceAccessRequest(String resourceId, Map EntityType.valueOf(input.readString()), input -> input.readSet(StreamInput::readString)); + this.revokeAccess = in.readMap(input -> new RecipientType(input.readString()), input -> input.readSet(StreamInput::readString)); this.scopes = in.readSet(StreamInput::readString); } @@ -42,7 +42,7 @@ public void writeTo(final StreamOutput out) throws IOException { out.writeString(resourceId); out.writeMap( revokeAccess, - (streamOutput, entityType) -> streamOutput.writeString(entityType.name()), + (streamOutput, recipientType) -> streamOutput.writeString(recipientType.getType()), StreamOutput::writeStringCollection ); out.writeStringCollection(scopes); @@ -62,7 +62,7 @@ public String getResourceId() { return resourceId; } - public Map> getRevokeAccess() { + public Map> getRevokeAccess() { return revokeAccess; } diff --git a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRestAction.java b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRestAction.java index 1145457863..387d02502f 100644 --- a/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRestAction.java +++ b/sample-resource-plugin/src/main/java/org/opensearch/sample/actions/access/revoke/RevokeResourceAccessRestAction.java @@ -12,7 +12,8 @@ import java.util.*; import java.util.stream.Collectors; -import org.opensearch.accesscontrol.resources.EntityType; +import org.opensearch.accesscontrol.resources.RecipientType; +import org.opensearch.accesscontrol.resources.RecipientTypeRegistry; import org.opensearch.client.node.NodeClient; import org.opensearch.core.xcontent.XContentParser; import org.opensearch.rest.BaseRestHandler; @@ -46,15 +47,9 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli String resourceId = (String) source.get("resource_id"); @SuppressWarnings("unchecked") Map> revokeSource = (Map>) source.get("entities"); - Map> revoke = revokeSource.entrySet().stream().collect(Collectors.toMap(entry -> { - try { - return EntityType.fromValue(entry.getKey()); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException( - "Invalid entity type: " + entry.getKey() + ". Valid values are: " + Arrays.toString(EntityType.values()) - ); - } - }, Map.Entry::getValue)); + Map> revoke = revokeSource.entrySet() + .stream() + .collect(Collectors.toMap(entry -> RecipientTypeRegistry.fromValue(entry.getKey()), Map.Entry::getValue)); @SuppressWarnings("unchecked") Set scopes = new HashSet<>(source.containsKey("scopes") ? (List) source.get("scopes") : List.of()); final RevokeResourceAccessRequest revokeResourceAccessRequest = new RevokeResourceAccessRequest(resourceId, revoke, scopes);