From 52b980e2a9ac9e4ffbd427d7efba5970da1169b0 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Fri, 18 Aug 2023 16:54:39 -0400 Subject: [PATCH 01/13] Base setup for dummy plugin for E2E testing Signed-off-by: Darshit Chanpura --- .../testplugins/CustomTestPlugin.java | 51 ++++++++++ .../testplugins/DummyRestHandler.java | 99 +++++++++++++++++++ .../testplugins/dummyaction/DummyAction.java | 39 ++++++++ .../testplugins/dummyaction/DummyRequest.java | 43 ++++++++ .../dummyaction/DummyRequestBuilder.java | 43 ++++++++ .../dummyaction/DummyResponse.java | 78 +++++++++++++++ .../dummyaction/TransportDummyAction.java | 51 ++++++++++ 7 files changed, 404 insertions(+) create mode 100644 src/integrationTest/java/org/opensearch/test/framework/testplugins/CustomTestPlugin.java create mode 100644 src/integrationTest/java/org/opensearch/test/framework/testplugins/DummyRestHandler.java create mode 100644 src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyAction.java create mode 100644 src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyRequest.java create mode 100644 src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyRequestBuilder.java create mode 100644 src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyResponse.java create mode 100644 src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/TransportDummyAction.java diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/CustomTestPlugin.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/CustomTestPlugin.java new file mode 100644 index 0000000000..361a4cb3f7 --- /dev/null +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/CustomTestPlugin.java @@ -0,0 +1,51 @@ +package org.opensearch.test.framework.testplugins; + +import org.opensearch.action.ActionRequest; +import org.opensearch.cluster.metadata.IndexNameExpressionResolver; +import org.opensearch.cluster.node.DiscoveryNodes; +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.plugins.ActionPlugin; +import org.opensearch.plugins.ClusterPlugin; +import org.opensearch.plugins.NetworkPlugin; +import org.opensearch.plugins.Plugin; +import org.opensearch.rest.RestController; +import org.opensearch.rest.RestHandler; +import org.opensearch.test.framework.testplugins.dummyaction.DummyAction; +import org.opensearch.test.framework.testplugins.dummyaction.TransportDummyAction; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +public class CustomTestPlugin extends Plugin implements ClusterPlugin, NetworkPlugin, ActionPlugin { + + @Override + public List getRestHandlers( + Settings settings, + RestController restController, + ClusterSettings clusterSettings, + IndexScopedSettings indexScopedSettings, + SettingsFilter settingsFilter, + IndexNameExpressionResolver indexNameExpressionResolver, + Supplier nodesInCluster + ) { + + final List handlers = new ArrayList(1); + handlers.add(new DummyRestHandler()); + + return handlers; + } + + @Override + public List> getActions() { + List> actions = new ArrayList<>(1); + + actions.add(new ActionHandler<>(DummyAction.INSTANCE, TransportDummyAction.class)); + + return actions; + } +} diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/DummyRestHandler.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/DummyRestHandler.java new file mode 100644 index 0000000000..ac2f13fc88 --- /dev/null +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/DummyRestHandler.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. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +package org.opensearch.test.framework.testplugins; + +import java.io.IOException; +import java.util.List; +import java.util.Set; + +import com.google.common.collect.ImmutableList; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.opensearch.client.node.NodeClient; +import org.opensearch.core.xcontent.XContentBuilder; +import org.opensearch.rest.BaseRestHandler; +import org.opensearch.rest.BytesRestResponse; +import org.opensearch.rest.NamedRoute; +import org.opensearch.rest.RestChannel; +import org.opensearch.rest.RestRequest; +import org.opensearch.core.rest.RestStatus; + +import static org.opensearch.rest.RestRequest.Method.GET; +import static org.opensearch.rest.RestRequest.Method.POST; +import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; + +public class DummyRestHandler extends BaseRestHandler { + + private static final List routes = addRoutesPrefix( + ImmutableList.of( + new NamedRoute.Builder().method(POST) + .path("/dummy") + .uniqueName("security:dummy/post") + .legacyActionNames(Set.of("cluster:admin/dummy_plugin/dummy/post")) + .build(), + new NamedRoute.Builder().method(GET) + .path("/dummy") + .uniqueName("security:dummy/get") + .legacyActionNames(Set.of("cluster:admin/dummy_plugin/dummy/get")) + .build() + ), + "/_plugins/_dummyplugin" + ); + + private final Logger log = LogManager.getLogger(this.getClass()); + + public DummyRestHandler() { + super(); + } + + @Override + public List routes() { + return routes; + } + + @Override + protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + return new RestChannelConsumer() { + + @Override + public void accept(RestChannel channel) throws Exception { + XContentBuilder builder = channel.newBuilder(); + BytesRestResponse response = null; + + try { + + // TODO: do something + } catch (final Exception e1) { + log.error(e1.toString(), e1); + builder = channel.newBuilder(); + builder.startObject(); + builder.field("error", e1.toString()); + builder.endObject(); + response = new BytesRestResponse(RestStatus.INTERNAL_SERVER_ERROR, builder); + } finally { + if (builder != null) { + builder.close(); + } + } + + channel.sendResponse(response); + } + }; + } + + @Override + public String getName() { + return "Dummy Rest Action"; + } + +} diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyAction.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyAction.java new file mode 100644 index 0000000000..5ddd512d37 --- /dev/null +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyAction.java @@ -0,0 +1,39 @@ +/* + * Copyright 2015-2018 _floragunn_ GmbH + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * 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.test.framework.testplugins.dummyaction; + +import org.opensearch.action.ActionType; + +public class DummyAction extends ActionType { + + public static final DummyAction INSTANCE = new DummyAction(); + public static final String NAME = "cluster:admin/dummy_plugin/dummy"; + + protected DummyAction() { + super(NAME, DummyResponse::new); + } +} diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyRequest.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyRequest.java new file mode 100644 index 0000000000..fd519d88c4 --- /dev/null +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyRequest.java @@ -0,0 +1,43 @@ +/* + * Copyright 2015-2018 _floragunn_ GmbH + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * 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.test.framework.testplugins.dummyaction; + +import org.opensearch.action.support.nodes.BaseNodesRequest; +import org.opensearch.core.common.io.stream.StreamInput; + +import java.io.IOException; + +public class DummyRequest extends BaseNodesRequest { + + public DummyRequest(final StreamInput in) throws IOException { + super(in); + } + + public DummyRequest() throws IOException { + super(new String[0]); + } +} diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyRequestBuilder.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyRequestBuilder.java new file mode 100644 index 0000000000..c0733a8a6a --- /dev/null +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyRequestBuilder.java @@ -0,0 +1,43 @@ +/* + * Copyright 2015-2018 _floragunn_ GmbH + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * 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.test.framework.testplugins.dummyaction; + +import org.opensearch.action.ActionRequestBuilder; +import org.opensearch.client.ClusterAdminClient; +import org.opensearch.client.OpenSearchClient; + +import java.io.IOException; + +public class DummyRequestBuilder extends ActionRequestBuilder { + public DummyRequestBuilder(final ClusterAdminClient client) throws IOException { + this(client, DummyAction.INSTANCE); + } + + public DummyRequestBuilder(final OpenSearchClient client, final DummyAction action) throws IOException { + super(client, action, new DummyRequest()); + } +} diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyResponse.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyResponse.java new file mode 100644 index 0000000000..701e6ccc4c --- /dev/null +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyResponse.java @@ -0,0 +1,78 @@ +/* + * Copyright 2015-2018 _floragunn_ GmbH + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * 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.test.framework.testplugins.dummyaction; + +import org.opensearch.core.action.ActionResponse; +import org.opensearch.core.common.Strings; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.xcontent.MediaTypeRegistry; +import org.opensearch.core.xcontent.ToXContent; +import org.opensearch.core.xcontent.XContentBuilder; + +import java.io.IOException; + +public class DummyResponse extends ActionResponse implements ToXContent { + private String responseString; + + public DummyResponse(String responseString) { + this.responseString = responseString; + } + + public DummyResponse() { + super(); + this.responseString = "Bleh!"; + } + + public DummyResponse(StreamInput in) throws IOException { + super(in); + responseString = in.readString(); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(responseString); + } + + public String getResponseString() { + return responseString; + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject("dummy_response"); + builder.field("responseString", responseString); + builder.endObject(); + + return builder; + } + + @Override + public String toString() { + return Strings.toString(MediaTypeRegistry.JSON, this, true, true); + } +} diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/TransportDummyAction.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/TransportDummyAction.java new file mode 100644 index 0000000000..745210ef0c --- /dev/null +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/TransportDummyAction.java @@ -0,0 +1,51 @@ +/* + * Copyright 2015-2018 _floragunn_ GmbH + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * 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.test.framework.testplugins.dummyaction; + +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.tasks.Task; +import org.opensearch.transport.TransportService; + +public class TransportDummyAction extends HandledTransportAction { + + @Inject + public TransportDummyAction(final TransportService transportService, final ActionFilters actionFilters) { + + super(DummyAction.NAME, transportService, actionFilters, DummyRequest::new); + + } + + @Override + protected void doExecute(Task task, DummyRequest request, ActionListener listener) { + String responseString = "Hello from dummy plugin"; + + listener.onResponse(new DummyResponse(responseString)); + } +} From 022e66347252fd06570ed649c8945cb894f21381 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Mon, 21 Aug 2023 13:22:56 -0400 Subject: [PATCH 02/13] Adds a plugin that has protected routes Signed-off-by: Darshit Chanpura --- .../testplugins/DummyRestHandler.java | 99 ------------------- .../testplugins/dummyaction/DummyRequest.java | 43 -------- .../dummyaction/DummyRequestBuilder.java | 43 -------- .../CustomRestProtectedTestPlugin.java} | 10 +- .../ProtectedRoutesRestHandler.java | 61 ++++++++++++ .../dummyaction/DummyAction.java | 4 +- .../dummyaction/DummyRequest.java | 75 ++++++++++++++ .../dummyaction/DummyResponse.java | 21 ++-- .../dummyaction/TransportDummyAction.java | 4 +- 9 files changed, 160 insertions(+), 200 deletions(-) delete mode 100644 src/integrationTest/java/org/opensearch/test/framework/testplugins/DummyRestHandler.java delete mode 100644 src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyRequest.java delete mode 100644 src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyRequestBuilder.java rename src/integrationTest/java/org/opensearch/test/framework/testplugins/{CustomTestPlugin.java => dummyprotected/CustomRestProtectedTestPlugin.java} (79%) create mode 100644 src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/ProtectedRoutesRestHandler.java rename src/integrationTest/java/org/opensearch/test/framework/testplugins/{ => dummyprotected}/dummyaction/DummyAction.java (87%) create mode 100644 src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyRequest.java rename src/integrationTest/java/org/opensearch/test/framework/testplugins/{ => dummyprotected}/dummyaction/DummyResponse.java (79%) rename src/integrationTest/java/org/opensearch/test/framework/testplugins/{ => dummyprotected}/dummyaction/TransportDummyAction.java (92%) diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/DummyRestHandler.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/DummyRestHandler.java deleted file mode 100644 index ac2f13fc88..0000000000 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/DummyRestHandler.java +++ /dev/null @@ -1,99 +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.test.framework.testplugins; - -import java.io.IOException; -import java.util.List; -import java.util.Set; - -import com.google.common.collect.ImmutableList; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import org.opensearch.client.node.NodeClient; -import org.opensearch.core.xcontent.XContentBuilder; -import org.opensearch.rest.BaseRestHandler; -import org.opensearch.rest.BytesRestResponse; -import org.opensearch.rest.NamedRoute; -import org.opensearch.rest.RestChannel; -import org.opensearch.rest.RestRequest; -import org.opensearch.core.rest.RestStatus; - -import static org.opensearch.rest.RestRequest.Method.GET; -import static org.opensearch.rest.RestRequest.Method.POST; -import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; - -public class DummyRestHandler extends BaseRestHandler { - - private static final List routes = addRoutesPrefix( - ImmutableList.of( - new NamedRoute.Builder().method(POST) - .path("/dummy") - .uniqueName("security:dummy/post") - .legacyActionNames(Set.of("cluster:admin/dummy_plugin/dummy/post")) - .build(), - new NamedRoute.Builder().method(GET) - .path("/dummy") - .uniqueName("security:dummy/get") - .legacyActionNames(Set.of("cluster:admin/dummy_plugin/dummy/get")) - .build() - ), - "/_plugins/_dummyplugin" - ); - - private final Logger log = LogManager.getLogger(this.getClass()); - - public DummyRestHandler() { - super(); - } - - @Override - public List routes() { - return routes; - } - - @Override - protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { - return new RestChannelConsumer() { - - @Override - public void accept(RestChannel channel) throws Exception { - XContentBuilder builder = channel.newBuilder(); - BytesRestResponse response = null; - - try { - - // TODO: do something - } catch (final Exception e1) { - log.error(e1.toString(), e1); - builder = channel.newBuilder(); - builder.startObject(); - builder.field("error", e1.toString()); - builder.endObject(); - response = new BytesRestResponse(RestStatus.INTERNAL_SERVER_ERROR, builder); - } finally { - if (builder != null) { - builder.close(); - } - } - - channel.sendResponse(response); - } - }; - } - - @Override - public String getName() { - return "Dummy Rest Action"; - } - -} diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyRequest.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyRequest.java deleted file mode 100644 index fd519d88c4..0000000000 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyRequest.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2015-2018 _floragunn_ GmbH - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * 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.test.framework.testplugins.dummyaction; - -import org.opensearch.action.support.nodes.BaseNodesRequest; -import org.opensearch.core.common.io.stream.StreamInput; - -import java.io.IOException; - -public class DummyRequest extends BaseNodesRequest { - - public DummyRequest(final StreamInput in) throws IOException { - super(in); - } - - public DummyRequest() throws IOException { - super(new String[0]); - } -} diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyRequestBuilder.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyRequestBuilder.java deleted file mode 100644 index c0733a8a6a..0000000000 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyRequestBuilder.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2015-2018 _floragunn_ GmbH - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * 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.test.framework.testplugins.dummyaction; - -import org.opensearch.action.ActionRequestBuilder; -import org.opensearch.client.ClusterAdminClient; -import org.opensearch.client.OpenSearchClient; - -import java.io.IOException; - -public class DummyRequestBuilder extends ActionRequestBuilder { - public DummyRequestBuilder(final ClusterAdminClient client) throws IOException { - this(client, DummyAction.INSTANCE); - } - - public DummyRequestBuilder(final OpenSearchClient client, final DummyAction action) throws IOException { - super(client, action, new DummyRequest()); - } -} diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/CustomTestPlugin.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/CustomRestProtectedTestPlugin.java similarity index 79% rename from src/integrationTest/java/org/opensearch/test/framework/testplugins/CustomTestPlugin.java rename to src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/CustomRestProtectedTestPlugin.java index 361a4cb3f7..eeba94f1d3 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/CustomTestPlugin.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/CustomRestProtectedTestPlugin.java @@ -1,4 +1,4 @@ -package org.opensearch.test.framework.testplugins; +package org.opensearch.test.framework.testplugins.dummyprotected; import org.opensearch.action.ActionRequest; import org.opensearch.cluster.metadata.IndexNameExpressionResolver; @@ -14,14 +14,14 @@ import org.opensearch.plugins.Plugin; import org.opensearch.rest.RestController; import org.opensearch.rest.RestHandler; -import org.opensearch.test.framework.testplugins.dummyaction.DummyAction; -import org.opensearch.test.framework.testplugins.dummyaction.TransportDummyAction; +import org.opensearch.test.framework.testplugins.dummyprotected.dummyaction.DummyAction; +import org.opensearch.test.framework.testplugins.dummyprotected.dummyaction.TransportDummyAction; import java.util.ArrayList; import java.util.List; import java.util.function.Supplier; -public class CustomTestPlugin extends Plugin implements ClusterPlugin, NetworkPlugin, ActionPlugin { +public class CustomRestProtectedTestPlugin extends Plugin implements ClusterPlugin, NetworkPlugin, ActionPlugin { @Override public List getRestHandlers( @@ -35,7 +35,7 @@ public List getRestHandlers( ) { final List handlers = new ArrayList(1); - handlers.add(new DummyRestHandler()); + handlers.add(new ProtectedRoutesRestHandler()); return handlers; } diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/ProtectedRoutesRestHandler.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/ProtectedRoutesRestHandler.java new file mode 100644 index 0000000000..9c79df2bc6 --- /dev/null +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/ProtectedRoutesRestHandler.java @@ -0,0 +1,61 @@ +/* + * 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.test.framework.testplugins.dummyprotected; + +import java.util.List; +import java.util.Set; + +import com.google.common.collect.ImmutableList; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.opensearch.rest.NamedRoute; +import org.opensearch.test.framework.testplugins.AbstractRestHandler; + +import static org.opensearch.rest.RestRequest.Method.GET; +import static org.opensearch.rest.RestRequest.Method.POST; +import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; + +public class ProtectedRoutesRestHandler extends AbstractRestHandler { + + private static final List routes = addRoutesPrefix( + ImmutableList.of( + new NamedRoute.Builder().method(POST) + .path("/dummy") + .uniqueName("security:dummy_protected/post") + .legacyActionNames(Set.of("cluster:admin/dummy_protected_plugin/dummy/post")) + .build(), + new NamedRoute.Builder().method(GET) + .path("/dummy") + .uniqueName("security:dummy_protected/get") + .legacyActionNames(Set.of("cluster:admin/dummy_protected_plugin/dummy/get")) + .build() + ), + "/_plugins/_dummy_protected" + ); + + private final Logger log = LogManager.getLogger(this.getClass()); + + public ProtectedRoutesRestHandler() { + super(); + } + + @Override + public List routes() { + return routes; + } + + @Override + public String getName() { + return "Dummy Protected Rest Action"; + } +} diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyAction.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyAction.java similarity index 87% rename from src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyAction.java rename to src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyAction.java index 5ddd512d37..01a0cd5995 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyAction.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyAction.java @@ -24,14 +24,14 @@ * GitHub history for details. */ -package org.opensearch.test.framework.testplugins.dummyaction; +package org.opensearch.test.framework.testplugins.dummyprotected.dummyaction; import org.opensearch.action.ActionType; public class DummyAction extends ActionType { public static final DummyAction INSTANCE = new DummyAction(); - public static final String NAME = "cluster:admin/dummy_plugin/dummy"; + public static final String NAME = "cluster:admin/dummy_protected_plugin/dummy"; protected DummyAction() { super(NAME, DummyResponse::new); diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyRequest.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyRequest.java new file mode 100644 index 0000000000..88cb7b855c --- /dev/null +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyRequest.java @@ -0,0 +1,75 @@ +/* + * Copyright 2015-2018 _floragunn_ GmbH + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * 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.test.framework.testplugins.dummyprotected.dummyaction; + +import org.opensearch.action.ActionRequest; +import org.opensearch.action.ActionRequestValidationException; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.xcontent.ToXContent; +import org.opensearch.core.xcontent.XContentBuilder; + +import java.io.IOException; + +public class DummyRequest extends ActionRequest implements ToXContent { + + private final String message; + + public DummyRequest(final StreamInput in) throws IOException { + super(in); + message = in.readString(); + } + + public DummyRequest(String message) { + this.message = message; + } + + /** + * @return + */ + @Override + public ActionRequestValidationException validate() { + // if (Strings.isNullOrEmpty(message)) { + // ActionRequestValidationException ex = new ActionRequestValidationException(); + // ex.addValidationError("Message cannot be null or empty"); + // throw ex; + // } + return null; + } + + /** + * @param xContentBuilder + * @param params + * @return + * @throws IOException + */ + @Override + public XContentBuilder toXContent(XContentBuilder xContentBuilder, Params params) throws IOException { + xContentBuilder.field("message", message); + + return xContentBuilder; + } +} diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyResponse.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyResponse.java similarity index 79% rename from src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyResponse.java rename to src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyResponse.java index 701e6ccc4c..59034b4575 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/DummyResponse.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyResponse.java @@ -24,20 +24,21 @@ * GitHub history for details. */ -package org.opensearch.test.framework.testplugins.dummyaction; +package org.opensearch.test.framework.testplugins.dummyprotected.dummyaction; +import org.opensearch.common.xcontent.StatusToXContentObject; import org.opensearch.core.action.ActionResponse; import org.opensearch.core.common.Strings; import org.opensearch.core.common.io.stream.StreamInput; import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.rest.RestStatus; import org.opensearch.core.xcontent.MediaTypeRegistry; -import org.opensearch.core.xcontent.ToXContent; import org.opensearch.core.xcontent.XContentBuilder; import java.io.IOException; -public class DummyResponse extends ActionResponse implements ToXContent { - private String responseString; +public class DummyResponse extends ActionResponse implements StatusToXContentObject { + private final String responseString; public DummyResponse(String responseString) { this.responseString = responseString; @@ -64,8 +65,8 @@ public String getResponseString() { @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - builder.startObject("dummy_response"); - builder.field("responseString", responseString); + builder.startObject(); + builder.field("response_string", this.responseString); builder.endObject(); return builder; @@ -75,4 +76,12 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws public String toString() { return Strings.toString(MediaTypeRegistry.JSON, this, true, true); } + + /** + * @return + */ + @Override + public RestStatus status() { + return RestStatus.OK; + } } diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/TransportDummyAction.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/TransportDummyAction.java similarity index 92% rename from src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/TransportDummyAction.java rename to src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/TransportDummyAction.java index 745210ef0c..fe0c9b4c63 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyaction/TransportDummyAction.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/TransportDummyAction.java @@ -24,7 +24,7 @@ * GitHub history for details. */ -package org.opensearch.test.framework.testplugins.dummyaction; +package org.opensearch.test.framework.testplugins.dummyprotected.dummyaction; import org.opensearch.action.support.ActionFilters; import org.opensearch.action.support.HandledTransportAction; @@ -44,7 +44,7 @@ public TransportDummyAction(final TransportService transportService, final Actio @Override protected void doExecute(Task task, DummyRequest request, ActionListener listener) { - String responseString = "Hello from dummy plugin"; + String responseString = "Hello from dummy protected plugin"; listener.onResponse(new DummyResponse(responseString)); } From 6a1add9936d2c96cf1d41ceef5c19f2a7e210292 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Mon, 21 Aug 2023 13:24:25 -0400 Subject: [PATCH 03/13] Adds a plugin that is a legacy plugin which does not have protected routes Signed-off-by: Darshit Chanpura --- .../dummy/CustomLegacyTestPlugin.java | 51 +++++++++++ .../testplugins/dummy/LegacyRestHandler.java | 47 ++++++++++ .../dummy/dummyaction/DummyAction.java | 39 +++++++++ .../dummy/dummyaction/DummyRequest.java | 75 ++++++++++++++++ .../dummy/dummyaction/DummyResponse.java | 87 +++++++++++++++++++ .../dummyaction/TransportDummyAction.java | 51 +++++++++++ 6 files changed, 350 insertions(+) create mode 100644 src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/CustomLegacyTestPlugin.java create mode 100644 src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/LegacyRestHandler.java create mode 100644 src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyAction.java create mode 100644 src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyRequest.java create mode 100644 src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyResponse.java create mode 100644 src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/TransportDummyAction.java diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/CustomLegacyTestPlugin.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/CustomLegacyTestPlugin.java new file mode 100644 index 0000000000..320e12ece2 --- /dev/null +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/CustomLegacyTestPlugin.java @@ -0,0 +1,51 @@ +package org.opensearch.test.framework.testplugins.dummy; + +import org.opensearch.action.ActionRequest; +import org.opensearch.cluster.metadata.IndexNameExpressionResolver; +import org.opensearch.cluster.node.DiscoveryNodes; +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.plugins.ActionPlugin; +import org.opensearch.plugins.ClusterPlugin; +import org.opensearch.plugins.NetworkPlugin; +import org.opensearch.plugins.Plugin; +import org.opensearch.rest.RestController; +import org.opensearch.rest.RestHandler; +import org.opensearch.test.framework.testplugins.dummy.dummyaction.DummyAction; +import org.opensearch.test.framework.testplugins.dummy.dummyaction.TransportDummyAction; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +public class CustomLegacyTestPlugin extends Plugin implements ClusterPlugin, NetworkPlugin, ActionPlugin { + + @Override + public List getRestHandlers( + Settings settings, + RestController restController, + ClusterSettings clusterSettings, + IndexScopedSettings indexScopedSettings, + SettingsFilter settingsFilter, + IndexNameExpressionResolver indexNameExpressionResolver, + Supplier nodesInCluster + ) { + + final List handlers = new ArrayList(1); + handlers.add(new LegacyRestHandler()); + + return handlers; + } + + @Override + public List> getActions() { + List> actions = new ArrayList<>(1); + + actions.add(new ActionHandler<>(DummyAction.INSTANCE, TransportDummyAction.class)); + + return actions; + } +} diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/LegacyRestHandler.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/LegacyRestHandler.java new file mode 100644 index 0000000000..878519b5aa --- /dev/null +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/LegacyRestHandler.java @@ -0,0 +1,47 @@ +/* + * 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.test.framework.testplugins.dummy; + +import com.google.common.collect.ImmutableList; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.opensearch.test.framework.testplugins.AbstractRestHandler; + +import java.util.List; + +import static org.opensearch.rest.RestRequest.Method.GET; +import static org.opensearch.rest.RestRequest.Method.POST; +import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix; + +public class LegacyRestHandler extends AbstractRestHandler { + + private static final List routes = addRoutesPrefix( + ImmutableList.of(new Route(POST, "/dummy"), new Route(GET, "/dummy")), + "/_plugins/_dummy" + ); + + private final Logger log = LogManager.getLogger(this.getClass()); + + public LegacyRestHandler() { + super(); + } + + @Override + public List routes() { + return routes; + } + + @Override + public String getName() { + return "Dummy Rest Action"; + } +} diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyAction.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyAction.java new file mode 100644 index 0000000000..36b94971af --- /dev/null +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyAction.java @@ -0,0 +1,39 @@ +/* + * Copyright 2015-2018 _floragunn_ GmbH + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * 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.test.framework.testplugins.dummy.dummyaction; + +import org.opensearch.action.ActionType; + +public class DummyAction extends ActionType { + + public static final DummyAction INSTANCE = new DummyAction(); + public static final String NAME = "cluster:admin/dummy_plugin/dummy"; + + protected DummyAction() { + super(NAME, DummyResponse::new); + } +} diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyRequest.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyRequest.java new file mode 100644 index 0000000000..b9a81f4889 --- /dev/null +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyRequest.java @@ -0,0 +1,75 @@ +/* + * Copyright 2015-2018 _floragunn_ GmbH + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * 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.test.framework.testplugins.dummy.dummyaction; + +import org.opensearch.action.ActionRequest; +import org.opensearch.action.ActionRequestValidationException; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.xcontent.ToXContent; +import org.opensearch.core.xcontent.XContentBuilder; + +import java.io.IOException; + +public class DummyRequest extends ActionRequest implements ToXContent { + + private final String message; + + public DummyRequest(final StreamInput in) throws IOException { + super(in); + message = in.readString(); + } + + public DummyRequest(String message) { + this.message = message; + } + + /** + * @return + */ + @Override + public ActionRequestValidationException validate() { + // if (Strings.isNullOrEmpty(message)) { + // ActionRequestValidationException ex = new ActionRequestValidationException(); + // ex.addValidationError("Message cannot be null or empty"); + // throw ex; + // } + return null; + } + + /** + * @param xContentBuilder + * @param params + * @return + * @throws IOException + */ + @Override + public XContentBuilder toXContent(XContentBuilder xContentBuilder, Params params) throws IOException { + xContentBuilder.field("message", message); + + return xContentBuilder; + } +} diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyResponse.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyResponse.java new file mode 100644 index 0000000000..a8eee2070e --- /dev/null +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyResponse.java @@ -0,0 +1,87 @@ +/* + * Copyright 2015-2018 _floragunn_ GmbH + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * 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.test.framework.testplugins.dummy.dummyaction; + +import org.opensearch.common.xcontent.StatusToXContentObject; +import org.opensearch.core.action.ActionResponse; +import org.opensearch.core.common.Strings; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.rest.RestStatus; +import org.opensearch.core.xcontent.MediaTypeRegistry; +import org.opensearch.core.xcontent.XContentBuilder; + +import java.io.IOException; + +public class DummyResponse extends ActionResponse implements StatusToXContentObject { + private final String responseString; + + public DummyResponse(String responseString) { + this.responseString = responseString; + } + + public DummyResponse() { + super(); + this.responseString = "Bleh!"; + } + + public DummyResponse(StreamInput in) throws IOException { + super(in); + responseString = in.readString(); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(responseString); + } + + public String getResponseString() { + return responseString; + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.field("response_string", responseString); + builder.endObject(); + + return builder; + } + + @Override + public String toString() { + return Strings.toString(MediaTypeRegistry.JSON, this, true, true); + } + + /** + * @return + */ + @Override + public RestStatus status() { + return RestStatus.OK; + } +} diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/TransportDummyAction.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/TransportDummyAction.java new file mode 100644 index 0000000000..b9c67e21aa --- /dev/null +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/TransportDummyAction.java @@ -0,0 +1,51 @@ +/* + * Copyright 2015-2018 _floragunn_ GmbH + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * 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.test.framework.testplugins.dummy.dummyaction; + +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.tasks.Task; +import org.opensearch.transport.TransportService; + +public class TransportDummyAction extends HandledTransportAction { + + @Inject + public TransportDummyAction(final TransportService transportService, final ActionFilters actionFilters) { + + super(DummyAction.NAME, transportService, actionFilters, DummyRequest::new); + + } + + @Override + protected void doExecute(Task task, DummyRequest request, ActionListener listener) { + String responseString = "Hello from dummy plugin"; + + listener.onResponse(new DummyResponse(responseString)); + } +} From 214d276c24f5319247e906ccbb0c99b19655bb95 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Mon, 21 Aug 2023 13:25:19 -0400 Subject: [PATCH 04/13] Adds an abstract base rest handler for dummy plugins Signed-off-by: Darshit Chanpura --- .../testplugins/AbstractRestHandler.java | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/integrationTest/java/org/opensearch/test/framework/testplugins/AbstractRestHandler.java diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/AbstractRestHandler.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/AbstractRestHandler.java new file mode 100644 index 0000000000..cec1f81097 --- /dev/null +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/AbstractRestHandler.java @@ -0,0 +1,59 @@ +package org.opensearch.test.framework.testplugins; + +import org.opensearch.ExceptionsHelper; +import org.opensearch.client.node.NodeClient; +import org.opensearch.core.rest.RestStatus; +import org.opensearch.core.xcontent.XContentBuilder; +import org.opensearch.rest.BaseRestHandler; +import org.opensearch.rest.BytesRestResponse; +import org.opensearch.rest.RestChannel; +import org.opensearch.rest.RestRequest; +import org.opensearch.rest.action.RestStatusToXContentListener; +import org.opensearch.test.framework.testplugins.dummyprotected.dummyaction.DummyAction; +import org.opensearch.test.framework.testplugins.dummyprotected.dummyaction.DummyRequest; + +import java.io.IOException; + +public class AbstractRestHandler extends BaseRestHandler { + + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Override + protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + + switch (request.method()) { + case GET: + return channel -> handleGet(channel, request, client); + case POST: + return channel -> handlePost(channel, request, client); + default: + throw new IllegalArgumentException(request.method() + " not supported"); + } + } + + private void notImplemented(RestChannel channel, RestRequest.Method method) { + try { + final XContentBuilder builder = channel.newBuilder(); + builder.startObject(); + builder.field("status", RestStatus.NOT_IMPLEMENTED.name()); + builder.field("message", "Method " + method + " not implemented."); + builder.endObject(); + channel.sendResponse(new BytesRestResponse(RestStatus.NOT_IMPLEMENTED, builder)); + } catch (IOException e) { + throw ExceptionsHelper.convertToOpenSearchException(e); + } + } + + private void handlePost(RestChannel channel, RestRequest request, NodeClient client) { + notImplemented(channel, request.method()); + } + + private void handleGet(RestChannel channel, RestRequest request, NodeClient client) { + String message = request.param("message"); + DummyRequest dummyRequest = new DummyRequest(message); + client.execute(DummyAction.INSTANCE, dummyRequest, new RestStatusToXContentListener<>(channel)); + } +} From 7a68bec69e5af61746a8b9f2fea41ecc3fd470f3 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Mon, 21 Aug 2023 13:34:09 -0400 Subject: [PATCH 05/13] Adds a few tests for E2E testing Signed-off-by: Darshit Chanpura --- .../security/rest/AuthZinRestLayerTests.java | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 src/integrationTest/java/org/opensearch/security/rest/AuthZinRestLayerTests.java diff --git a/src/integrationTest/java/org/opensearch/security/rest/AuthZinRestLayerTests.java b/src/integrationTest/java/org/opensearch/security/rest/AuthZinRestLayerTests.java new file mode 100644 index 0000000000..8b8644d4bc --- /dev/null +++ b/src/integrationTest/java/org/opensearch/security/rest/AuthZinRestLayerTests.java @@ -0,0 +1,134 @@ +/* + * 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.security.rest; + +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; +import org.apache.hc.core5.http.HttpStatus; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.opensearch.test.framework.AuditCompliance; +import org.opensearch.test.framework.AuditConfiguration; +import org.opensearch.test.framework.AuditFilters; +import org.opensearch.test.framework.TestSecurityConfig; +import org.opensearch.test.framework.TestSecurityConfig.Role; +import org.opensearch.test.framework.audit.AuditLogsRule; +import org.opensearch.test.framework.cluster.ClusterManager; +import org.opensearch.test.framework.cluster.LocalCluster; +import org.opensearch.test.framework.cluster.TestRestClient; +import org.opensearch.test.framework.testplugins.dummy.CustomLegacyTestPlugin; +import org.opensearch.test.framework.testplugins.dummyprotected.CustomRestProtectedTestPlugin; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.opensearch.test.framework.TestSecurityConfig.AuthcDomain.AUTHC_HTTPBASIC_INTERNAL; + +@RunWith(com.carrotsearch.randomizedtesting.RandomizedRunner.class) +@ThreadLeakScope(ThreadLeakScope.Scope.NONE) +public class AuthZinRestLayerTests { + protected final static TestSecurityConfig.User DUMMY_REST_ONLY = new TestSecurityConfig.User("dummy_rest_only").roles( + new Role("dummy_rest_only_role").clusterPermissions("security:dummy_protected/get") + .clusterPermissions("cluster:admin/dummy_plugin/dummy") + ); + + protected final static TestSecurityConfig.User DUMMY_WITH_TRANSPORT_PERM = new TestSecurityConfig.User("dummy_transport_perm").roles( + new Role("dummy_transport_perm_role").clusterPermissions("security:dummy_protected/get") + .clusterPermissions("cluster:admin/dummy_plugin/dummy", "cluster:admin/dummy_protected_plugin/dummy") + ); + + protected final static TestSecurityConfig.User DUMMY_LEGACY = new TestSecurityConfig.User("dummy_user_legacy").roles( + new Role("dummy_role_legacy").clusterPermissions("cluster:admin/dummy_plugin/dummy") + ); + + protected final static TestSecurityConfig.User DUMMY_NO_PERM = new TestSecurityConfig.User("dummy_user_no_perm").roles( + new Role("dummy_role_no_perm") + ); + + protected final static TestSecurityConfig.User DUMMY_UNREGISTERED = new TestSecurityConfig.User("dummy_user_not_registered"); + + public static final String DUMMY_BASE_ENDPOINT = "_plugins/_dummy"; + public static final String DUMMY_PROTECTED_BASE_ENDPOINT = "_plugins/_dummy"; + public static final String DUMMY_API = DUMMY_BASE_ENDPOINT + "/dummy"; + public static final String DUMMY_PROTECTED_API = DUMMY_PROTECTED_BASE_ENDPOINT + "/dummy"; + + @ClassRule + public static LocalCluster cluster = new LocalCluster.Builder().clusterManager(ClusterManager.THREE_CLUSTER_MANAGERS) + .authc(AUTHC_HTTPBASIC_INTERNAL) + .users(DUMMY_REST_ONLY, DUMMY_WITH_TRANSPORT_PERM, DUMMY_LEGACY, DUMMY_NO_PERM) + .plugin(CustomLegacyTestPlugin.class) + .plugin(CustomRestProtectedTestPlugin.class) + .audit( + new AuditConfiguration(true).compliance(new AuditCompliance().enabled(true)) + .filters(new AuditFilters().enabledRest(true).enabledTransport(true).resolveBulkRequests(true)) + ) + .build(); + + @Rule + public AuditLogsRule auditLogsRule = new AuditLogsRule(); + + // Class-level TODO: Ensure all tests have checks for status, body and audit logs (as needed) + + /* Basic Access check */ + + @Test + public void testShouldFailForUnregisteredUsers() { + try (TestRestClient client = cluster.getRestClient(DUMMY_UNREGISTERED)) { + assertThat(client.get(DUMMY_API).getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); + assertThat(client.get(DUMMY_PROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); + } + } + + @Test + public void testShouldFailForBothPlugins() { + try (TestRestClient client = cluster.getRestClient(DUMMY_NO_PERM)) { + // fail at Transport + assertThat(client.get(DUMMY_API).getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); + + // fail at REST + assertThat(client.get(DUMMY_PROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); + + // TODO: add audit log check for both cases + } + } + + /* AuthZ in REST check */ + @Test + public void testShouldFailAtTransportLayerWithRestOnlyPermission() { + try (TestRestClient client = cluster.getRestClient(DUMMY_REST_ONLY)) { + assertThat(client.get(DUMMY_PROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); + // TODO: add audit log check to verify it passes at REST layer and fails at Transport Layer + } + } + + @Test + public void testShouldPassWithRequiredPermissions() { + String expectedResponse = "{\"response_string\":\"Hello from dummy protected plugin\"}"; + try (TestRestClient client = cluster.getRestClient(DUMMY_WITH_TRANSPORT_PERM)) { + TestRestClient.HttpResponse res = client.get(DUMMY_PROTECTED_API); + assertThat(res.getStatusCode(), equalTo(HttpStatus.SC_OK)); + assertThat(res.getBody(), equalTo(expectedResponse)); + // TODO: add audit log check to verify it passes at REST layer and at Transport Layer + } + } + + // TODO: Add test that verifies failed execution with DUMMY_REST_ONLY & DUMMY_WITH_TRANSPORT for POST request, both should fail at REST + // layer + + /* Backwards compatibility check */ + // TODO: add a test that verifies that DUMMY_LEGACY cannot access the protected endpoint from new plugin but can still endpoints from + // legacy plugin with only transport permission, also add audit log check + + // TODO: add a test to verify that DUMMY_REST_ONLY & DUMMY_WITH_TRANSPORT can access legacy plugin endpoints with only transport + // permissions + +} From 0d6ba843166e93b0743b9d0f78023eb8106e2d9c Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Mon, 21 Aug 2023 14:49:29 -0400 Subject: [PATCH 06/13] Refactors plugins to be more readable Signed-off-by: Darshit Chanpura --- .../testplugins/AbstractRestHandler.java | 11 +++-------- .../testplugins/dummy/LegacyRestHandler.java | 17 +++++++++++++---- .../ProtectedRoutesRestHandler.java | 17 +++++++++++++---- .../dummyprotected/dummyaction/DummyAction.java | 2 +- 4 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/AbstractRestHandler.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/AbstractRestHandler.java index cec1f81097..770d61b2f9 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/AbstractRestHandler.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/AbstractRestHandler.java @@ -8,9 +8,6 @@ import org.opensearch.rest.BytesRestResponse; import org.opensearch.rest.RestChannel; import org.opensearch.rest.RestRequest; -import org.opensearch.rest.action.RestStatusToXContentListener; -import org.opensearch.test.framework.testplugins.dummyprotected.dummyaction.DummyAction; -import org.opensearch.test.framework.testplugins.dummyprotected.dummyaction.DummyRequest; import java.io.IOException; @@ -47,13 +44,11 @@ private void notImplemented(RestChannel channel, RestRequest.Method method) { } } - private void handlePost(RestChannel channel, RestRequest request, NodeClient client) { + public void handlePost(RestChannel channel, RestRequest request, NodeClient client) { notImplemented(channel, request.method()); } - private void handleGet(RestChannel channel, RestRequest request, NodeClient client) { - String message = request.param("message"); - DummyRequest dummyRequest = new DummyRequest(message); - client.execute(DummyAction.INSTANCE, dummyRequest, new RestStatusToXContentListener<>(channel)); + public void handleGet(RestChannel channel, RestRequest request, NodeClient client) { + notImplemented(channel, request.method()); } } diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/LegacyRestHandler.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/LegacyRestHandler.java index 878519b5aa..e001628596 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/LegacyRestHandler.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/LegacyRestHandler.java @@ -12,9 +12,13 @@ package org.opensearch.test.framework.testplugins.dummy; import com.google.common.collect.ImmutableList; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; +import org.opensearch.client.node.NodeClient; +import org.opensearch.rest.RestChannel; +import org.opensearch.rest.RestRequest; +import org.opensearch.rest.action.RestStatusToXContentListener; import org.opensearch.test.framework.testplugins.AbstractRestHandler; +import org.opensearch.test.framework.testplugins.dummy.dummyaction.DummyAction; +import org.opensearch.test.framework.testplugins.dummy.dummyaction.DummyRequest; import java.util.List; @@ -29,8 +33,6 @@ public class LegacyRestHandler extends AbstractRestHandler { "/_plugins/_dummy" ); - private final Logger log = LogManager.getLogger(this.getClass()); - public LegacyRestHandler() { super(); } @@ -44,4 +46,11 @@ public List routes() { public String getName() { return "Dummy Rest Action"; } + + @Override + public void handleGet(RestChannel channel, RestRequest request, NodeClient client) { + String message = request.param("message"); + DummyRequest dummyRequest = new DummyRequest(message); + client.execute(DummyAction.INSTANCE, dummyRequest, new RestStatusToXContentListener<>(channel)); + } } diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/ProtectedRoutesRestHandler.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/ProtectedRoutesRestHandler.java index 9c79df2bc6..5f20585cd6 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/ProtectedRoutesRestHandler.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/ProtectedRoutesRestHandler.java @@ -15,11 +15,15 @@ import java.util.Set; import com.google.common.collect.ImmutableList; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; +import org.opensearch.client.node.NodeClient; import org.opensearch.rest.NamedRoute; +import org.opensearch.rest.RestChannel; +import org.opensearch.rest.RestRequest; +import org.opensearch.rest.action.RestStatusToXContentListener; import org.opensearch.test.framework.testplugins.AbstractRestHandler; +import org.opensearch.test.framework.testplugins.dummyprotected.dummyaction.DummyAction; +import org.opensearch.test.framework.testplugins.dummyprotected.dummyaction.DummyRequest; import static org.opensearch.rest.RestRequest.Method.GET; import static org.opensearch.rest.RestRequest.Method.POST; @@ -43,8 +47,6 @@ public class ProtectedRoutesRestHandler extends AbstractRestHandler { "/_plugins/_dummy_protected" ); - private final Logger log = LogManager.getLogger(this.getClass()); - public ProtectedRoutesRestHandler() { super(); } @@ -58,4 +60,11 @@ public List routes() { public String getName() { return "Dummy Protected Rest Action"; } + + @Override + public void handleGet(RestChannel channel, RestRequest request, NodeClient client) { + String message = request.param("message"); + DummyRequest dummyRequest = new DummyRequest(message); + client.execute(DummyAction.INSTANCE, dummyRequest, new RestStatusToXContentListener<>(channel)); + } } diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyAction.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyAction.java index 01a0cd5995..f06c181744 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyAction.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyAction.java @@ -31,7 +31,7 @@ public class DummyAction extends ActionType { public static final DummyAction INSTANCE = new DummyAction(); - public static final String NAME = "cluster:admin/dummy_protected_plugin/dummy"; + public static final String NAME = "cluster:admin/dummy_protected_plugin/dummy/get"; protected DummyAction() { super(NAME, DummyResponse::new); From bc87ad5e28f7a2a8ae51a6bc74225e6be2913927 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Mon, 21 Aug 2023 16:42:59 -0400 Subject: [PATCH 07/13] Adds two reusable methods in AuditMessagePredicate Signed-off-by: Darshit Chanpura --- .../audit/AuditMessagePredicate.java | 59 ++++++++++++++++--- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/src/integrationTest/java/org/opensearch/test/framework/audit/AuditMessagePredicate.java b/src/integrationTest/java/org/opensearch/test/framework/audit/AuditMessagePredicate.java index 922f2d54aa..333ad7f49d 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/audit/AuditMessagePredicate.java +++ b/src/integrationTest/java/org/opensearch/test/framework/audit/AuditMessagePredicate.java @@ -41,6 +41,7 @@ public class AuditMessagePredicate implements Predicate { private final String transportRequestType; private final String effectiveUser; private final String index; + private final String privilege; private AuditMessagePredicate( AuditCategory category, @@ -50,7 +51,8 @@ private AuditMessagePredicate( Method requestMethod, String transportRequestType, String effectiveUser, - String index + String index, + String privilege ) { this.category = category; this.requestLayer = requestLayer; @@ -60,10 +62,11 @@ private AuditMessagePredicate( this.transportRequestType = transportRequestType; this.effectiveUser = effectiveUser; this.index = index; + this.privilege = privilege; } private AuditMessagePredicate(AuditCategory category) { - this(category, null, null, null, null, null, null, null); + this(category, null, null, null, null, null, null, null, null); } public static AuditMessagePredicate auditPredicate(AuditCategory category) { @@ -82,6 +85,22 @@ public static AuditMessagePredicate missingPrivilege(User user, String requestTy return auditPredicate(MISSING_PRIVILEGES).withLayer(Origin.TRANSPORT).withEffectiveUser(user).withTransportRequestType(requestType); } + public static AuditMessagePredicate privilegePredicateTransportLayer( + AuditCategory category, + User user, + String requestType, + String privilege + ) { + return auditPredicate(category).withLayer(Origin.TRANSPORT) + .withEffectiveUser(user) + .withPrivilege(privilege) + .withTransportRequestType(requestType); + } + + public static AuditMessagePredicate privilegePredicateRESTLayer(AuditCategory category, User user, Method method, String endpoint) { + return auditPredicate(category).withLayer(Origin.REST).withEffectiveUser(user).withRestRequest(method, endpoint); + } + public AuditMessagePredicate withLayer(Origin layer) { return new AuditMessagePredicate( category, @@ -91,7 +110,8 @@ public AuditMessagePredicate withLayer(Origin layer) { requestMethod, transportRequestType, effectiveUser, - index + index, + privilege ); } @@ -104,7 +124,8 @@ public AuditMessagePredicate withRequestPath(String path) { requestMethod, transportRequestType, effectiveUser, - index + index, + privilege ); } @@ -117,7 +138,8 @@ public AuditMessagePredicate withInitiatingUser(String user) { requestMethod, transportRequestType, effectiveUser, - index + index, + privilege ); } @@ -134,7 +156,8 @@ public AuditMessagePredicate withRestMethod(Method method) { method, transportRequestType, effectiveUser, - index + index, + privilege ); } @@ -147,7 +170,8 @@ public AuditMessagePredicate withTransportRequestType(String type) { requestMethod, type, effectiveUser, - index + index, + privilege ); } @@ -160,7 +184,8 @@ public AuditMessagePredicate withEffectiveUser(String user) { requestMethod, transportRequestType, user, - index + index, + privilege ); } @@ -181,7 +206,22 @@ public AuditMessagePredicate withIndex(String indexName) { requestMethod, transportRequestType, effectiveUser, - indexName + indexName, + privilege + ); + } + + public AuditMessagePredicate withPrivilege(String privilegeAction) { + return new AuditMessagePredicate( + category, + requestLayer, + restRequestPath, + initiatingUser, + requestMethod, + transportRequestType, + effectiveUser, + index, + privilegeAction ); } @@ -196,6 +236,7 @@ public boolean test(AuditMessage auditMessage) { predicates.add(audit -> Objects.isNull(transportRequestType) || transportRequestType.equals(audit.getRequestType())); predicates.add(audit -> Objects.isNull(effectiveUser) || effectiveUser.equals(audit.getEffectiveUser())); predicates.add(audit -> Objects.isNull(index) || containIndex(audit, index)); + predicates.add(audit -> Objects.isNull(privilege) || privilege.equals(audit.getPrivilege())); return predicates.stream().reduce(Predicate::and).orElseThrow().test(auditMessage); } From 65d53da9f686a62fd25296148f323722ca072db6 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Mon, 21 Aug 2023 16:44:06 -0400 Subject: [PATCH 08/13] Adds final changes to AuthZ end-to-end tests Signed-off-by: Darshit Chanpura --- .../security/rest/AuthZinRestLayerTests.java | 164 +++++++++++++++--- 1 file changed, 142 insertions(+), 22 deletions(-) diff --git a/src/integrationTest/java/org/opensearch/security/rest/AuthZinRestLayerTests.java b/src/integrationTest/java/org/opensearch/security/rest/AuthZinRestLayerTests.java index 8b8644d4bc..8b8b5e84da 100644 --- a/src/integrationTest/java/org/opensearch/security/rest/AuthZinRestLayerTests.java +++ b/src/integrationTest/java/org/opensearch/security/rest/AuthZinRestLayerTests.java @@ -31,7 +31,14 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; +import static org.opensearch.rest.RestRequest.Method.GET; +import static org.opensearch.rest.RestRequest.Method.POST; +import static org.opensearch.security.auditlog.impl.AuditCategory.FAILED_LOGIN; +import static org.opensearch.security.auditlog.impl.AuditCategory.GRANTED_PRIVILEGES; +import static org.opensearch.security.auditlog.impl.AuditCategory.MISSING_PRIVILEGES; import static org.opensearch.test.framework.TestSecurityConfig.AuthcDomain.AUTHC_HTTPBASIC_INTERNAL; +import static org.opensearch.test.framework.audit.AuditMessagePredicate.privilegePredicateRESTLayer; +import static org.opensearch.test.framework.audit.AuditMessagePredicate.privilegePredicateTransportLayer; @RunWith(com.carrotsearch.randomizedtesting.RandomizedRunner.class) @ThreadLeakScope(ThreadLeakScope.Scope.NONE) @@ -43,7 +50,7 @@ public class AuthZinRestLayerTests { protected final static TestSecurityConfig.User DUMMY_WITH_TRANSPORT_PERM = new TestSecurityConfig.User("dummy_transport_perm").roles( new Role("dummy_transport_perm_role").clusterPermissions("security:dummy_protected/get") - .clusterPermissions("cluster:admin/dummy_plugin/dummy", "cluster:admin/dummy_protected_plugin/dummy") + .clusterPermissions("cluster:admin/dummy_plugin/dummy", "cluster:admin/dummy_protected_plugin/dummy/get") ); protected final static TestSecurityConfig.User DUMMY_LEGACY = new TestSecurityConfig.User("dummy_user_legacy").roles( @@ -57,7 +64,7 @@ public class AuthZinRestLayerTests { protected final static TestSecurityConfig.User DUMMY_UNREGISTERED = new TestSecurityConfig.User("dummy_user_not_registered"); public static final String DUMMY_BASE_ENDPOINT = "_plugins/_dummy"; - public static final String DUMMY_PROTECTED_BASE_ENDPOINT = "_plugins/_dummy"; + public static final String DUMMY_PROTECTED_BASE_ENDPOINT = "_plugins/_dummy_protected"; public static final String DUMMY_API = DUMMY_BASE_ENDPOINT + "/dummy"; public static final String DUMMY_PROTECTED_API = DUMMY_PROTECTED_BASE_ENDPOINT + "/dummy"; @@ -76,15 +83,18 @@ public class AuthZinRestLayerTests { @Rule public AuditLogsRule auditLogsRule = new AuditLogsRule(); - // Class-level TODO: Ensure all tests have checks for status, body and audit logs (as needed) - - /* Basic Access check */ + /** Basic Access check */ @Test public void testShouldFailForUnregisteredUsers() { try (TestRestClient client = cluster.getRestClient(DUMMY_UNREGISTERED)) { + // Legacy plugin assertThat(client.get(DUMMY_API).getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); + auditLogsRule.assertExactlyOne(privilegePredicateRESTLayer(FAILED_LOGIN, DUMMY_UNREGISTERED, GET, "/" + DUMMY_API)); + + // Protected Routes plugin assertThat(client.get(DUMMY_PROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); + auditLogsRule.assertExactlyOne(privilegePredicateRESTLayer(FAILED_LOGIN, DUMMY_UNREGISTERED, GET, "/" + DUMMY_PROTECTED_API)); } } @@ -93,42 +103,152 @@ public void testShouldFailForBothPlugins() { try (TestRestClient client = cluster.getRestClient(DUMMY_NO_PERM)) { // fail at Transport assertThat(client.get(DUMMY_API).getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); + auditLogsRule.assertExactlyOne( + privilegePredicateTransportLayer(MISSING_PRIVILEGES, DUMMY_NO_PERM, "DummyRequest", "cluster:admin/dummy_plugin/dummy") + ); // fail at REST - assertThat(client.get(DUMMY_PROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); - - // TODO: add audit log check for both cases + assertThat(client.get(DUMMY_PROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); + auditLogsRule.assertExactlyOne(privilegePredicateRESTLayer(MISSING_PRIVILEGES, DUMMY_NO_PERM, GET, "/" + DUMMY_PROTECTED_API)); } } - /* AuthZ in REST check */ + /** AuthZ in REST Layer check */ + @Test public void testShouldFailAtTransportLayerWithRestOnlyPermission() { try (TestRestClient client = cluster.getRestClient(DUMMY_REST_ONLY)) { assertThat(client.get(DUMMY_PROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); - // TODO: add audit log check to verify it passes at REST layer and fails at Transport Layer + // granted at Rest layer + auditLogsRule.assertExactlyOne( + privilegePredicateRESTLayer(GRANTED_PRIVILEGES, DUMMY_REST_ONLY, GET, "/" + DUMMY_PROTECTED_API) + ); + // missing at Transport layer + auditLogsRule.assertExactlyOne( + privilegePredicateTransportLayer( + MISSING_PRIVILEGES, + DUMMY_REST_ONLY, + "DummyRequest", + "cluster:admin/dummy_protected_plugin/dummy/get" + ) + ); } } @Test public void testShouldPassWithRequiredPermissions() { - String expectedResponse = "{\"response_string\":\"Hello from dummy protected plugin\"}"; try (TestRestClient client = cluster.getRestClient(DUMMY_WITH_TRANSPORT_PERM)) { - TestRestClient.HttpResponse res = client.get(DUMMY_PROTECTED_API); - assertThat(res.getStatusCode(), equalTo(HttpStatus.SC_OK)); - assertThat(res.getBody(), equalTo(expectedResponse)); - // TODO: add audit log check to verify it passes at REST layer and at Transport Layer + assertOKResponseFromProtectedPlugin(client); + + auditLogsRule.assertExactlyOne( + privilegePredicateRESTLayer(GRANTED_PRIVILEGES, DUMMY_WITH_TRANSPORT_PERM, GET, "/" + DUMMY_PROTECTED_API) + ); + auditLogsRule.assertExactlyOne( + privilegePredicateTransportLayer( + GRANTED_PRIVILEGES, + DUMMY_WITH_TRANSPORT_PERM, + "DummyRequest", + "cluster:admin/dummy_protected_plugin/dummy/get" + ) + ); } } - // TODO: Add test that verifies failed execution with DUMMY_REST_ONLY & DUMMY_WITH_TRANSPORT for POST request, both should fail at REST - // layer + @Test + public void testShouldFailForPOST() { + try (TestRestClient client = cluster.getRestClient(DUMMY_REST_ONLY)) { + assertThat(client.post(DUMMY_PROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); + + auditLogsRule.assertExactlyOne( + privilegePredicateRESTLayer(MISSING_PRIVILEGES, DUMMY_REST_ONLY, POST, "/" + DUMMY_PROTECTED_API) + ); + } + + try (TestRestClient client = cluster.getRestClient(DUMMY_WITH_TRANSPORT_PERM)) { + assertThat(client.post(DUMMY_PROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); + + auditLogsRule.assertExactlyOne( + privilegePredicateRESTLayer(MISSING_PRIVILEGES, DUMMY_WITH_TRANSPORT_PERM, POST, "/" + DUMMY_PROTECTED_API) + ); + } + } + + /** Backwards compatibility check */ + + @Test + public void testBackwardsCompatibility() { + + // DUMMY_LEGACY should have access to legacy endpoint, but not protected endpoint + try (TestRestClient client = cluster.getRestClient(DUMMY_LEGACY)) { + TestRestClient.HttpResponse res = client.get(DUMMY_PROTECTED_API); + assertThat(res.getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); + auditLogsRule.assertExactlyOne(privilegePredicateRESTLayer(MISSING_PRIVILEGES, DUMMY_LEGACY, GET, "/" + DUMMY_PROTECTED_API)); + + assertOKResponseFromLegacyPlugin(client); + // check that there is no log for REST layer AuthZ since this is an unprotected endpoint + auditLogsRule.assertExactly(0, privilegePredicateRESTLayer(GRANTED_PRIVILEGES, DUMMY_LEGACY, GET, DUMMY_API)); + // check that there is exactly 1 message for Transport Layer privilege evaluation + auditLogsRule.assertExactlyOne( + privilegePredicateTransportLayer(GRANTED_PRIVILEGES, DUMMY_LEGACY, "DummyRequest", "cluster:admin/dummy_plugin/dummy") + ); + } - /* Backwards compatibility check */ - // TODO: add a test that verifies that DUMMY_LEGACY cannot access the protected endpoint from new plugin but can still endpoints from - // legacy plugin with only transport permission, also add audit log check + // DUMMY_REST_ONLY should have access to legacy endpoint (protected endpoint already tested above) + try (TestRestClient client = cluster.getRestClient(DUMMY_REST_ONLY)) { + assertOKResponseFromLegacyPlugin(client); + auditLogsRule.assertExactly(0, privilegePredicateRESTLayer(GRANTED_PRIVILEGES, DUMMY_REST_ONLY, GET, DUMMY_API)); + auditLogsRule.assertExactlyOne( + privilegePredicateTransportLayer(GRANTED_PRIVILEGES, DUMMY_REST_ONLY, "DummyRequest", "cluster:admin/dummy_plugin/dummy") + ); + } - // TODO: add a test to verify that DUMMY_REST_ONLY & DUMMY_WITH_TRANSPORT can access legacy plugin endpoints with only transport - // permissions + // DUMMY_WITH_TRANSPORT_PERM should have access to legacy endpoint (protected endpoint already tested above) + try (TestRestClient client = cluster.getRestClient(DUMMY_WITH_TRANSPORT_PERM)) { + assertOKResponseFromLegacyPlugin(client); + auditLogsRule.assertExactly(0, privilegePredicateRESTLayer(GRANTED_PRIVILEGES, DUMMY_WITH_TRANSPORT_PERM, GET, DUMMY_API)); + auditLogsRule.assertExactlyOne( + privilegePredicateTransportLayer( + GRANTED_PRIVILEGES, + DUMMY_WITH_TRANSPORT_PERM, + "DummyRequest", + "cluster:admin/dummy_plugin/dummy" + ) + ); + } + // DUMMY_NO_PERM should not have access to legacy endpoint (protected endpoint already tested above) + try (TestRestClient client = cluster.getRestClient(DUMMY_NO_PERM)) { + assertThat(client.get(DUMMY_API).getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); + auditLogsRule.assertExactly(0, privilegePredicateRESTLayer(MISSING_PRIVILEGES, DUMMY_NO_PERM, GET, DUMMY_API)); + auditLogsRule.assertExactlyOne( + privilegePredicateTransportLayer(MISSING_PRIVILEGES, DUMMY_NO_PERM, "DummyRequest", "cluster:admin/dummy_plugin/dummy") + ); + } + + // DUMMY_UNREGISTERED should not have access to legacy endpoint (protected endpoint already tested above) + try (TestRestClient client = cluster.getRestClient(DUMMY_UNREGISTERED)) { + assertThat(client.get(DUMMY_API).getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); + auditLogsRule.assertExactly(0, privilegePredicateRESTLayer(MISSING_PRIVILEGES, DUMMY_UNREGISTERED, GET, DUMMY_API)); + auditLogsRule.assertExactly( + 0, + privilegePredicateTransportLayer(MISSING_PRIVILEGES, DUMMY_UNREGISTERED, "DummyRequest", "cluster:admin/dummy_plugin/dummy") + ); + auditLogsRule.assertExactly(0, privilegePredicateRESTLayer(FAILED_LOGIN, DUMMY_UNREGISTERED, GET, DUMMY_API)); + } + } + + /** Helper Methods */ + private void assertOKResponseFromLegacyPlugin(TestRestClient client) { + String expectedResponseFromLegacyPlugin = "{\"response_string\":\"Hello from dummy plugin\"}"; + TestRestClient.HttpResponse res = client.get(DUMMY_API); + assertThat(res.getStatusCode(), equalTo(HttpStatus.SC_OK)); + assertThat(res.getBody(), equalTo(expectedResponseFromLegacyPlugin)); + } + + private void assertOKResponseFromProtectedPlugin(TestRestClient client) { + String expectedResponseFromProtectedPlugin = "{\"response_string\":\"Hello from dummy protected plugin\"}"; + TestRestClient.HttpResponse res = client.get(DUMMY_PROTECTED_API); + assertThat(res.getStatusCode(), equalTo(HttpStatus.SC_OK)); + assertThat(res.getBody(), equalTo(expectedResponseFromProtectedPlugin)); + } } From eb61c9e39c3eb752bef8b9ecd2b13b24c44c0269 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Mon, 21 Aug 2023 17:12:57 -0400 Subject: [PATCH 09/13] Fixes WhoAmITests to be a little cleaner Signed-off-by: Darshit Chanpura --- .../opensearch/security/rest/WhoAmITests.java | 50 +++++++------------ .../audit/AuditMessagePredicate.java | 4 ++ 2 files changed, 22 insertions(+), 32 deletions(-) diff --git a/src/integrationTest/java/org/opensearch/security/rest/WhoAmITests.java b/src/integrationTest/java/org/opensearch/security/rest/WhoAmITests.java index 4eaa49b62e..fe94df26b9 100644 --- a/src/integrationTest/java/org/opensearch/security/rest/WhoAmITests.java +++ b/src/integrationTest/java/org/opensearch/security/rest/WhoAmITests.java @@ -18,9 +18,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; -import org.opensearch.rest.RestRequest; -import org.opensearch.security.auditlog.AuditLog; -import org.opensearch.security.auditlog.impl.AuditCategory; import org.opensearch.security.auditlog.impl.AuditMessage; import org.opensearch.test.framework.AuditCompliance; import org.opensearch.test.framework.AuditConfiguration; @@ -47,12 +44,13 @@ import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.lessThan; import static org.junit.Assert.assertTrue; +import static org.opensearch.rest.RestRequest.Method.GET; import static org.opensearch.security.auditlog.impl.AuditCategory.GRANTED_PRIVILEGES; import static org.opensearch.security.auditlog.impl.AuditCategory.MISSING_PRIVILEGES; import static org.opensearch.test.framework.TestSecurityConfig.AuthcDomain.AUTHC_HTTPBASIC_INTERNAL; -import static org.opensearch.test.framework.audit.AuditMessagePredicate.auditPredicate; import static org.opensearch.test.framework.audit.AuditMessagePredicate.grantedPrivilege; -import static org.opensearch.test.framework.audit.AuditMessagePredicate.userAuthenticated; +import static org.opensearch.test.framework.audit.AuditMessagePredicate.privilegePredicateRESTLayer; +import static org.opensearch.test.framework.audit.AuditMessagePredicate.userAuthenticatedPredicate; @RunWith(com.carrotsearch.randomizedtesting.RandomizedRunner.class) @ThreadLeakScope(ThreadLeakScope.Scope.NONE) @@ -102,8 +100,8 @@ public void testWhoAmIWithGetPermissions() { assertResponse(client.get(WHOAMI_PROTECTED_ENDPOINT), HttpStatus.SC_OK, expectedAuthorizedBody); // audit log, named route - assertExactlyOneAuthenticatedLogMessage(WHO_AM_I); - assertExactlyOnePrivilegeEvaluationMessage(GRANTED_PRIVILEGES, WHO_AM_I); + auditLogsRule.assertExactlyOne(userAuthenticatedPredicate(WHO_AM_I, GET, "/" + WHOAMI_PROTECTED_ENDPOINT)); + auditLogsRule.assertExactlyOne(privilegePredicateRESTLayer(GRANTED_PRIVILEGES, WHO_AM_I, GET, "/" + WHOAMI_PROTECTED_ENDPOINT)); assertResponse(client.get(WHOAMI_ENDPOINT), HttpStatus.SC_OK, expectedAuthorizedBody); } @@ -115,8 +113,10 @@ public void testWhoAmIWithGetPermissionsLegacy() { assertResponse(client.get(WHOAMI_PROTECTED_ENDPOINT), HttpStatus.SC_OK, expectedAuthorizedBody); // audit log, named route - assertExactlyOneAuthenticatedLogMessage(WHO_AM_I_LEGACY); - assertExactlyOnePrivilegeEvaluationMessage(GRANTED_PRIVILEGES, WHO_AM_I_LEGACY); + auditLogsRule.assertExactlyOne(userAuthenticatedPredicate(WHO_AM_I_LEGACY, GET, "/" + WHOAMI_PROTECTED_ENDPOINT)); + auditLogsRule.assertExactlyOne( + privilegePredicateRESTLayer(GRANTED_PRIVILEGES, WHO_AM_I_LEGACY, GET, "/" + WHOAMI_PROTECTED_ENDPOINT) + ); assertResponse(client.get(WHOAMI_ENDPOINT), HttpStatus.SC_OK, expectedAuthorizedBody); } @@ -127,8 +127,10 @@ public void testWhoAmIWithoutGetPermissions() { try (TestRestClient client = cluster.getRestClient(WHO_AM_I_NO_PERM)) { assertResponse(client.get(WHOAMI_PROTECTED_ENDPOINT), HttpStatus.SC_UNAUTHORIZED, expectedUnuauthorizedBody); // audit log, named route - assertExactlyOneAuthenticatedLogMessage(WHO_AM_I_NO_PERM); - assertExactlyOnePrivilegeEvaluationMessage(MISSING_PRIVILEGES, WHO_AM_I_NO_PERM); + auditLogsRule.assertExactlyOne(userAuthenticatedPredicate(WHO_AM_I_NO_PERM, GET, "/" + WHOAMI_PROTECTED_ENDPOINT)); + auditLogsRule.assertExactlyOne( + privilegePredicateRESTLayer(MISSING_PRIVILEGES, WHO_AM_I_NO_PERM, GET, "/" + WHOAMI_PROTECTED_ENDPOINT) + ); assertResponse(client.get(WHOAMI_ENDPOINT), HttpStatus.SC_OK, expectedAuthorizedBody); } @@ -152,13 +154,17 @@ public void testWhoAmIPost() { assertThat(client.post(WHOAMI_ENDPOINT).getStatusCode(), equalTo(HttpStatus.SC_OK)); } + // No audit logs generated because `/whoami` is passthrough at Transport Layer, and POST route is not a NamedRoute + auditLogsRule.assertAuditLogsCount(0, 0); } @Test public void testAuditLogSimilarityWithTransportLayer() { try (TestRestClient client = cluster.getRestClient(AUDIT_LOG_VERIFIER)) { assertResponse(client.get(WHOAMI_PROTECTED_ENDPOINT), HttpStatus.SC_OK, expectedAuthorizedBody); - assertExactlyOnePrivilegeEvaluationMessage(GRANTED_PRIVILEGES, AUDIT_LOG_VERIFIER); + auditLogsRule.assertExactlyOne( + privilegePredicateRESTLayer(GRANTED_PRIVILEGES, AUDIT_LOG_VERIFIER, GET, "/" + WHOAMI_PROTECTED_ENDPOINT) + ); assertThat(client.get("_cat/indices").getStatusCode(), equalTo(HttpStatus.SC_OK)); @@ -179,26 +185,6 @@ private void assertResponse(TestRestClient.HttpResponse response, int expectedSt assertThat(response.getBody(), equalTo(expectedBody)); } - private void assertExactlyOneAuthenticatedLogMessage(TestSecurityConfig.User user) { - auditLogsRule.assertExactly( - 1, - userAuthenticated(user).withLayer(AuditLog.Origin.REST) - .withRestMethod(RestRequest.Method.GET) - .withRequestPath("/" + WhoAmITests.WHOAMI_PROTECTED_ENDPOINT) - .withInitiatingUser(user) - ); - } - - private void assertExactlyOnePrivilegeEvaluationMessage(AuditCategory privileges, TestSecurityConfig.User user) { - auditLogsRule.assertExactly( - 1, - auditPredicate(privileges).withLayer(AuditLog.Origin.REST) - .withRestMethod(RestRequest.Method.GET) - .withRequestPath("/" + WhoAmITests.WHOAMI_PROTECTED_ENDPOINT) - .withEffectiveUser(user) - ); - } - private void verifyAuditLogSimilarity(List currentTestAuditMessages) { List restSet = new ArrayList<>(); List transportSet = new ArrayList<>(); diff --git a/src/integrationTest/java/org/opensearch/test/framework/audit/AuditMessagePredicate.java b/src/integrationTest/java/org/opensearch/test/framework/audit/AuditMessagePredicate.java index 333ad7f49d..4935bf0387 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/audit/AuditMessagePredicate.java +++ b/src/integrationTest/java/org/opensearch/test/framework/audit/AuditMessagePredicate.java @@ -101,6 +101,10 @@ public static AuditMessagePredicate privilegePredicateRESTLayer(AuditCategory ca return auditPredicate(category).withLayer(Origin.REST).withEffectiveUser(user).withRestRequest(method, endpoint); } + public static AuditMessagePredicate userAuthenticatedPredicate(User user, Method method, String endpoint) { + return userAuthenticated(user).withLayer(Origin.REST).withRestRequest(method, endpoint).withInitiatingUser(user); + } + public AuditMessagePredicate withLayer(Origin layer) { return new AuditMessagePredicate( category, From 8c0cd13e1255f40829a3c804712061e101c9a564 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Mon, 21 Aug 2023 17:21:52 -0400 Subject: [PATCH 10/13] Fixes license headers Signed-off-by: Darshit Chanpura --- .../testplugins/dummy/CustomLegacyTestPlugin.java | 11 +++++++++++ .../dummy/dummyaction/DummyAction.java | 15 --------------- .../dummy/dummyaction/DummyRequest.java | 15 --------------- .../dummy/dummyaction/DummyResponse.java | 15 --------------- .../dummy/dummyaction/TransportDummyAction.java | 15 --------------- .../CustomRestProtectedTestPlugin.java | 11 +++++++++++ .../dummyprotected/dummyaction/DummyAction.java | 15 --------------- .../dummyprotected/dummyaction/DummyRequest.java | 15 --------------- .../dummyprotected/dummyaction/DummyResponse.java | 15 --------------- .../dummyaction/TransportDummyAction.java | 15 --------------- 10 files changed, 22 insertions(+), 120 deletions(-) diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/CustomLegacyTestPlugin.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/CustomLegacyTestPlugin.java index 320e12ece2..74186ecbd2 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/CustomLegacyTestPlugin.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/CustomLegacyTestPlugin.java @@ -1,3 +1,14 @@ +/* + * 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.test.framework.testplugins.dummy; import org.opensearch.action.ActionRequest; diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyAction.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyAction.java index 36b94971af..ff10f0ca74 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyAction.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyAction.java @@ -1,18 +1,3 @@ -/* - * Copyright 2015-2018 _floragunn_ GmbH - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /* * SPDX-License-Identifier: Apache-2.0 * diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyRequest.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyRequest.java index b9a81f4889..543e41ccb0 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyRequest.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyRequest.java @@ -1,18 +1,3 @@ -/* - * Copyright 2015-2018 _floragunn_ GmbH - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /* * SPDX-License-Identifier: Apache-2.0 * diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyResponse.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyResponse.java index a8eee2070e..62c58c6a52 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyResponse.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyResponse.java @@ -1,18 +1,3 @@ -/* - * Copyright 2015-2018 _floragunn_ GmbH - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /* * SPDX-License-Identifier: Apache-2.0 * diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/TransportDummyAction.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/TransportDummyAction.java index b9c67e21aa..6b14f01e0c 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/TransportDummyAction.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/TransportDummyAction.java @@ -1,18 +1,3 @@ -/* - * Copyright 2015-2018 _floragunn_ GmbH - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /* * SPDX-License-Identifier: Apache-2.0 * diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/CustomRestProtectedTestPlugin.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/CustomRestProtectedTestPlugin.java index eeba94f1d3..003de0dcb4 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/CustomRestProtectedTestPlugin.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/CustomRestProtectedTestPlugin.java @@ -1,3 +1,14 @@ +/* + * 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.test.framework.testplugins.dummyprotected; import org.opensearch.action.ActionRequest; diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyAction.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyAction.java index f06c181744..26edfa4e17 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyAction.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyAction.java @@ -1,18 +1,3 @@ -/* - * Copyright 2015-2018 _floragunn_ GmbH - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /* * SPDX-License-Identifier: Apache-2.0 * diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyRequest.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyRequest.java index 88cb7b855c..39901992e8 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyRequest.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyRequest.java @@ -1,18 +1,3 @@ -/* - * Copyright 2015-2018 _floragunn_ GmbH - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /* * SPDX-License-Identifier: Apache-2.0 * diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyResponse.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyResponse.java index 59034b4575..3b8fc2b0a0 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyResponse.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyResponse.java @@ -1,18 +1,3 @@ -/* - * Copyright 2015-2018 _floragunn_ GmbH - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /* * SPDX-License-Identifier: Apache-2.0 * diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/TransportDummyAction.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/TransportDummyAction.java index fe0c9b4c63..8273b9e667 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/TransportDummyAction.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/TransportDummyAction.java @@ -1,18 +1,3 @@ -/* - * Copyright 2015-2018 _floragunn_ GmbH - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /* * SPDX-License-Identifier: Apache-2.0 * From d6b69f9aafd6803045986a8933136d80f0558eea Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Tue, 22 Aug 2023 12:21:49 -0400 Subject: [PATCH 11/13] Cleans up code and addresses PR feedback Signed-off-by: Darshit Chanpura --- .../org/opensearch/security/rest/WhoAmITests.java | 1 + .../testplugins/AbstractRestHandler.java | 1 - .../testplugins/dummy/CustomLegacyTestPlugin.java | 4 ---- .../dummy/dummyaction/DummyRequest.java | 14 -------------- .../dummy/dummyaction/DummyResponse.java | 13 ------------- .../dummy/dummyaction/TransportDummyAction.java | 3 --- .../CustomRestProtectedTestPlugin.java | 4 ---- .../dummyprotected/dummyaction/DummyRequest.java | 15 --------------- .../dummyprotected/dummyaction/DummyResponse.java | 13 ------------- .../dummyaction/TransportDummyAction.java | 3 --- 10 files changed, 1 insertion(+), 70 deletions(-) diff --git a/src/integrationTest/java/org/opensearch/security/rest/WhoAmITests.java b/src/integrationTest/java/org/opensearch/security/rest/WhoAmITests.java index fe94df26b9..6b72a36277 100644 --- a/src/integrationTest/java/org/opensearch/security/rest/WhoAmITests.java +++ b/src/integrationTest/java/org/opensearch/security/rest/WhoAmITests.java @@ -162,6 +162,7 @@ public void testWhoAmIPost() { public void testAuditLogSimilarityWithTransportLayer() { try (TestRestClient client = cluster.getRestClient(AUDIT_LOG_VERIFIER)) { assertResponse(client.get(WHOAMI_PROTECTED_ENDPOINT), HttpStatus.SC_OK, expectedAuthorizedBody); + auditLogsRule.assertExactlyOne(userAuthenticatedPredicate(AUDIT_LOG_VERIFIER, GET, "/" + WHOAMI_PROTECTED_ENDPOINT)); auditLogsRule.assertExactlyOne( privilegePredicateRESTLayer(GRANTED_PRIVILEGES, AUDIT_LOG_VERIFIER, GET, "/" + WHOAMI_PROTECTED_ENDPOINT) ); diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/AbstractRestHandler.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/AbstractRestHandler.java index 770d61b2f9..764173b5b9 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/AbstractRestHandler.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/AbstractRestHandler.java @@ -20,7 +20,6 @@ public String getName() { @Override protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { - switch (request.method()) { case GET: return channel -> handleGet(channel, request, client); diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/CustomLegacyTestPlugin.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/CustomLegacyTestPlugin.java index 74186ecbd2..8f131d2544 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/CustomLegacyTestPlugin.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/CustomLegacyTestPlugin.java @@ -44,19 +44,15 @@ public List getRestHandlers( IndexNameExpressionResolver indexNameExpressionResolver, Supplier nodesInCluster ) { - final List handlers = new ArrayList(1); handlers.add(new LegacyRestHandler()); - return handlers; } @Override public List> getActions() { List> actions = new ArrayList<>(1); - actions.add(new ActionHandler<>(DummyAction.INSTANCE, TransportDummyAction.class)); - return actions; } } diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyRequest.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyRequest.java index 543e41ccb0..5928b4892f 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyRequest.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyRequest.java @@ -32,25 +32,11 @@ public DummyRequest(String message) { this.message = message; } - /** - * @return - */ @Override public ActionRequestValidationException validate() { - // if (Strings.isNullOrEmpty(message)) { - // ActionRequestValidationException ex = new ActionRequestValidationException(); - // ex.addValidationError("Message cannot be null or empty"); - // throw ex; - // } return null; } - /** - * @param xContentBuilder - * @param params - * @return - * @throws IOException - */ @Override public XContentBuilder toXContent(XContentBuilder xContentBuilder, Params params) throws IOException { xContentBuilder.field("message", message); diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyResponse.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyResponse.java index 62c58c6a52..e2ee6c9344 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyResponse.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/DummyResponse.java @@ -29,11 +29,6 @@ public DummyResponse(String responseString) { this.responseString = responseString; } - public DummyResponse() { - super(); - this.responseString = "Bleh!"; - } - public DummyResponse(StreamInput in) throws IOException { super(in); responseString = in.readString(); @@ -44,16 +39,11 @@ public void writeTo(StreamOutput out) throws IOException { out.writeString(responseString); } - public String getResponseString() { - return responseString; - } - @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(); builder.field("response_string", responseString); builder.endObject(); - return builder; } @@ -62,9 +52,6 @@ public String toString() { return Strings.toString(MediaTypeRegistry.JSON, this, true, true); } - /** - * @return - */ @Override public RestStatus status() { return RestStatus.OK; diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/TransportDummyAction.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/TransportDummyAction.java index 6b14f01e0c..7e30af64bd 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/TransportDummyAction.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/dummyaction/TransportDummyAction.java @@ -22,15 +22,12 @@ public class TransportDummyAction extends HandledTransportAction listener) { String responseString = "Hello from dummy plugin"; - listener.onResponse(new DummyResponse(responseString)); } } diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/CustomRestProtectedTestPlugin.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/CustomRestProtectedTestPlugin.java index 003de0dcb4..67ad9d4392 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/CustomRestProtectedTestPlugin.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/CustomRestProtectedTestPlugin.java @@ -44,19 +44,15 @@ public List getRestHandlers( IndexNameExpressionResolver indexNameExpressionResolver, Supplier nodesInCluster ) { - final List handlers = new ArrayList(1); handlers.add(new ProtectedRoutesRestHandler()); - return handlers; } @Override public List> getActions() { List> actions = new ArrayList<>(1); - actions.add(new ActionHandler<>(DummyAction.INSTANCE, TransportDummyAction.class)); - return actions; } } diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyRequest.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyRequest.java index 39901992e8..025d2e1c55 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyRequest.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyRequest.java @@ -32,29 +32,14 @@ public DummyRequest(String message) { this.message = message; } - /** - * @return - */ @Override public ActionRequestValidationException validate() { - // if (Strings.isNullOrEmpty(message)) { - // ActionRequestValidationException ex = new ActionRequestValidationException(); - // ex.addValidationError("Message cannot be null or empty"); - // throw ex; - // } return null; } - /** - * @param xContentBuilder - * @param params - * @return - * @throws IOException - */ @Override public XContentBuilder toXContent(XContentBuilder xContentBuilder, Params params) throws IOException { xContentBuilder.field("message", message); - return xContentBuilder; } } diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyResponse.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyResponse.java index 3b8fc2b0a0..efd7be49b4 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyResponse.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/DummyResponse.java @@ -29,11 +29,6 @@ public DummyResponse(String responseString) { this.responseString = responseString; } - public DummyResponse() { - super(); - this.responseString = "Bleh!"; - } - public DummyResponse(StreamInput in) throws IOException { super(in); responseString = in.readString(); @@ -44,16 +39,11 @@ public void writeTo(StreamOutput out) throws IOException { out.writeString(responseString); } - public String getResponseString() { - return responseString; - } - @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(); builder.field("response_string", this.responseString); builder.endObject(); - return builder; } @@ -62,9 +52,6 @@ public String toString() { return Strings.toString(MediaTypeRegistry.JSON, this, true, true); } - /** - * @return - */ @Override public RestStatus status() { return RestStatus.OK; diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/TransportDummyAction.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/TransportDummyAction.java index 8273b9e667..05a10d875a 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/TransportDummyAction.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/dummyaction/TransportDummyAction.java @@ -22,15 +22,12 @@ public class TransportDummyAction extends HandledTransportAction listener) { String responseString = "Hello from dummy protected plugin"; - listener.onResponse(new DummyResponse(responseString)); } } From cbbbf2797127fe3a0591464bc6da41143246fc14 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Tue, 22 Aug 2023 14:29:03 -0400 Subject: [PATCH 12/13] Renames users in Authz tests to be more intuitive Signed-off-by: Darshit Chanpura --- .../security/rest/AuthZinRestLayerTests.java | 133 ++++++++---------- .../dummy/CustomLegacyTestPlugin.java | 3 + .../CustomRestProtectedTestPlugin.java | 4 + 3 files changed, 68 insertions(+), 72 deletions(-) diff --git a/src/integrationTest/java/org/opensearch/security/rest/AuthZinRestLayerTests.java b/src/integrationTest/java/org/opensearch/security/rest/AuthZinRestLayerTests.java index 8b8b5e84da..a67fa196a0 100644 --- a/src/integrationTest/java/org/opensearch/security/rest/AuthZinRestLayerTests.java +++ b/src/integrationTest/java/org/opensearch/security/rest/AuthZinRestLayerTests.java @@ -43,35 +43,32 @@ @RunWith(com.carrotsearch.randomizedtesting.RandomizedRunner.class) @ThreadLeakScope(ThreadLeakScope.Scope.NONE) public class AuthZinRestLayerTests { - protected final static TestSecurityConfig.User DUMMY_REST_ONLY = new TestSecurityConfig.User("dummy_rest_only").roles( - new Role("dummy_rest_only_role").clusterPermissions("security:dummy_protected/get") - .clusterPermissions("cluster:admin/dummy_plugin/dummy") + protected final static TestSecurityConfig.User REST_ONLY = new TestSecurityConfig.User("rest_only").roles( + new Role("rest_only_role").clusterPermissions("security:dummy_protected/get").clusterPermissions("cluster:admin/dummy_plugin/dummy") ); - protected final static TestSecurityConfig.User DUMMY_WITH_TRANSPORT_PERM = new TestSecurityConfig.User("dummy_transport_perm").roles( - new Role("dummy_transport_perm_role").clusterPermissions("security:dummy_protected/get") - .clusterPermissions("cluster:admin/dummy_plugin/dummy", "cluster:admin/dummy_protected_plugin/dummy/get") + protected final static TestSecurityConfig.User TRANSPORT_ONLY = new TestSecurityConfig.User("transport_only").roles( + new Role("transport_only_role").clusterPermissions("cluster:admin/dummy_plugin/dummy") ); - protected final static TestSecurityConfig.User DUMMY_LEGACY = new TestSecurityConfig.User("dummy_user_legacy").roles( - new Role("dummy_role_legacy").clusterPermissions("cluster:admin/dummy_plugin/dummy") + protected final static TestSecurityConfig.User REST_PLUS_TRANSPORT = new TestSecurityConfig.User("rest_plus_transport").roles( + new Role("rest_plus_transport_role").clusterPermissions("security:dummy_protected/get") + .clusterPermissions("cluster:admin/dummy_plugin/dummy", "cluster:admin/dummy_protected_plugin/dummy/get") ); - protected final static TestSecurityConfig.User DUMMY_NO_PERM = new TestSecurityConfig.User("dummy_user_no_perm").roles( - new Role("dummy_role_no_perm") - ); + protected final static TestSecurityConfig.User NO_PERM = new TestSecurityConfig.User("no_perm").roles(new Role("no_perm_role")); - protected final static TestSecurityConfig.User DUMMY_UNREGISTERED = new TestSecurityConfig.User("dummy_user_not_registered"); + protected final static TestSecurityConfig.User UNREGISTERED = new TestSecurityConfig.User("unregistered"); - public static final String DUMMY_BASE_ENDPOINT = "_plugins/_dummy"; - public static final String DUMMY_PROTECTED_BASE_ENDPOINT = "_plugins/_dummy_protected"; - public static final String DUMMY_API = DUMMY_BASE_ENDPOINT + "/dummy"; - public static final String DUMMY_PROTECTED_API = DUMMY_PROTECTED_BASE_ENDPOINT + "/dummy"; + public static final String UNPROTECTED_BASE_ENDPOINT = "_plugins/_dummy"; + public static final String PROTECTED_BASE_ENDPOINT = "_plugins/_dummy_protected"; + public static final String UNPROTECTED_API = UNPROTECTED_BASE_ENDPOINT + "/dummy"; + public static final String PROTECTED_API = PROTECTED_BASE_ENDPOINT + "/dummy"; @ClassRule public static LocalCluster cluster = new LocalCluster.Builder().clusterManager(ClusterManager.THREE_CLUSTER_MANAGERS) .authc(AUTHC_HTTPBASIC_INTERNAL) - .users(DUMMY_REST_ONLY, DUMMY_WITH_TRANSPORT_PERM, DUMMY_LEGACY, DUMMY_NO_PERM) + .users(REST_ONLY, REST_PLUS_TRANSPORT, TRANSPORT_ONLY, NO_PERM) .plugin(CustomLegacyTestPlugin.class) .plugin(CustomRestProtectedTestPlugin.class) .audit( @@ -87,29 +84,29 @@ public class AuthZinRestLayerTests { @Test public void testShouldFailForUnregisteredUsers() { - try (TestRestClient client = cluster.getRestClient(DUMMY_UNREGISTERED)) { + try (TestRestClient client = cluster.getRestClient(UNREGISTERED)) { // Legacy plugin - assertThat(client.get(DUMMY_API).getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); - auditLogsRule.assertExactlyOne(privilegePredicateRESTLayer(FAILED_LOGIN, DUMMY_UNREGISTERED, GET, "/" + DUMMY_API)); + assertThat(client.get(UNPROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); + auditLogsRule.assertExactlyOne(privilegePredicateRESTLayer(FAILED_LOGIN, UNREGISTERED, GET, "/" + UNPROTECTED_API)); // Protected Routes plugin - assertThat(client.get(DUMMY_PROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); - auditLogsRule.assertExactlyOne(privilegePredicateRESTLayer(FAILED_LOGIN, DUMMY_UNREGISTERED, GET, "/" + DUMMY_PROTECTED_API)); + assertThat(client.get(PROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); + auditLogsRule.assertExactlyOne(privilegePredicateRESTLayer(FAILED_LOGIN, UNREGISTERED, GET, "/" + PROTECTED_API)); } } @Test public void testShouldFailForBothPlugins() { - try (TestRestClient client = cluster.getRestClient(DUMMY_NO_PERM)) { - // fail at Transport - assertThat(client.get(DUMMY_API).getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); + try (TestRestClient client = cluster.getRestClient(NO_PERM)) { + // fail at Transport (won't have a rest authz success audit log since this is not a protected endpoint) + assertThat(client.get(UNPROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); auditLogsRule.assertExactlyOne( - privilegePredicateTransportLayer(MISSING_PRIVILEGES, DUMMY_NO_PERM, "DummyRequest", "cluster:admin/dummy_plugin/dummy") + privilegePredicateTransportLayer(MISSING_PRIVILEGES, NO_PERM, "DummyRequest", "cluster:admin/dummy_plugin/dummy") ); // fail at REST - assertThat(client.get(DUMMY_PROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); - auditLogsRule.assertExactlyOne(privilegePredicateRESTLayer(MISSING_PRIVILEGES, DUMMY_NO_PERM, GET, "/" + DUMMY_PROTECTED_API)); + assertThat(client.get(PROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); + auditLogsRule.assertExactlyOne(privilegePredicateRESTLayer(MISSING_PRIVILEGES, NO_PERM, GET, "/" + PROTECTED_API)); } } @@ -117,17 +114,15 @@ public void testShouldFailForBothPlugins() { @Test public void testShouldFailAtTransportLayerWithRestOnlyPermission() { - try (TestRestClient client = cluster.getRestClient(DUMMY_REST_ONLY)) { - assertThat(client.get(DUMMY_PROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); + try (TestRestClient client = cluster.getRestClient(REST_ONLY)) { + assertThat(client.get(PROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); // granted at Rest layer - auditLogsRule.assertExactlyOne( - privilegePredicateRESTLayer(GRANTED_PRIVILEGES, DUMMY_REST_ONLY, GET, "/" + DUMMY_PROTECTED_API) - ); + auditLogsRule.assertExactlyOne(privilegePredicateRESTLayer(GRANTED_PRIVILEGES, REST_ONLY, GET, "/" + PROTECTED_API)); // missing at Transport layer auditLogsRule.assertExactlyOne( privilegePredicateTransportLayer( MISSING_PRIVILEGES, - DUMMY_REST_ONLY, + REST_ONLY, "DummyRequest", "cluster:admin/dummy_protected_plugin/dummy/get" ) @@ -136,17 +131,15 @@ public void testShouldFailAtTransportLayerWithRestOnlyPermission() { } @Test - public void testShouldPassWithRequiredPermissions() { - try (TestRestClient client = cluster.getRestClient(DUMMY_WITH_TRANSPORT_PERM)) { + public void testShouldReturnSuccessResponseWithRequiredPermissions() { + try (TestRestClient client = cluster.getRestClient(REST_PLUS_TRANSPORT)) { assertOKResponseFromProtectedPlugin(client); - auditLogsRule.assertExactlyOne( - privilegePredicateRESTLayer(GRANTED_PRIVILEGES, DUMMY_WITH_TRANSPORT_PERM, GET, "/" + DUMMY_PROTECTED_API) - ); + auditLogsRule.assertExactlyOne(privilegePredicateRESTLayer(GRANTED_PRIVILEGES, REST_PLUS_TRANSPORT, GET, "/" + PROTECTED_API)); auditLogsRule.assertExactlyOne( privilegePredicateTransportLayer( GRANTED_PRIVILEGES, - DUMMY_WITH_TRANSPORT_PERM, + REST_PLUS_TRANSPORT, "DummyRequest", "cluster:admin/dummy_protected_plugin/dummy/get" ) @@ -156,20 +149,16 @@ public void testShouldPassWithRequiredPermissions() { @Test public void testShouldFailForPOST() { - try (TestRestClient client = cluster.getRestClient(DUMMY_REST_ONLY)) { - assertThat(client.post(DUMMY_PROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); + try (TestRestClient client = cluster.getRestClient(REST_ONLY)) { + assertThat(client.post(PROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); - auditLogsRule.assertExactlyOne( - privilegePredicateRESTLayer(MISSING_PRIVILEGES, DUMMY_REST_ONLY, POST, "/" + DUMMY_PROTECTED_API) - ); + auditLogsRule.assertExactlyOne(privilegePredicateRESTLayer(MISSING_PRIVILEGES, REST_ONLY, POST, "/" + PROTECTED_API)); } - try (TestRestClient client = cluster.getRestClient(DUMMY_WITH_TRANSPORT_PERM)) { - assertThat(client.post(DUMMY_PROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); + try (TestRestClient client = cluster.getRestClient(REST_PLUS_TRANSPORT)) { + assertThat(client.post(PROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); - auditLogsRule.assertExactlyOne( - privilegePredicateRESTLayer(MISSING_PRIVILEGES, DUMMY_WITH_TRANSPORT_PERM, POST, "/" + DUMMY_PROTECTED_API) - ); + auditLogsRule.assertExactlyOne(privilegePredicateRESTLayer(MISSING_PRIVILEGES, REST_PLUS_TRANSPORT, POST, "/" + PROTECTED_API)); } } @@ -179,37 +168,37 @@ public void testShouldFailForPOST() { public void testBackwardsCompatibility() { // DUMMY_LEGACY should have access to legacy endpoint, but not protected endpoint - try (TestRestClient client = cluster.getRestClient(DUMMY_LEGACY)) { - TestRestClient.HttpResponse res = client.get(DUMMY_PROTECTED_API); + try (TestRestClient client = cluster.getRestClient(TRANSPORT_ONLY)) { + TestRestClient.HttpResponse res = client.get(PROTECTED_API); assertThat(res.getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); - auditLogsRule.assertExactlyOne(privilegePredicateRESTLayer(MISSING_PRIVILEGES, DUMMY_LEGACY, GET, "/" + DUMMY_PROTECTED_API)); + auditLogsRule.assertExactlyOne(privilegePredicateRESTLayer(MISSING_PRIVILEGES, TRANSPORT_ONLY, GET, "/" + PROTECTED_API)); assertOKResponseFromLegacyPlugin(client); // check that there is no log for REST layer AuthZ since this is an unprotected endpoint - auditLogsRule.assertExactly(0, privilegePredicateRESTLayer(GRANTED_PRIVILEGES, DUMMY_LEGACY, GET, DUMMY_API)); + auditLogsRule.assertExactly(0, privilegePredicateRESTLayer(GRANTED_PRIVILEGES, TRANSPORT_ONLY, GET, UNPROTECTED_API)); // check that there is exactly 1 message for Transport Layer privilege evaluation auditLogsRule.assertExactlyOne( - privilegePredicateTransportLayer(GRANTED_PRIVILEGES, DUMMY_LEGACY, "DummyRequest", "cluster:admin/dummy_plugin/dummy") + privilegePredicateTransportLayer(GRANTED_PRIVILEGES, TRANSPORT_ONLY, "DummyRequest", "cluster:admin/dummy_plugin/dummy") ); } // DUMMY_REST_ONLY should have access to legacy endpoint (protected endpoint already tested above) - try (TestRestClient client = cluster.getRestClient(DUMMY_REST_ONLY)) { + try (TestRestClient client = cluster.getRestClient(REST_ONLY)) { assertOKResponseFromLegacyPlugin(client); - auditLogsRule.assertExactly(0, privilegePredicateRESTLayer(GRANTED_PRIVILEGES, DUMMY_REST_ONLY, GET, DUMMY_API)); + auditLogsRule.assertExactly(0, privilegePredicateRESTLayer(GRANTED_PRIVILEGES, REST_ONLY, GET, UNPROTECTED_API)); auditLogsRule.assertExactlyOne( - privilegePredicateTransportLayer(GRANTED_PRIVILEGES, DUMMY_REST_ONLY, "DummyRequest", "cluster:admin/dummy_plugin/dummy") + privilegePredicateTransportLayer(GRANTED_PRIVILEGES, REST_ONLY, "DummyRequest", "cluster:admin/dummy_plugin/dummy") ); } // DUMMY_WITH_TRANSPORT_PERM should have access to legacy endpoint (protected endpoint already tested above) - try (TestRestClient client = cluster.getRestClient(DUMMY_WITH_TRANSPORT_PERM)) { + try (TestRestClient client = cluster.getRestClient(REST_PLUS_TRANSPORT)) { assertOKResponseFromLegacyPlugin(client); - auditLogsRule.assertExactly(0, privilegePredicateRESTLayer(GRANTED_PRIVILEGES, DUMMY_WITH_TRANSPORT_PERM, GET, DUMMY_API)); + auditLogsRule.assertExactly(0, privilegePredicateRESTLayer(GRANTED_PRIVILEGES, REST_PLUS_TRANSPORT, GET, UNPROTECTED_API)); auditLogsRule.assertExactlyOne( privilegePredicateTransportLayer( GRANTED_PRIVILEGES, - DUMMY_WITH_TRANSPORT_PERM, + REST_PLUS_TRANSPORT, "DummyRequest", "cluster:admin/dummy_plugin/dummy" ) @@ -217,37 +206,37 @@ public void testBackwardsCompatibility() { } // DUMMY_NO_PERM should not have access to legacy endpoint (protected endpoint already tested above) - try (TestRestClient client = cluster.getRestClient(DUMMY_NO_PERM)) { - assertThat(client.get(DUMMY_API).getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); - auditLogsRule.assertExactly(0, privilegePredicateRESTLayer(MISSING_PRIVILEGES, DUMMY_NO_PERM, GET, DUMMY_API)); + try (TestRestClient client = cluster.getRestClient(NO_PERM)) { + assertThat(client.get(UNPROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); + auditLogsRule.assertExactly(0, privilegePredicateRESTLayer(MISSING_PRIVILEGES, NO_PERM, GET, UNPROTECTED_API)); auditLogsRule.assertExactlyOne( - privilegePredicateTransportLayer(MISSING_PRIVILEGES, DUMMY_NO_PERM, "DummyRequest", "cluster:admin/dummy_plugin/dummy") + privilegePredicateTransportLayer(MISSING_PRIVILEGES, NO_PERM, "DummyRequest", "cluster:admin/dummy_plugin/dummy") ); } // DUMMY_UNREGISTERED should not have access to legacy endpoint (protected endpoint already tested above) - try (TestRestClient client = cluster.getRestClient(DUMMY_UNREGISTERED)) { - assertThat(client.get(DUMMY_API).getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); - auditLogsRule.assertExactly(0, privilegePredicateRESTLayer(MISSING_PRIVILEGES, DUMMY_UNREGISTERED, GET, DUMMY_API)); + try (TestRestClient client = cluster.getRestClient(UNREGISTERED)) { + assertThat(client.get(UNPROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); + auditLogsRule.assertExactly(0, privilegePredicateRESTLayer(MISSING_PRIVILEGES, UNREGISTERED, GET, UNPROTECTED_API)); auditLogsRule.assertExactly( 0, - privilegePredicateTransportLayer(MISSING_PRIVILEGES, DUMMY_UNREGISTERED, "DummyRequest", "cluster:admin/dummy_plugin/dummy") + privilegePredicateTransportLayer(MISSING_PRIVILEGES, UNREGISTERED, "DummyRequest", "cluster:admin/dummy_plugin/dummy") ); - auditLogsRule.assertExactly(0, privilegePredicateRESTLayer(FAILED_LOGIN, DUMMY_UNREGISTERED, GET, DUMMY_API)); + auditLogsRule.assertExactly(0, privilegePredicateRESTLayer(FAILED_LOGIN, UNREGISTERED, GET, UNPROTECTED_API)); } } /** Helper Methods */ private void assertOKResponseFromLegacyPlugin(TestRestClient client) { String expectedResponseFromLegacyPlugin = "{\"response_string\":\"Hello from dummy plugin\"}"; - TestRestClient.HttpResponse res = client.get(DUMMY_API); + TestRestClient.HttpResponse res = client.get(UNPROTECTED_API); assertThat(res.getStatusCode(), equalTo(HttpStatus.SC_OK)); assertThat(res.getBody(), equalTo(expectedResponseFromLegacyPlugin)); } private void assertOKResponseFromProtectedPlugin(TestRestClient client) { String expectedResponseFromProtectedPlugin = "{\"response_string\":\"Hello from dummy protected plugin\"}"; - TestRestClient.HttpResponse res = client.get(DUMMY_PROTECTED_API); + TestRestClient.HttpResponse res = client.get(PROTECTED_API); assertThat(res.getStatusCode(), equalTo(HttpStatus.SC_OK)); assertThat(res.getBody(), equalTo(expectedResponseFromProtectedPlugin)); } diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/CustomLegacyTestPlugin.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/CustomLegacyTestPlugin.java index 8f131d2544..648abef704 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/CustomLegacyTestPlugin.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummy/CustomLegacyTestPlugin.java @@ -32,6 +32,9 @@ import java.util.List; import java.util.function.Supplier; +/** + * Registers a plugin with legacy routes using {@link org.opensearch.rest.RestHandler.Route} + */ public class CustomLegacyTestPlugin extends Plugin implements ClusterPlugin, NetworkPlugin, ActionPlugin { @Override diff --git a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/CustomRestProtectedTestPlugin.java b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/CustomRestProtectedTestPlugin.java index 67ad9d4392..780bee4ac6 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/CustomRestProtectedTestPlugin.java +++ b/src/integrationTest/java/org/opensearch/test/framework/testplugins/dummyprotected/CustomRestProtectedTestPlugin.java @@ -32,6 +32,10 @@ import java.util.List; import java.util.function.Supplier; +/** + * Registers a plugin with protected routes using {@linkplain org.opensearch.rest.NamedRoute} + * This allows authorization against REST layer + */ public class CustomRestProtectedTestPlugin extends Plugin implements ClusterPlugin, NetworkPlugin, ActionPlugin { @Override From fd84d3a75dd1557814742cd4ff9091dd9d2bd030 Mon Sep 17 00:00:00 2001 From: Darshit Chanpura Date: Tue, 22 Aug 2023 18:53:37 -0400 Subject: [PATCH 13/13] Renames tests to be more readable Signed-off-by: Darshit Chanpura --- .../security/rest/AuthZinRestLayerTests.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/integrationTest/java/org/opensearch/security/rest/AuthZinRestLayerTests.java b/src/integrationTest/java/org/opensearch/security/rest/AuthZinRestLayerTests.java index a67fa196a0..96aea9d4bc 100644 --- a/src/integrationTest/java/org/opensearch/security/rest/AuthZinRestLayerTests.java +++ b/src/integrationTest/java/org/opensearch/security/rest/AuthZinRestLayerTests.java @@ -83,7 +83,7 @@ public class AuthZinRestLayerTests { /** Basic Access check */ @Test - public void testShouldFailForUnregisteredUsers() { + public void testShouldNotAllowUnregisteredUsers() { try (TestRestClient client = cluster.getRestClient(UNREGISTERED)) { // Legacy plugin assertThat(client.get(UNPROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); @@ -96,7 +96,7 @@ public void testShouldFailForUnregisteredUsers() { } @Test - public void testShouldFailForBothPlugins() { + public void testAccessDeniedForUserWithNoPermissions() { try (TestRestClient client = cluster.getRestClient(NO_PERM)) { // fail at Transport (won't have a rest authz success audit log since this is not a protected endpoint) assertThat(client.get(UNPROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); @@ -113,7 +113,7 @@ public void testShouldFailForBothPlugins() { /** AuthZ in REST Layer check */ @Test - public void testShouldFailAtTransportLayerWithRestOnlyPermission() { + public void testShouldAllowAtRestAndBlockAtTransport() { try (TestRestClient client = cluster.getRestClient(REST_ONLY)) { assertThat(client.get(PROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); // granted at Rest layer @@ -131,7 +131,7 @@ public void testShouldFailAtTransportLayerWithRestOnlyPermission() { } @Test - public void testShouldReturnSuccessResponseWithRequiredPermissions() { + public void testShouldAllowAtRestAndTransport() { try (TestRestClient client = cluster.getRestClient(REST_PLUS_TRANSPORT)) { assertOKResponseFromProtectedPlugin(client); @@ -148,7 +148,7 @@ public void testShouldReturnSuccessResponseWithRequiredPermissions() { } @Test - public void testShouldFailForPOST() { + public void testShouldBlockAccessToEndpointForWhichUserHasNoPermission() { try (TestRestClient client = cluster.getRestClient(REST_ONLY)) { assertThat(client.post(PROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); @@ -167,7 +167,7 @@ public void testShouldFailForPOST() { @Test public void testBackwardsCompatibility() { - // DUMMY_LEGACY should have access to legacy endpoint, but not protected endpoint + // TRANSPORT_ONLY should have access to legacy endpoint, but not protected endpoint try (TestRestClient client = cluster.getRestClient(TRANSPORT_ONLY)) { TestRestClient.HttpResponse res = client.get(PROTECTED_API); assertThat(res.getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); @@ -182,7 +182,7 @@ public void testBackwardsCompatibility() { ); } - // DUMMY_REST_ONLY should have access to legacy endpoint (protected endpoint already tested above) + // REST_ONLY should have access to legacy endpoint (protected endpoint already tested above) try (TestRestClient client = cluster.getRestClient(REST_ONLY)) { assertOKResponseFromLegacyPlugin(client); auditLogsRule.assertExactly(0, privilegePredicateRESTLayer(GRANTED_PRIVILEGES, REST_ONLY, GET, UNPROTECTED_API)); @@ -205,7 +205,7 @@ public void testBackwardsCompatibility() { ); } - // DUMMY_NO_PERM should not have access to legacy endpoint (protected endpoint already tested above) + // NO_PERM should not have access to legacy endpoint (protected endpoint already tested above) try (TestRestClient client = cluster.getRestClient(NO_PERM)) { assertThat(client.get(UNPROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_FORBIDDEN)); auditLogsRule.assertExactly(0, privilegePredicateRESTLayer(MISSING_PRIVILEGES, NO_PERM, GET, UNPROTECTED_API)); @@ -214,7 +214,7 @@ public void testBackwardsCompatibility() { ); } - // DUMMY_UNREGISTERED should not have access to legacy endpoint (protected endpoint already tested above) + // UNREGISTERED should not have access to legacy endpoint (protected endpoint already tested above) try (TestRestClient client = cluster.getRestClient(UNREGISTERED)) { assertThat(client.get(UNPROTECTED_API).getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); auditLogsRule.assertExactly(0, privilegePredicateRESTLayer(MISSING_PRIVILEGES, UNREGISTERED, GET, UNPROTECTED_API));