From 283720064bf4b055dbc2aaf47f1174d81433cc47 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Wed, 12 Jul 2023 15:54:45 -0400 Subject: [PATCH 01/33] Outline changes Signed-off-by: Stephen Crawford --- .../extensions/ExtensionsManager.java | 6 +- .../extensions/NoopExtensionsManager.java | 4 +- .../rest/RestActionsRequestHandler.java | 12 +- .../rest/RestSendToExtensionAction.java | 40 ++--- .../main/java/org/opensearch/node/Node.java | 137 +++++++++--------- .../extensions/ExtensionsManagerTests.java | 44 +++--- 6 files changed, 129 insertions(+), 114 deletions(-) diff --git a/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java b/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java index cb22c8d864b1b..124bd47451e07 100644 --- a/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java +++ b/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java @@ -49,6 +49,7 @@ import org.opensearch.extensions.rest.RestActionsRequestHandler; import org.opensearch.extensions.settings.CustomSettingsRequestHandler; import org.opensearch.extensions.settings.RegisterCustomSettingsRequest; +import org.opensearch.identity.IdentityService; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.ConnectTransportException; import org.opensearch.transport.TransportException; @@ -142,9 +143,10 @@ public void initializeServicesAndRestHandler( TransportService transportService, ClusterService clusterService, Settings initialEnvironmentSettings, - NodeClient client + NodeClient client, + IdentityService identityService ) { - this.restActionsRequestHandler = new RestActionsRequestHandler(actionModule.getRestController(), extensionIdMap, transportService); + this.restActionsRequestHandler = new RestActionsRequestHandler(actionModule.getRestController(), extensionIdMap, transportService, identityService); this.customSettingsRequestHandler = new CustomSettingsRequestHandler(settingsModule); this.transportService = transportService; this.clusterService = clusterService; diff --git a/server/src/main/java/org/opensearch/extensions/NoopExtensionsManager.java b/server/src/main/java/org/opensearch/extensions/NoopExtensionsManager.java index d434074279041..d0f69efc0de3a 100644 --- a/server/src/main/java/org/opensearch/extensions/NoopExtensionsManager.java +++ b/server/src/main/java/org/opensearch/extensions/NoopExtensionsManager.java @@ -21,6 +21,7 @@ import org.opensearch.extensions.action.ExtensionActionRequest; import org.opensearch.extensions.action.ExtensionActionResponse; import org.opensearch.extensions.action.RemoteExtensionActionResponse; +import org.opensearch.identity.IdentityService; import org.opensearch.transport.TransportService; /** @@ -41,7 +42,8 @@ public void initializeServicesAndRestHandler( TransportService transportService, ClusterService clusterService, Settings initialEnvironmentSettings, - NodeClient client + NodeClient client, + IdentityService identityService ) { // no-op } diff --git a/server/src/main/java/org/opensearch/extensions/rest/RestActionsRequestHandler.java b/server/src/main/java/org/opensearch/extensions/rest/RestActionsRequestHandler.java index d890c1b85bb81..130a45479b150 100644 --- a/server/src/main/java/org/opensearch/extensions/rest/RestActionsRequestHandler.java +++ b/server/src/main/java/org/opensearch/extensions/rest/RestActionsRequestHandler.java @@ -8,16 +8,16 @@ package org.opensearch.extensions.rest; +import java.util.Map; import org.opensearch.action.ActionModule.DynamicActionRegistry; import org.opensearch.extensions.AcknowledgedResponse; import org.opensearch.extensions.DiscoveryExtensionNode; +import org.opensearch.identity.IdentityService; import org.opensearch.rest.RestController; import org.opensearch.rest.RestHandler; import org.opensearch.transport.TransportResponse; import org.opensearch.transport.TransportService; -import java.util.Map; - /** * Handles requests to register extension REST actions. * @@ -28,6 +28,7 @@ public class RestActionsRequestHandler { private final RestController restController; private final Map extensionIdMap; private final TransportService transportService; + private final IdentityService identityService; /** * Instantiates a new REST Actions Request Handler using the Node's RestController. @@ -39,11 +40,13 @@ public class RestActionsRequestHandler { public RestActionsRequestHandler( RestController restController, Map extensionIdMap, - TransportService transportService + TransportService transportService, + IdentityService identityService ) { this.restController = restController; this.extensionIdMap = extensionIdMap; this.transportService = transportService; + this.identityService = identityService; } /** @@ -62,7 +65,8 @@ public TransportResponse handleRegisterRestActionsRequest( restActionsRequest, discoveryExtensionNode, transportService, - dynamicActionRegistry + dynamicActionRegistry, + identityService ); restController.registerHandler(handler); return new AcknowledgedResponse(true); diff --git a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java index 3dd6056bb36cf..77ac10acbfd15 100644 --- a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java +++ b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java @@ -8,6 +8,19 @@ package org.opensearch.extensions.rest; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.security.Principal; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.stream.Collectors; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.opensearch.action.ActionModule.DynamicActionRegistry; @@ -17,6 +30,9 @@ import org.opensearch.common.xcontent.XContentType; import org.opensearch.extensions.DiscoveryExtensionNode; import org.opensearch.extensions.ExtensionsManager; +import org.opensearch.http.HttpRequest; +import org.opensearch.identity.IdentityService; +import org.opensearch.identity.tokens.AuthToken; import org.opensearch.rest.BaseRestHandler; import org.opensearch.rest.BytesRestResponse; import org.opensearch.rest.NamedRoute; @@ -27,22 +43,6 @@ import org.opensearch.transport.TransportException; import org.opensearch.transport.TransportResponseHandler; import org.opensearch.transport.TransportService; -import org.opensearch.http.HttpRequest; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.security.Principal; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - import static java.util.Collections.emptyList; import static java.util.Collections.emptyMap; import static java.util.Collections.unmodifiableList; @@ -67,6 +67,7 @@ public String getName() { private final String pathPrefix; private final DiscoveryExtensionNode discoveryExtensionNode; private final TransportService transportService; + private final IdentityService identityService; private static final Set allowList = Set.of("Content-Type"); private static final Set denyList = Set.of("Authorization", "Proxy-Authorization"); @@ -82,7 +83,8 @@ public RestSendToExtensionAction( RegisterRestActionsRequest restActionsRequest, DiscoveryExtensionNode discoveryExtensionNode, TransportService transportService, - DynamicActionRegistry dynamicActionRegistry + DynamicActionRegistry dynamicActionRegistry, + IdentityService identityService ) { this.pathPrefix = "/_extensions/_" + restActionsRequest.getUniqueId(); RestRequest.Method method; @@ -147,6 +149,7 @@ public RestSendToExtensionAction( this.discoveryExtensionNode = discoveryExtensionNode; this.transportService = transportService; + this.identityService = identityService; } @Override @@ -242,8 +245,11 @@ public String executor() { try { // Will be replaced with ExtensionTokenProcessor and PrincipalIdentifierToken classes from feature/identity final String extensionTokenProcessor = "placeholder_token_processor"; + final String requestIssuerIdentity = "placeholder_request_issuer_identity"; + AuthToken token = identityService.getTokenManager().issueToken(extensionTokenProcessor); + Map> filteredHeaders = filterHeaders(headers, allowList, denyList); transportService.sendRequest( diff --git a/server/src/main/java/org/opensearch/node/Node.java b/server/src/main/java/org/opensearch/node/Node.java index aecf5659de7fe..b2e3e567ebf2b 100644 --- a/server/src/main/java/org/opensearch/node/Node.java +++ b/server/src/main/java/org/opensearch/node/Node.java @@ -32,46 +32,40 @@ package org.opensearch.node; +import java.io.BufferedWriter; +import java.io.Closeable; +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; +import java.util.function.UnaryOperator; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.net.ssl.SNIHostName; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.lucene.util.Constants; -import org.opensearch.ExceptionsHelper; -import org.opensearch.common.SetOnce; -import org.opensearch.common.settings.SettingsException; -import org.opensearch.common.unit.ByteSizeUnit; -import org.opensearch.common.unit.ByteSizeValue; -import org.opensearch.common.util.FeatureFlags; -import org.opensearch.cluster.routing.allocation.AwarenessReplicaBalance; -import org.opensearch.index.IndexModule; -import org.opensearch.index.IndexingPressureService; -import org.opensearch.index.store.remote.filecache.FileCache; -import org.opensearch.index.store.remote.filecache.FileCacheCleaner; -import org.opensearch.index.store.remote.filecache.FileCacheFactory; -import org.opensearch.indices.replication.SegmentReplicationSourceFactory; -import org.opensearch.indices.replication.SegmentReplicationTargetService; -import org.opensearch.indices.replication.SegmentReplicationSourceService; -import org.opensearch.extensions.ExtensionsManager; -import org.opensearch.extensions.NoopExtensionsManager; -import org.opensearch.monitor.fs.FsInfo; -import org.opensearch.monitor.fs.FsProbe; -import org.opensearch.plugins.ExtensionAwarePlugin; -import org.opensearch.plugins.SearchPipelinePlugin; -import org.opensearch.telemetry.tracing.NoopTracerFactory; -import org.opensearch.telemetry.tracing.TracerFactory; -import org.opensearch.search.backpressure.SearchBackpressureService; -import org.opensearch.search.backpressure.settings.SearchBackpressureSettings; -import org.opensearch.search.pipeline.SearchPipelineService; -import org.opensearch.tasks.TaskCancellationMonitoringService; -import org.opensearch.tasks.TaskCancellationMonitoringSettings; -import org.opensearch.tasks.TaskResourceTrackingService; -import org.opensearch.tasks.consumer.TopNSearchTasksLogger; -import org.opensearch.threadpool.RunnableTaskExecutionListener; -import org.opensearch.index.store.RemoteSegmentStoreDirectoryFactory; -import org.opensearch.telemetry.TelemetryModule; -import org.opensearch.telemetry.TelemetrySettings; -import org.opensearch.watcher.ResourceWatcherService; -import org.opensearch.core.Assertions; import org.opensearch.Build; +import org.opensearch.ExceptionsHelper; import org.opensearch.OpenSearchException; import org.opensearch.OpenSearchTimeoutException; import org.opensearch.Version; @@ -108,8 +102,10 @@ import org.opensearch.cluster.node.DiscoveryNodeRole; import org.opensearch.cluster.routing.BatchedRerouteService; import org.opensearch.cluster.routing.RerouteService; +import org.opensearch.cluster.routing.allocation.AwarenessReplicaBalance; import org.opensearch.cluster.routing.allocation.DiskThresholdMonitor; import org.opensearch.cluster.service.ClusterService; +import org.opensearch.common.SetOnce; import org.opensearch.common.StopWatch; import org.opensearch.common.breaker.CircuitBreaker; import org.opensearch.common.component.Lifecycle; @@ -119,6 +115,7 @@ import org.opensearch.common.inject.Module; import org.opensearch.common.inject.ModulesBuilder; import org.opensearch.common.io.stream.NamedWriteableRegistry; +import org.opensearch.common.lease.Releasables; import org.opensearch.common.logging.DeprecationLogger; import org.opensearch.common.logging.HeaderWarning; import org.opensearch.common.logging.NodeAndClusterIdStateListener; @@ -131,20 +128,26 @@ import org.opensearch.common.settings.Setting.Property; import org.opensearch.common.settings.SettingUpgrader; import org.opensearch.common.settings.Settings; +import org.opensearch.common.settings.SettingsException; import org.opensearch.common.settings.SettingsModule; import org.opensearch.common.transport.BoundTransportAddress; import org.opensearch.common.transport.TransportAddress; +import org.opensearch.common.unit.ByteSizeUnit; +import org.opensearch.common.unit.ByteSizeValue; import org.opensearch.common.unit.TimeValue; import org.opensearch.common.util.BigArrays; +import org.opensearch.common.util.FeatureFlags; import org.opensearch.common.util.PageCacheRecycler; import org.opensearch.common.util.io.IOUtils; -import org.opensearch.common.lease.Releasables; +import org.opensearch.core.Assertions; import org.opensearch.core.xcontent.NamedXContentRegistry; import org.opensearch.discovery.Discovery; import org.opensearch.discovery.DiscoveryModule; import org.opensearch.env.Environment; import org.opensearch.env.NodeEnvironment; import org.opensearch.env.NodeMetadata; +import org.opensearch.extensions.ExtensionsManager; +import org.opensearch.extensions.NoopExtensionsManager; import org.opensearch.gateway.GatewayAllocator; import org.opensearch.gateway.GatewayMetaState; import org.opensearch.gateway.GatewayModule; @@ -153,9 +156,15 @@ import org.opensearch.gateway.PersistedClusterStateService; import org.opensearch.http.HttpServerTransport; import org.opensearch.identity.IdentityService; +import org.opensearch.index.IndexModule; import org.opensearch.index.IndexSettings; +import org.opensearch.index.IndexingPressureService; import org.opensearch.index.analysis.AnalysisRegistry; import org.opensearch.index.engine.EngineFactory; +import org.opensearch.index.store.RemoteSegmentStoreDirectoryFactory; +import org.opensearch.index.store.remote.filecache.FileCache; +import org.opensearch.index.store.remote.filecache.FileCacheCleaner; +import org.opensearch.index.store.remote.filecache.FileCacheFactory; import org.opensearch.indices.IndicesModule; import org.opensearch.indices.IndicesService; import org.opensearch.indices.ShardLimitValidator; @@ -170,10 +179,15 @@ import org.opensearch.indices.recovery.PeerRecoverySourceService; import org.opensearch.indices.recovery.PeerRecoveryTargetService; import org.opensearch.indices.recovery.RecoverySettings; +import org.opensearch.indices.replication.SegmentReplicationSourceFactory; +import org.opensearch.indices.replication.SegmentReplicationSourceService; +import org.opensearch.indices.replication.SegmentReplicationTargetService; import org.opensearch.indices.store.IndicesStore; import org.opensearch.ingest.IngestService; import org.opensearch.monitor.MonitorService; import org.opensearch.monitor.fs.FsHealthService; +import org.opensearch.monitor.fs.FsInfo; +import org.opensearch.monitor.fs.FsProbe; import org.opensearch.monitor.jvm.JvmInfo; import org.opensearch.persistent.PersistentTasksClusterService; import org.opensearch.persistent.PersistentTasksExecutor; @@ -185,6 +199,7 @@ import org.opensearch.plugins.ClusterPlugin; import org.opensearch.plugins.DiscoveryPlugin; import org.opensearch.plugins.EnginePlugin; +import org.opensearch.plugins.ExtensionAwarePlugin; import org.opensearch.plugins.IdentityPlugin; import org.opensearch.plugins.IndexStorePlugin; import org.opensearch.plugins.IngestPlugin; @@ -196,6 +211,7 @@ import org.opensearch.plugins.PluginsService; import org.opensearch.plugins.RepositoryPlugin; import org.opensearch.plugins.ScriptPlugin; +import org.opensearch.plugins.SearchPipelinePlugin; import org.opensearch.plugins.SearchPlugin; import org.opensearch.plugins.SystemIndexPlugin; import org.opensearch.plugins.TelemetryPlugin; @@ -209,7 +225,10 @@ import org.opensearch.search.SearchModule; import org.opensearch.search.SearchService; import org.opensearch.search.aggregations.support.AggregationUsageService; +import org.opensearch.search.backpressure.SearchBackpressureService; +import org.opensearch.search.backpressure.settings.SearchBackpressureSettings; import org.opensearch.search.fetch.FetchPhase; +import org.opensearch.search.pipeline.SearchPipelineService; import org.opensearch.search.query.QueryPhase; import org.opensearch.snapshots.InternalSnapshotsInfoService; import org.opensearch.snapshots.RestoreService; @@ -217,46 +236,25 @@ import org.opensearch.snapshots.SnapshotsInfoService; import org.opensearch.snapshots.SnapshotsService; import org.opensearch.tasks.Task; +import org.opensearch.tasks.TaskCancellationMonitoringService; +import org.opensearch.tasks.TaskCancellationMonitoringSettings; import org.opensearch.tasks.TaskCancellationService; +import org.opensearch.tasks.TaskResourceTrackingService; import org.opensearch.tasks.TaskResultsService; +import org.opensearch.tasks.consumer.TopNSearchTasksLogger; +import org.opensearch.telemetry.TelemetryModule; +import org.opensearch.telemetry.TelemetrySettings; +import org.opensearch.telemetry.tracing.NoopTracerFactory; +import org.opensearch.telemetry.tracing.TracerFactory; import org.opensearch.threadpool.ExecutorBuilder; +import org.opensearch.threadpool.RunnableTaskExecutionListener; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.RemoteClusterService; import org.opensearch.transport.Transport; import org.opensearch.transport.TransportInterceptor; import org.opensearch.transport.TransportService; import org.opensearch.usage.UsageService; - -import javax.net.ssl.SNIHostName; -import java.io.BufferedWriter; -import java.io.Closeable; -import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardCopyOption; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Executor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Function; -import java.util.function.UnaryOperator; -import java.util.stream.Collectors; -import java.util.stream.Stream; - +import org.opensearch.watcher.ResourceWatcherService; import static java.util.stream.Collectors.toList; import static org.opensearch.common.util.FeatureFlags.SEARCH_PIPELINE; import static org.opensearch.common.util.FeatureFlags.TELEMETRY; @@ -869,7 +867,8 @@ protected Node( transportService, clusterService, environment.settings(), - client + client, + identityService ); final GatewayMetaState gatewayMetaState = new GatewayMetaState(); final ResponseCollectorService responseCollectorService = new ResponseCollectorService(clusterService); diff --git a/server/src/test/java/org/opensearch/extensions/ExtensionsManagerTests.java b/server/src/test/java/org/opensearch/extensions/ExtensionsManagerTests.java index 3f61d01166fb9..f97e608ec492c 100644 --- a/server/src/test/java/org/opensearch/extensions/ExtensionsManagerTests.java +++ b/server/src/test/java/org/opensearch/extensions/ExtensionsManagerTests.java @@ -8,19 +8,6 @@ package org.opensearch.extensions; -import static java.util.Collections.emptyList; -import static java.util.Collections.emptyMap; -import static java.util.Collections.emptySet; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.mock; -import static org.opensearch.test.ClusterServiceUtils.createClusterService; - import java.io.IOException; import java.net.InetAddress; import java.nio.file.Path; @@ -32,7 +19,6 @@ import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; - import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.junit.After; @@ -44,8 +30,6 @@ import org.opensearch.action.admin.cluster.state.ClusterStateResponse; import org.opensearch.client.node.NodeClient; import org.opensearch.cluster.ClusterSettingsResponse; -import org.opensearch.common.util.FeatureFlags; -import org.opensearch.env.EnvironmentSettingsResponse; import org.opensearch.cluster.metadata.IndexMetadata; import org.opensearch.cluster.node.DiscoveryNode; import org.opensearch.cluster.service.ClusterService; @@ -55,18 +39,20 @@ import org.opensearch.common.io.stream.NamedWriteableRegistry; import org.opensearch.common.network.NetworkService; import org.opensearch.common.settings.Setting; +import org.opensearch.common.settings.Setting.Property; import org.opensearch.common.settings.Settings; +import org.opensearch.common.settings.SettingsModule; import org.opensearch.common.settings.WriteableSetting; -import org.opensearch.common.settings.Setting.Property; import org.opensearch.common.settings.WriteableSetting.SettingType; -import org.opensearch.common.settings.SettingsModule; import org.opensearch.common.transport.TransportAddress; +import org.opensearch.common.util.FeatureFlags; import org.opensearch.common.util.PageCacheRecycler; import org.opensearch.env.Environment; +import org.opensearch.env.EnvironmentSettingsResponse; +import org.opensearch.extensions.ExtensionsSettings.Extension; import org.opensearch.extensions.proto.ExtensionRequestProto; import org.opensearch.extensions.rest.RegisterRestActionsRequest; import org.opensearch.extensions.settings.RegisterCustomSettingsRequest; -import org.opensearch.extensions.ExtensionsSettings.Extension; import org.opensearch.identity.IdentityService; import org.opensearch.indices.breaker.NoneCircuitBreakerService; import org.opensearch.plugins.ExtensionAwarePlugin; @@ -83,6 +69,18 @@ import org.opensearch.transport.TransportService; import org.opensearch.transport.nio.MockNioTransport; import org.opensearch.usage.UsageService; +import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; +import static java.util.Collections.emptySet; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.opensearch.test.ClusterServiceUtils.createClusterService; public class ExtensionsManagerTests extends OpenSearchTestCase { private TransportService transportService; @@ -95,6 +93,7 @@ public class ExtensionsManagerTests extends OpenSearchTestCase { private Setting customSetting = Setting.simpleString("custom_extension_setting", "none", Property.ExtensionScope); private NodeClient client; private MockNioTransport transport; + private IdentityService identityService; private Path extensionDir; private final ThreadPool threadPool = new TestThreadPool(ExtensionsManagerTests.class.getSimpleName()); private final Settings settings = Settings.builder() @@ -190,6 +189,7 @@ public List> getExtensionSettings() { Collections.emptyList() ); client = new NoOpNodeClient(this.getTestName()); + identityService = new IdentityService(Settings.EMPTY, List.of()); } @Override @@ -793,7 +793,8 @@ public void testRegisterHandler() throws Exception { mockTransportService, clusterService, settings, - client + client, + identityService ); verify(mockTransportService, times(9)).registerRequestHandler(anyString(), anyString(), anyBoolean(), anyBoolean(), any(), any()); @@ -910,7 +911,8 @@ private void initialize(ExtensionsManager extensionsManager) { transportService, clusterService, settings, - client + client, + identityService ); } } From 570c04b43dba07c6d38e1e880c8e3ea63f9d1270 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Wed, 12 Jul 2023 17:13:59 -0400 Subject: [PATCH 02/33] Basic outline Signed-off-by: Stephen Crawford --- .../identity/shiro/ShiroIdentityPlugin.java | 25 +++++++++++++++---- .../rest/RestSendToExtensionAction.java | 10 +++++--- .../opensearch/identity/IdentityService.java | 13 ++++++++++ .../identity/noop/NoopIdentityPlugin.java | 6 +++++ .../identity/tokens/TokenManager.java | 9 +++++++ .../opensearch/plugins/IdentityPlugin.java | 11 ++++++++ 6 files changed, 65 insertions(+), 9 deletions(-) diff --git a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroIdentityPlugin.java b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroIdentityPlugin.java index c3c08b1359aaa..9cb84eaa60f83 100644 --- a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroIdentityPlugin.java +++ b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroIdentityPlugin.java @@ -8,15 +8,17 @@ package org.opensearch.identity.shiro; -import org.opensearch.identity.Subject; +import java.security.Principal; +import java.util.List; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.mgt.SecurityManager; +import org.opensearch.common.settings.Settings; +import org.opensearch.identity.Subject; import org.opensearch.identity.tokens.TokenManager; import org.opensearch.plugins.IdentityPlugin; -import org.opensearch.common.settings.Settings; import org.opensearch.plugins.Plugin; -import org.apache.shiro.SecurityUtils; -import org.apache.shiro.mgt.SecurityManager; /** * Identity implementation with Shiro @@ -28,6 +30,7 @@ public final class ShiroIdentityPlugin extends Plugin implements IdentityPlugin private final Settings settings; private final ShiroTokenManager authTokenHandler; + private List shiroSubjectList = List.of(); /** * Create a new instance of the Shiro Identity Plugin @@ -49,7 +52,9 @@ public ShiroIdentityPlugin(final Settings settings) { */ @Override public Subject getSubject() { - return new ShiroSubject(authTokenHandler, SecurityUtils.getSubject()); + ShiroSubject newShiroSubject = new ShiroSubject(authTokenHandler, SecurityUtils.getSubject()); + shiroSubjectList.add(newShiroSubject); + return newShiroSubject; } /** @@ -61,4 +66,14 @@ public Subject getSubject() { public TokenManager getTokenManager() { return this.authTokenHandler; } + + @Override + public Subject identifyRequester(Principal principal) { + for (ShiroSubject shiroSubject : shiroSubjectList) { + if (shiroSubject.getPrincipal().equals(principal)) { + return shiroSubject; + } + }; + return null; + } } diff --git a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java index 77ac10acbfd15..48e5a78a66bb3 100644 --- a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java +++ b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java @@ -32,7 +32,6 @@ import org.opensearch.extensions.ExtensionsManager; import org.opensearch.http.HttpRequest; import org.opensearch.identity.IdentityService; -import org.opensearch.identity.tokens.AuthToken; import org.opensearch.rest.BaseRestHandler; import org.opensearch.rest.BytesRestResponse; import org.opensearch.rest.NamedRoute; @@ -244,11 +243,14 @@ public String executor() { try { // Will be replaced with ExtensionTokenProcessor and PrincipalIdentifierToken classes from feature/identity + final String extensionTokenProcessor = "placeholder_token_processor"; - final String requestIssuerIdentity = "placeholder_request_issuer_identity"; + // Authenticate the token + // identityService.getTokenManager().authenticateToken(); - AuthToken token = identityService.getTokenManager().issueToken(extensionTokenProcessor); + // Resolve a principal to identify the token type required + // Subject requester = identityService.identifyRequester(identityService.toPrincipal(discoveryExtensionNode.getId())); Map> filteredHeaders = filterHeaders(headers, allowList, denyList); @@ -265,7 +267,7 @@ public String executor() { filteredHeaders, contentType, content, - requestIssuerIdentity, + identityService.getTokenManager().issueToken(discoveryExtensionNode.getId()).toString(), httpVersion ), restExecuteOnExtensionResponseHandler diff --git a/server/src/main/java/org/opensearch/identity/IdentityService.java b/server/src/main/java/org/opensearch/identity/IdentityService.java index 54a11c8b31fb3..229ee5e718d4f 100644 --- a/server/src/main/java/org/opensearch/identity/IdentityService.java +++ b/server/src/main/java/org/opensearch/identity/IdentityService.java @@ -5,6 +5,7 @@ package org.opensearch.identity; +import java.security.Principal; import java.util.List; import java.util.stream.Collectors; import org.apache.logging.log4j.LogManager; @@ -56,4 +57,16 @@ public Subject getSubject() { public TokenManager getTokenManager() { return identityPlugin.getTokenManager(); } + + /** + * Identifies the Subject associated with a request + */ + public Subject identifyRequester(final Principal principal){ + + return identityPlugin.identifyRequester(principal); + } + + public Principal toPrincipal(String principal) { + return identityPlugin.toPrincipal(principal); + } } diff --git a/server/src/main/java/org/opensearch/identity/noop/NoopIdentityPlugin.java b/server/src/main/java/org/opensearch/identity/noop/NoopIdentityPlugin.java index c6ed8d57da435..245dd5d4eb53c 100644 --- a/server/src/main/java/org/opensearch/identity/noop/NoopIdentityPlugin.java +++ b/server/src/main/java/org/opensearch/identity/noop/NoopIdentityPlugin.java @@ -8,6 +8,7 @@ package org.opensearch.identity.noop; +import java.security.Principal; import org.opensearch.identity.tokens.TokenManager; import org.opensearch.plugins.IdentityPlugin; import org.opensearch.identity.Subject; @@ -38,4 +39,9 @@ public Subject getSubject() { public TokenManager getTokenManager() { return new NoopTokenManager(); } + + @Override + public Subject identifyRequester(Principal principal) { + return new NoopSubject(); + } } diff --git a/server/src/main/java/org/opensearch/identity/tokens/TokenManager.java b/server/src/main/java/org/opensearch/identity/tokens/TokenManager.java index 029ce430e7532..17fca6eb3f593 100644 --- a/server/src/main/java/org/opensearch/identity/tokens/TokenManager.java +++ b/server/src/main/java/org/opensearch/identity/tokens/TokenManager.java @@ -8,6 +8,8 @@ package org.opensearch.identity.tokens; +import org.opensearch.identity.Subject; + /** * This interface defines the expected methods of a token manager */ @@ -19,4 +21,11 @@ public interface TokenManager { * @return A new auth token */ public AuthToken issueToken(String audience); + + /** + * Authenticates a provided authToken + * @param authToken: The authToken to authenticate + * @return The authenticated subject + */ + public Subject authenticateToken(AuthToken authToken); } diff --git a/server/src/main/java/org/opensearch/plugins/IdentityPlugin.java b/server/src/main/java/org/opensearch/plugins/IdentityPlugin.java index 00f3f8aff585c..492e595fc9f90 100644 --- a/server/src/main/java/org/opensearch/plugins/IdentityPlugin.java +++ b/server/src/main/java/org/opensearch/plugins/IdentityPlugin.java @@ -8,6 +8,7 @@ package org.opensearch.plugins; +import java.security.Principal; import org.opensearch.identity.Subject; import org.opensearch.identity.tokens.TokenManager; @@ -31,4 +32,14 @@ public interface IdentityPlugin { * Should never return null */ public TokenManager getTokenManager(); + + /** + * Identifies the Subject associated with a request + */ + public Subject identifyRequester(final Principal principal); + + /** + * Creates a standardized principal concept for an Identity Plugin + */ + public Principal toPrincipal(String principal); } From abd83c432cd1a4d2e6d2dd8ced15080af35889c4 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Thu, 13 Jul 2023 09:57:57 -0400 Subject: [PATCH 03/33] Basic token passing Signed-off-by: Stephen Crawford --- .../identity/shiro/ShiroTokenManager.java | 18 ++++++- .../rest/RestSendToExtensionAction.java | 9 ---- .../opensearch/identity/IdentityService.java | 13 ----- .../identity/noop/NoopTokenManager.java | 6 +++ .../identity/tokens/TokenManager.java | 4 +- .../rest/RestSendToExtensionActionTests.java | 52 ++++++++++--------- 6 files changed, 54 insertions(+), 48 deletions(-) diff --git a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java index 110095a5cd4ef..be7c2d36e0af2 100644 --- a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java +++ b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java @@ -20,8 +20,10 @@ import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.UsernamePasswordToken; +import org.apache.shiro.authz.UnauthenticatedException; import org.opensearch.common.Randomness; import org.opensearch.identity.IdentityService; +import org.opensearch.identity.Subject; import org.opensearch.identity.tokens.AuthToken; import org.opensearch.identity.tokens.BasicAuthToken; import org.opensearch.identity.tokens.TokenManager; @@ -51,7 +53,6 @@ public Optional translateAuthToken(org.opensearch.identity. final BasicAuthToken basicAuthToken = (BasicAuthToken) authenticationToken; return Optional.of(new UsernamePasswordToken(basicAuthToken.getUser(), basicAuthToken.getPassword())); } - return Optional.empty(); } @@ -68,6 +69,21 @@ public AuthToken issueToken(String audience) { return token; } + @Override + public Subject authenticateToken(AuthToken authToken) { + Optional translatedToken = null; + if (authToken instanceof BasicAuthToken) { + if (shiroTokenPasswordMap.containsKey(authToken)) { + translatedToken = translateAuthToken(authToken); + } else { + throw new UnauthenticatedException("Invalid token"); + } + } + SecurityUtils.getSubject().login(translatedToken.get()); + return new ShiroSubject(this, SecurityUtils.getSubject()); + } + + public boolean validateToken(AuthToken token) { if (token instanceof BasicAuthToken) { final BasicAuthToken basicAuthToken = (BasicAuthToken) token; diff --git a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java index 48e5a78a66bb3..e503c1754b486 100644 --- a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java +++ b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java @@ -242,15 +242,6 @@ public String executor() { }; try { - // Will be replaced with ExtensionTokenProcessor and PrincipalIdentifierToken classes from feature/identity - - final String extensionTokenProcessor = "placeholder_token_processor"; - - // Authenticate the token - // identityService.getTokenManager().authenticateToken(); - - // Resolve a principal to identify the token type required - // Subject requester = identityService.identifyRequester(identityService.toPrincipal(discoveryExtensionNode.getId())); Map> filteredHeaders = filterHeaders(headers, allowList, denyList); diff --git a/server/src/main/java/org/opensearch/identity/IdentityService.java b/server/src/main/java/org/opensearch/identity/IdentityService.java index 229ee5e718d4f..54a11c8b31fb3 100644 --- a/server/src/main/java/org/opensearch/identity/IdentityService.java +++ b/server/src/main/java/org/opensearch/identity/IdentityService.java @@ -5,7 +5,6 @@ package org.opensearch.identity; -import java.security.Principal; import java.util.List; import java.util.stream.Collectors; import org.apache.logging.log4j.LogManager; @@ -57,16 +56,4 @@ public Subject getSubject() { public TokenManager getTokenManager() { return identityPlugin.getTokenManager(); } - - /** - * Identifies the Subject associated with a request - */ - public Subject identifyRequester(final Principal principal){ - - return identityPlugin.identifyRequester(principal); - } - - public Principal toPrincipal(String principal) { - return identityPlugin.toPrincipal(principal); - } } diff --git a/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java b/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java index a55f28e02a8aa..1637c73d23bfc 100644 --- a/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java +++ b/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java @@ -11,6 +11,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.opensearch.identity.IdentityService; +import org.opensearch.identity.Subject; import org.opensearch.identity.tokens.AuthToken; import org.opensearch.identity.tokens.TokenManager; @@ -30,4 +31,9 @@ public AuthToken issueToken(String audience) { return new AuthToken() { }; } + + @Override + public Subject authenticateToken(AuthToken authToken) { + return null; + } } diff --git a/server/src/main/java/org/opensearch/identity/tokens/TokenManager.java b/server/src/main/java/org/opensearch/identity/tokens/TokenManager.java index 17fca6eb3f593..77144dafa0b9d 100644 --- a/server/src/main/java/org/opensearch/identity/tokens/TokenManager.java +++ b/server/src/main/java/org/opensearch/identity/tokens/TokenManager.java @@ -16,7 +16,9 @@ public interface TokenManager { /** - * Create a new auth token + * Create a new auth token. + * If the audience is an application ? serviceAccountToken : OnBehalfOf token + * * @param audience: The audience for the token * @return A new auth token */ diff --git a/server/src/test/java/org/opensearch/extensions/rest/RestSendToExtensionActionTests.java b/server/src/test/java/org/opensearch/extensions/rest/RestSendToExtensionActionTests.java index 23a9169b91e21..000241d3d3d7a 100644 --- a/server/src/test/java/org/opensearch/extensions/rest/RestSendToExtensionActionTests.java +++ b/server/src/test/java/org/opensearch/extensions/rest/RestSendToExtensionActionTests.java @@ -10,20 +10,14 @@ import java.net.InetAddress; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; -import java.util.Set; import java.util.Map; -import java.util.Arrays; +import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; - -import static java.util.Collections.emptyList; -import static java.util.Collections.emptyMap; -import static java.util.Collections.emptySet; -import static org.mockito.Mockito.mock; - import org.junit.After; import org.junit.Before; import org.opensearch.Version; @@ -57,6 +51,10 @@ import org.opensearch.transport.TransportService; import org.opensearch.transport.nio.MockNioTransport; import org.opensearch.usage.UsageService; +import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; +import static java.util.Collections.emptySet; +import static org.mockito.Mockito.mock; public class RestSendToExtensionActionTests extends OpenSearchTestCase { @@ -65,6 +63,7 @@ public class RestSendToExtensionActionTests extends OpenSearchTestCase { private DiscoveryExtensionNode discoveryExtensionNode; private ActionModule actionModule; private DynamicActionRegistry dynamicActionRegistry; + private IdentityService identityService; private final ThreadPool threadPool = new TestThreadPool(RestSendToExtensionActionTests.class.getSimpleName()); @Before @@ -121,6 +120,7 @@ public void setup() throws Exception { new IdentityService(Settings.EMPTY, new ArrayList<>()), new ExtensionsManager(Set.of()) ); + identityService = new IdentityService(Settings.EMPTY, new ArrayList<>()); dynamicActionRegistry = actionModule.getDynamicActionRegistry(); } @@ -142,7 +142,8 @@ public void testRestSendToExtensionAction() throws Exception { registerRestActionRequest, discoveryExtensionNode, transportService, - dynamicActionRegistry + dynamicActionRegistry, + identityService ); assertEquals("send_to_extension_action", restSendToExtensionAction.getName()); @@ -174,7 +175,8 @@ public void testRestSendToExtensionActionWithNamedRoute() throws Exception { registerRestActionRequest, discoveryExtensionNode, transportService, - dynamicActionRegistry + dynamicActionRegistry, + identityService ); assertEquals("send_to_extension_action", restSendToExtensionAction.getName()); @@ -219,7 +221,8 @@ public void testRestSendToExtensionActionWithNamedRouteAndLegacyActionName() thr registerRestActionRequest, discoveryExtensionNode, transportService, - dynamicActionRegistry + dynamicActionRegistry, + identityService ); assertEquals("send_to_extension_action", restSendToExtensionAction.getName()); @@ -271,7 +274,7 @@ public void testRestSendToExtensionActionWithoutUniqueNameShouldFail() { ); expectThrows( IllegalArgumentException.class, - () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry) + () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry, identityService) ); } @@ -283,7 +286,7 @@ public void testRestSendToExtensionMultipleNamedRoutesWithSameName() throws Exce ); expectThrows( IllegalArgumentException.class, - () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry) + () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry, identityService) ); } @@ -295,7 +298,7 @@ public void testRestSendToExtensionMultipleNamedRoutesWithSameLegacyActionName() ); expectThrows( IllegalArgumentException.class, - () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry) + () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry, identityService) ); } @@ -307,7 +310,7 @@ public void testRestSendToExtensionMultipleRoutesWithSameMethodAndPath() throws ); expectThrows( IllegalArgumentException.class, - () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry) + () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry, identityService) ); } @@ -319,7 +322,7 @@ public void testRestSendToExtensionMultipleRoutesWithSameMethodAndPathWithDiffer ); expectThrows( IllegalArgumentException.class, - () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry) + () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry, identityService) ); } @@ -331,7 +334,7 @@ public void testRestSendToExtensionMultipleRoutesWithSameMethodAndPathWithPathPa ); try { - new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry); + new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry, identityService); } catch (IllegalArgumentException e) { fail("IllegalArgumentException should not be thrown for different paths"); } @@ -353,7 +356,7 @@ public void testRestSendToExtensionWithNamedRouteCollidingWithDynamicTransportAc expectThrows( IllegalArgumentException.class, - () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry) + () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry, identityService) ); } @@ -367,7 +370,7 @@ public void testRestSendToExtensionWithNamedRouteCollidingWithNativeTransportAct ); expectThrows( IllegalArgumentException.class, - () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry) + () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry, identityService) ); } @@ -381,7 +384,8 @@ public void testRestSendToExtensionActionFilterHeaders() throws Exception { registerRestActionRequest, discoveryExtensionNode, transportService, - dynamicActionRegistry + dynamicActionRegistry, + identityService ); Map> headers = new HashMap<>(); @@ -407,7 +411,7 @@ public void testRestSendToExtensionActionBadMethod() throws Exception { ); expectThrows( IllegalArgumentException.class, - () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry) + () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry, identityService) ); } @@ -419,7 +423,7 @@ public void testRestSendToExtensionActionBadDeprecatedMethod() throws Exception ); expectThrows( IllegalArgumentException.class, - () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry) + () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry, identityService) ); } @@ -431,7 +435,7 @@ public void testRestSendToExtensionActionMissingUri() throws Exception { ); expectThrows( IllegalArgumentException.class, - () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry) + () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry, identityService) ); } @@ -443,7 +447,7 @@ public void testRestSendToExtensionActionMissingDeprecatedUri() throws Exception ); expectThrows( IllegalArgumentException.class, - () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry) + () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry, identityService) ); } } From afc6b349a411ec5dba27fa1365f527dffd00ba6c Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Thu, 13 Jul 2023 10:12:04 -0400 Subject: [PATCH 04/33] Minor changes Signed-off-by: Stephen Crawford --- .../opensearch/extensions/rest/RestSendToExtensionAction.java | 1 + 1 file changed, 1 insertion(+) diff --git a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java index af651fc82a8e6..2390db4552384 100644 --- a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java +++ b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java @@ -53,6 +53,7 @@ public class RestSendToExtensionAction extends BaseRestHandler { private static final String SEND_TO_EXTENSION_ACTION = "send_to_extension_action"; private static final Logger logger = LogManager.getLogger(RestSendToExtensionAction.class); + // To replace with user identity see https://github.com/opensearch-project/OpenSearch/pull/4247 private static final Principal DEFAULT_PRINCIPAL = new Principal() { @Override From ee602cf815d4bd81b337b4f895623f25c0eff592 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Thu, 13 Jul 2023 11:10:29 -0400 Subject: [PATCH 05/33] Swap issue token type Signed-off-by: Stephen Crawford --- .../identity/shiro/ShiroTokenManager.java | 5 +++++ .../rest/RestSendToExtensionAction.java | 15 +++------------ .../identity/noop/NoopIdentityPlugin.java | 5 +++++ .../identity/noop/NoopTokenManager.java | 6 ++++++ .../opensearch/identity/tokens/TokenManager.java | 8 ++++---- .../rest/RestSendToExtensionActionTests.java | 4 ++++ 6 files changed, 27 insertions(+), 16 deletions(-) diff --git a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java index be7c2d36e0af2..2914ab1785c23 100644 --- a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java +++ b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java @@ -69,6 +69,11 @@ public AuthToken issueToken(String audience) { return token; } + @Override + public AuthToken issueOnBehalfOfToken(List claims) { + return null; + } + @Override public Subject authenticateToken(AuthToken authToken) { Optional translatedToken = null; diff --git a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java index 2390db4552384..c8d02f3754586 100644 --- a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java +++ b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java @@ -10,7 +10,6 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; -import java.security.Principal; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -25,9 +24,10 @@ import org.apache.logging.log4j.Logger; import org.opensearch.action.ActionModule.DynamicActionRegistry; import org.opensearch.client.node.NodeClient; +import org.opensearch.common.xcontent.XContentType; import org.opensearch.core.common.bytes.BytesReference; import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.common.xcontent.XContentType; +import org.opensearch.core.rest.RestStatus; import org.opensearch.extensions.DiscoveryExtensionNode; import org.opensearch.extensions.ExtensionsManager; import org.opensearch.http.HttpRequest; @@ -37,7 +37,6 @@ import org.opensearch.rest.NamedRoute; import org.opensearch.rest.RestRequest; import org.opensearch.rest.RestRequest.Method; -import org.opensearch.core.rest.RestStatus; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.TransportException; import org.opensearch.transport.TransportResponseHandler; @@ -54,14 +53,6 @@ public class RestSendToExtensionAction extends BaseRestHandler { private static final String SEND_TO_EXTENSION_ACTION = "send_to_extension_action"; private static final Logger logger = LogManager.getLogger(RestSendToExtensionAction.class); - // To replace with user identity see https://github.com/opensearch-project/OpenSearch/pull/4247 - private static final Principal DEFAULT_PRINCIPAL = new Principal() { - @Override - public String getName() { - return "OpenSearchUser"; - } - }; - private final List routes; private final List deprecatedRoutes; private final String pathPrefix; @@ -259,7 +250,7 @@ public String executor() { filteredHeaders, contentType, content, - identityService.getTokenManager().issueToken(discoveryExtensionNode.getId()).toString(), + identityService.getTokenManager().issueOnBehalfOfToken(List.of(discoveryExtensionNode.getId(), identityService.getSubject().toString())).toString(), httpVersion ), restExecuteOnExtensionResponseHandler diff --git a/server/src/main/java/org/opensearch/identity/noop/NoopIdentityPlugin.java b/server/src/main/java/org/opensearch/identity/noop/NoopIdentityPlugin.java index 245dd5d4eb53c..6571f3091a830 100644 --- a/server/src/main/java/org/opensearch/identity/noop/NoopIdentityPlugin.java +++ b/server/src/main/java/org/opensearch/identity/noop/NoopIdentityPlugin.java @@ -44,4 +44,9 @@ public TokenManager getTokenManager() { public Subject identifyRequester(Principal principal) { return new NoopSubject(); } + + @Override + public Principal toPrincipal(String principal) { + return null; + } } diff --git a/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java b/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java index 1637c73d23bfc..08b75e17d2a2c 100644 --- a/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java +++ b/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java @@ -8,6 +8,7 @@ package org.opensearch.identity.noop; +import java.util.List; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.opensearch.identity.IdentityService; @@ -32,6 +33,11 @@ public AuthToken issueToken(String audience) { }; } + @Override + public AuthToken issueOnBehalfOfToken(List claims) { + return null; + } + @Override public Subject authenticateToken(AuthToken authToken) { return null; diff --git a/server/src/main/java/org/opensearch/identity/tokens/TokenManager.java b/server/src/main/java/org/opensearch/identity/tokens/TokenManager.java index 77144dafa0b9d..b76c8fdc615b1 100644 --- a/server/src/main/java/org/opensearch/identity/tokens/TokenManager.java +++ b/server/src/main/java/org/opensearch/identity/tokens/TokenManager.java @@ -8,6 +8,7 @@ package org.opensearch.identity.tokens; +import java.util.List; import org.opensearch.identity.Subject; /** @@ -16,13 +17,12 @@ public interface TokenManager { /** - * Create a new auth token. - * If the audience is an application ? serviceAccountToken : OnBehalfOf token + * Create a new on behalf of token * - * @param audience: The audience for the token + * @param claims: A list of claims for the token to be generated with * @return A new auth token */ - public AuthToken issueToken(String audience); + public AuthToken issueOnBehalfOfToken(List claims); /** * Authenticates a provided authToken diff --git a/server/src/test/java/org/opensearch/extensions/rest/RestSendToExtensionActionTests.java b/server/src/test/java/org/opensearch/extensions/rest/RestSendToExtensionActionTests.java index ba9a1b56c8df1..cd3c92c40d150 100644 --- a/server/src/test/java/org/opensearch/extensions/rest/RestSendToExtensionActionTests.java +++ b/server/src/test/java/org/opensearch/extensions/rest/RestSendToExtensionActionTests.java @@ -450,4 +450,8 @@ public void testRestSendToExtensionActionMissingDeprecatedUri() throws Exception () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry, identityService) ); } + + public void testRestSendToExtensionActionIncludesToken() { + + } } From 095932d44b14805f7d21a403e84606145c5e9d88 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Thu, 13 Jul 2023 13:53:36 -0400 Subject: [PATCH 06/33] Update changelog Signed-off-by: Stephen Crawford --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef26caadc48bf..a2df6e89c1448 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Add events correlation engine plugin ([#6854](https://github.com/opensearch-project/OpenSearch/issues/6854)) - Add support for ignoring missing Javadoc on generated code using annotation ([#7604](https://github.com/opensearch-project/OpenSearch/pull/7604)) - Add partial results support for concurrent segment search ([#8306](https://github.com/opensearch-project/OpenSearch/pull/8306)) +- Pass OnBehalfOfToken in RestSendToExtensionAction ([#8679](https://github.com/opensearch-project/OpenSearch/pull/8679)) ### Dependencies - Bump `log4j-core` from 2.18.0 to 2.19.0 From 676d14f1e58d49af076c7f123060500aa11206f8 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Thu, 13 Jul 2023 14:00:44 -0400 Subject: [PATCH 07/33] SPotless Signed-off-by: Stephen Crawford --- .../identity/shiro/ShiroIdentityPlugin.java | 3 +- .../identity/shiro/ShiroTokenManager.java | 1 - .../extensions/ExtensionsManager.java | 7 +- .../rest/RestSendToExtensionAction.java | 4 +- .../rest/RestSendToExtensionActionTests.java | 96 ++++++++++++++++--- 5 files changed, 95 insertions(+), 16 deletions(-) diff --git a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroIdentityPlugin.java b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroIdentityPlugin.java index 9cb84eaa60f83..e14f0507a9979 100644 --- a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroIdentityPlugin.java +++ b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroIdentityPlugin.java @@ -73,7 +73,8 @@ public Subject identifyRequester(Principal principal) { if (shiroSubject.getPrincipal().equals(principal)) { return shiroSubject; } - }; + } + ; return null; } } diff --git a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java index 2914ab1785c23..7c97ce4c7fb9f 100644 --- a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java +++ b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java @@ -88,7 +88,6 @@ public Subject authenticateToken(AuthToken authToken) { return new ShiroSubject(this, SecurityUtils.getSubject()); } - public boolean validateToken(AuthToken token) { if (token instanceof BasicAuthToken) { final BasicAuthToken basicAuthToken = (BasicAuthToken) token; diff --git a/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java b/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java index d8660243d90a6..b646703daa7b6 100644 --- a/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java +++ b/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java @@ -146,7 +146,12 @@ public void initializeServicesAndRestHandler( NodeClient client, IdentityService identityService ) { - this.restActionsRequestHandler = new RestActionsRequestHandler(actionModule.getRestController(), extensionIdMap, transportService, identityService); + this.restActionsRequestHandler = new RestActionsRequestHandler( + actionModule.getRestController(), + extensionIdMap, + transportService, + identityService + ); this.customSettingsRequestHandler = new CustomSettingsRequestHandler(settingsModule); this.transportService = transportService; this.clusterService = clusterService; diff --git a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java index c8d02f3754586..38aedc8887320 100644 --- a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java +++ b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java @@ -250,7 +250,9 @@ public String executor() { filteredHeaders, contentType, content, - identityService.getTokenManager().issueOnBehalfOfToken(List.of(discoveryExtensionNode.getId(), identityService.getSubject().toString())).toString(), + identityService.getTokenManager() + .issueOnBehalfOfToken(List.of(discoveryExtensionNode.getId(), identityService.getSubject().toString())) + .toString(), httpVersion ), restExecuteOnExtensionResponseHandler diff --git a/server/src/test/java/org/opensearch/extensions/rest/RestSendToExtensionActionTests.java b/server/src/test/java/org/opensearch/extensions/rest/RestSendToExtensionActionTests.java index cd3c92c40d150..c98a466ad6f5b 100644 --- a/server/src/test/java/org/opensearch/extensions/rest/RestSendToExtensionActionTests.java +++ b/server/src/test/java/org/opensearch/extensions/rest/RestSendToExtensionActionTests.java @@ -274,7 +274,13 @@ public void testRestSendToExtensionActionWithoutUniqueNameShouldFail() { ); expectThrows( IllegalArgumentException.class, - () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry, identityService) + () -> new RestSendToExtensionAction( + registerRestActionRequest, + discoveryExtensionNode, + transportService, + dynamicActionRegistry, + identityService + ) ); } @@ -286,7 +292,13 @@ public void testRestSendToExtensionMultipleNamedRoutesWithSameName() throws Exce ); expectThrows( IllegalArgumentException.class, - () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry, identityService) + () -> new RestSendToExtensionAction( + registerRestActionRequest, + discoveryExtensionNode, + transportService, + dynamicActionRegistry, + identityService + ) ); } @@ -298,7 +310,13 @@ public void testRestSendToExtensionMultipleNamedRoutesWithSameLegacyActionName() ); expectThrows( IllegalArgumentException.class, - () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry, identityService) + () -> new RestSendToExtensionAction( + registerRestActionRequest, + discoveryExtensionNode, + transportService, + dynamicActionRegistry, + identityService + ) ); } @@ -310,7 +328,13 @@ public void testRestSendToExtensionMultipleRoutesWithSameMethodAndPath() throws ); expectThrows( IllegalArgumentException.class, - () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry, identityService) + () -> new RestSendToExtensionAction( + registerRestActionRequest, + discoveryExtensionNode, + transportService, + dynamicActionRegistry, + identityService + ) ); } @@ -322,7 +346,13 @@ public void testRestSendToExtensionMultipleRoutesWithSameMethodAndPathWithDiffer ); expectThrows( IllegalArgumentException.class, - () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry, identityService) + () -> new RestSendToExtensionAction( + registerRestActionRequest, + discoveryExtensionNode, + transportService, + dynamicActionRegistry, + identityService + ) ); } @@ -334,7 +364,13 @@ public void testRestSendToExtensionMultipleRoutesWithSameMethodAndPathWithPathPa ); try { - new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry, identityService); + new RestSendToExtensionAction( + registerRestActionRequest, + discoveryExtensionNode, + transportService, + dynamicActionRegistry, + identityService + ); } catch (IllegalArgumentException e) { fail("IllegalArgumentException should not be thrown for different paths"); } @@ -356,7 +392,13 @@ public void testRestSendToExtensionWithNamedRouteCollidingWithDynamicTransportAc expectThrows( IllegalArgumentException.class, - () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry, identityService) + () -> new RestSendToExtensionAction( + registerRestActionRequest, + discoveryExtensionNode, + transportService, + dynamicActionRegistry, + identityService + ) ); } @@ -370,7 +412,13 @@ public void testRestSendToExtensionWithNamedRouteCollidingWithNativeTransportAct ); expectThrows( IllegalArgumentException.class, - () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry, identityService) + () -> new RestSendToExtensionAction( + registerRestActionRequest, + discoveryExtensionNode, + transportService, + dynamicActionRegistry, + identityService + ) ); } @@ -411,7 +459,13 @@ public void testRestSendToExtensionActionBadMethod() throws Exception { ); expectThrows( IllegalArgumentException.class, - () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry, identityService) + () -> new RestSendToExtensionAction( + registerRestActionRequest, + discoveryExtensionNode, + transportService, + dynamicActionRegistry, + identityService + ) ); } @@ -423,7 +477,13 @@ public void testRestSendToExtensionActionBadDeprecatedMethod() throws Exception ); expectThrows( IllegalArgumentException.class, - () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry, identityService) + () -> new RestSendToExtensionAction( + registerRestActionRequest, + discoveryExtensionNode, + transportService, + dynamicActionRegistry, + identityService + ) ); } @@ -435,7 +495,13 @@ public void testRestSendToExtensionActionMissingUri() throws Exception { ); expectThrows( IllegalArgumentException.class, - () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry, identityService) + () -> new RestSendToExtensionAction( + registerRestActionRequest, + discoveryExtensionNode, + transportService, + dynamicActionRegistry, + identityService + ) ); } @@ -447,7 +513,13 @@ public void testRestSendToExtensionActionMissingDeprecatedUri() throws Exception ); expectThrows( IllegalArgumentException.class, - () -> new RestSendToExtensionAction(registerRestActionRequest, discoveryExtensionNode, transportService, dynamicActionRegistry, identityService) + () -> new RestSendToExtensionAction( + registerRestActionRequest, + discoveryExtensionNode, + transportService, + dynamicActionRegistry, + identityService + ) ); } From 3db805c032d3b96956f71a3f99e24e8d3b944766 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Thu, 13 Jul 2023 16:01:15 -0400 Subject: [PATCH 08/33] Add test Signed-off-by: Stephen Crawford --- .../identity/shiro/ShiroIdentityPlugin.java | 12 ------------ .../identity/shiro/ShiroTokenManager.java | 9 ++------- .../identity/shiro/AuthTokenHandlerTests.java | 17 ++++++++++++++--- .../identity/noop/NoopIdentityPlugin.java | 13 +------------ .../identity/noop/NoopTokenManager.java | 7 +------ .../org/opensearch/plugins/IdentityPlugin.java | 11 ----------- .../extensions/ExtensionsManagerTests.java | 2 +- 7 files changed, 19 insertions(+), 52 deletions(-) diff --git a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroIdentityPlugin.java b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroIdentityPlugin.java index e14f0507a9979..1cb3483be6e78 100644 --- a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroIdentityPlugin.java +++ b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroIdentityPlugin.java @@ -8,7 +8,6 @@ package org.opensearch.identity.shiro; -import java.security.Principal; import java.util.List; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -66,15 +65,4 @@ public Subject getSubject() { public TokenManager getTokenManager() { return this.authTokenHandler; } - - @Override - public Subject identifyRequester(Principal principal) { - for (ShiroSubject shiroSubject : shiroSubjectList) { - if (shiroSubject.getPrincipal().equals(principal)) { - return shiroSubject; - } - } - ; - return null; - } } diff --git a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java index 7c97ce4c7fb9f..c2a2773ad8df2 100644 --- a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java +++ b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java @@ -57,10 +57,10 @@ public Optional translateAuthToken(org.opensearch.identity. } @Override - public AuthToken issueToken(String audience) { + public AuthToken issueOnBehalfOfToken(List claims) { String password = generatePassword(); - final byte[] rawEncoded = Base64.getEncoder().encode((audience + ":" + password).getBytes(UTF_8)); + final byte[] rawEncoded = Base64.getEncoder().encode((claims.get(0) + ":" + password).getBytes(UTF_8)); final String usernamePassword = new String(rawEncoded, UTF_8); final String header = "Basic " + usernamePassword; BasicAuthToken token = new BasicAuthToken(header); @@ -69,11 +69,6 @@ public AuthToken issueToken(String audience) { return token; } - @Override - public AuthToken issueOnBehalfOfToken(List claims) { - return null; - } - @Override public Subject authenticateToken(AuthToken authToken) { Optional translatedToken = null; diff --git a/plugins/identity-shiro/src/test/java/org/opensearch/identity/shiro/AuthTokenHandlerTests.java b/plugins/identity-shiro/src/test/java/org/opensearch/identity/shiro/AuthTokenHandlerTests.java index 540fed368aeda..34d6ffd84819b 100644 --- a/plugins/identity-shiro/src/test/java/org/opensearch/identity/shiro/AuthTokenHandlerTests.java +++ b/plugins/identity-shiro/src/test/java/org/opensearch/identity/shiro/AuthTokenHandlerTests.java @@ -8,11 +8,12 @@ package org.opensearch.identity.shiro; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.UsernamePasswordToken; import org.junit.Before; -import org.opensearch.identity.noop.NoopTokenManager; import org.opensearch.identity.tokens.AuthToken; import org.opensearch.identity.tokens.BasicAuthToken; import org.opensearch.identity.tokens.BearerAuthToken; @@ -31,12 +32,10 @@ public class AuthTokenHandlerTests extends OpenSearchTestCase { private ShiroTokenManager shiroAuthTokenHandler; - private NoopTokenManager noopTokenManager; @Before public void testSetup() { shiroAuthTokenHandler = new ShiroTokenManager(); - noopTokenManager = new NoopTokenManager(); } public void testShouldExtractBasicAuthTokenSuccessfully() { @@ -144,4 +143,16 @@ public void testGeneratedPasswordContents() { validator.validate(data); } + public void testIssueOnBehalfOfTokenFromClaims() { + List claims = new ArrayList<>(); + claims.add("audience"); + claims.add("roles"); + BasicAuthToken authToken = (BasicAuthToken) shiroAuthTokenHandler.issueOnBehalfOfToken(claims); + assertTrue(authToken instanceof BasicAuthToken); + UsernamePasswordToken translatedToken = (UsernamePasswordToken) shiroAuthTokenHandler.translateAuthToken(authToken).get(); + assertEquals(authToken.getPassword(), new String(translatedToken.getPassword())); + assertTrue(shiroAuthTokenHandler.getShiroTokenPasswordMap().containsKey(authToken)); + assertEquals(shiroAuthTokenHandler.getShiroTokenPasswordMap().get(authToken), new String(translatedToken.getPassword())); + } + } diff --git a/server/src/main/java/org/opensearch/identity/noop/NoopIdentityPlugin.java b/server/src/main/java/org/opensearch/identity/noop/NoopIdentityPlugin.java index 6571f3091a830..c2367383df595 100644 --- a/server/src/main/java/org/opensearch/identity/noop/NoopIdentityPlugin.java +++ b/server/src/main/java/org/opensearch/identity/noop/NoopIdentityPlugin.java @@ -8,10 +8,9 @@ package org.opensearch.identity.noop; -import java.security.Principal; +import org.opensearch.identity.Subject; import org.opensearch.identity.tokens.TokenManager; import org.opensearch.plugins.IdentityPlugin; -import org.opensearch.identity.Subject; /** * Implementation of identity plugin that does not enforce authentication or authorization @@ -39,14 +38,4 @@ public Subject getSubject() { public TokenManager getTokenManager() { return new NoopTokenManager(); } - - @Override - public Subject identifyRequester(Principal principal) { - return new NoopSubject(); - } - - @Override - public Principal toPrincipal(String principal) { - return null; - } } diff --git a/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java b/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java index 08b75e17d2a2c..c33828c983987 100644 --- a/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java +++ b/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java @@ -28,16 +28,11 @@ public class NoopTokenManager implements TokenManager { * @return a new Noop Token */ @Override - public AuthToken issueToken(String audience) { + public AuthToken issueOnBehalfOfToken(List claims) { return new AuthToken() { }; } - @Override - public AuthToken issueOnBehalfOfToken(List claims) { - return null; - } - @Override public Subject authenticateToken(AuthToken authToken) { return null; diff --git a/server/src/main/java/org/opensearch/plugins/IdentityPlugin.java b/server/src/main/java/org/opensearch/plugins/IdentityPlugin.java index 492e595fc9f90..00f3f8aff585c 100644 --- a/server/src/main/java/org/opensearch/plugins/IdentityPlugin.java +++ b/server/src/main/java/org/opensearch/plugins/IdentityPlugin.java @@ -8,7 +8,6 @@ package org.opensearch.plugins; -import java.security.Principal; import org.opensearch.identity.Subject; import org.opensearch.identity.tokens.TokenManager; @@ -32,14 +31,4 @@ public interface IdentityPlugin { * Should never return null */ public TokenManager getTokenManager(); - - /** - * Identifies the Subject associated with a request - */ - public Subject identifyRequester(final Principal principal); - - /** - * Creates a standardized principal concept for an Identity Plugin - */ - public Principal toPrincipal(String principal); } diff --git a/server/src/test/java/org/opensearch/extensions/ExtensionsManagerTests.java b/server/src/test/java/org/opensearch/extensions/ExtensionsManagerTests.java index c9c5603ff167c..96085cdf6402d 100644 --- a/server/src/test/java/org/opensearch/extensions/ExtensionsManagerTests.java +++ b/server/src/test/java/org/opensearch/extensions/ExtensionsManagerTests.java @@ -93,7 +93,7 @@ public class ExtensionsManagerTests extends OpenSearchTestCase { private MockNioTransport transport; private IdentityService identityService; private Path extensionDir; - + private final ThreadPool threadPool = new TestThreadPool(ExtensionsManagerTests.class.getSimpleName()); private final Settings settings = Settings.builder() .put(IndexMetadata.SETTING_VERSION_CREATED, Version.CURRENT) From 4d6e2fd2e3d5fa1dcb01019756f0ca5a99c3d55c Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Thu, 13 Jul 2023 16:06:45 -0400 Subject: [PATCH 09/33] Swap out authentication Signed-off-by: Stephen Crawford --- .../identity/shiro/ShiroTokenManager.java | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java index c2a2773ad8df2..76ef130806c5f 100644 --- a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java +++ b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java @@ -20,10 +20,10 @@ import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.UsernamePasswordToken; -import org.apache.shiro.authz.UnauthenticatedException; import org.opensearch.common.Randomness; import org.opensearch.identity.IdentityService; import org.opensearch.identity.Subject; +import org.opensearch.identity.noop.NoopSubject; import org.opensearch.identity.tokens.AuthToken; import org.opensearch.identity.tokens.BasicAuthToken; import org.opensearch.identity.tokens.TokenManager; @@ -71,16 +71,7 @@ public AuthToken issueOnBehalfOfToken(List claims) { @Override public Subject authenticateToken(AuthToken authToken) { - Optional translatedToken = null; - if (authToken instanceof BasicAuthToken) { - if (shiroTokenPasswordMap.containsKey(authToken)) { - translatedToken = translateAuthToken(authToken); - } else { - throw new UnauthenticatedException("Invalid token"); - } - } - SecurityUtils.getSubject().login(translatedToken.get()); - return new ShiroSubject(this, SecurityUtils.getSubject()); + return new NoopSubject(); } public boolean validateToken(AuthToken token) { From b15df51666c8da673a34ff73b5f6fd75cbb5d1bb Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Thu, 13 Jul 2023 16:56:52 -0400 Subject: [PATCH 10/33] Swap to string, obj map Signed-off-by: Stephen Crawford --- .../opensearch/identity/shiro/ShiroTokenManager.java | 4 ++-- .../identity/shiro/AuthTokenHandlerTests.java | 10 ++++------ .../extensions/rest/RestSendToExtensionAction.java | 2 +- .../org/opensearch/identity/noop/NoopTokenManager.java | 4 ++-- .../org/opensearch/identity/tokens/TokenManager.java | 4 ++-- 5 files changed, 11 insertions(+), 13 deletions(-) diff --git a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java index 76ef130806c5f..94ee5a5499cb7 100644 --- a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java +++ b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java @@ -57,10 +57,10 @@ public Optional translateAuthToken(org.opensearch.identity. } @Override - public AuthToken issueOnBehalfOfToken(List claims) { + public AuthToken issueOnBehalfOfToken(Map claims) { String password = generatePassword(); - final byte[] rawEncoded = Base64.getEncoder().encode((claims.get(0) + ":" + password).getBytes(UTF_8)); + final byte[] rawEncoded = Base64.getEncoder().encode((claims.get("aud") + ":" + password).getBytes(UTF_8)); final String usernamePassword = new String(rawEncoded, UTF_8); final String header = "Basic " + usernamePassword; BasicAuthToken token = new BasicAuthToken(header); diff --git a/plugins/identity-shiro/src/test/java/org/opensearch/identity/shiro/AuthTokenHandlerTests.java b/plugins/identity-shiro/src/test/java/org/opensearch/identity/shiro/AuthTokenHandlerTests.java index 34d6ffd84819b..98d0ae4b9e2b6 100644 --- a/plugins/identity-shiro/src/test/java/org/opensearch/identity/shiro/AuthTokenHandlerTests.java +++ b/plugins/identity-shiro/src/test/java/org/opensearch/identity/shiro/AuthTokenHandlerTests.java @@ -8,8 +8,8 @@ package org.opensearch.identity.shiro; -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; +import java.util.Map; import java.util.Optional; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.UsernamePasswordToken; @@ -144,9 +144,8 @@ public void testGeneratedPasswordContents() { } public void testIssueOnBehalfOfTokenFromClaims() { - List claims = new ArrayList<>(); - claims.add("audience"); - claims.add("roles"); + Map claims = new HashMap<>(); + claims.put("aud", "test"); BasicAuthToken authToken = (BasicAuthToken) shiroAuthTokenHandler.issueOnBehalfOfToken(claims); assertTrue(authToken instanceof BasicAuthToken); UsernamePasswordToken translatedToken = (UsernamePasswordToken) shiroAuthTokenHandler.translateAuthToken(authToken).get(); @@ -154,5 +153,4 @@ public void testIssueOnBehalfOfTokenFromClaims() { assertTrue(shiroAuthTokenHandler.getShiroTokenPasswordMap().containsKey(authToken)); assertEquals(shiroAuthTokenHandler.getShiroTokenPasswordMap().get(authToken), new String(translatedToken.getPassword())); } - } diff --git a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java index 38aedc8887320..6146c44a515a1 100644 --- a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java +++ b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java @@ -251,7 +251,7 @@ public String executor() { contentType, content, identityService.getTokenManager() - .issueOnBehalfOfToken(List.of(discoveryExtensionNode.getId(), identityService.getSubject().toString())) + .issueOnBehalfOfToken(Map.of("aud", discoveryExtensionNode.getId())) .toString(), httpVersion ), diff --git a/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java b/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java index c33828c983987..d4b7a0ac2cb28 100644 --- a/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java +++ b/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java @@ -8,7 +8,7 @@ package org.opensearch.identity.noop; -import java.util.List; +import java.util.Map; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.opensearch.identity.IdentityService; @@ -28,7 +28,7 @@ public class NoopTokenManager implements TokenManager { * @return a new Noop Token */ @Override - public AuthToken issueOnBehalfOfToken(List claims) { + public AuthToken issueOnBehalfOfToken(Map claims) { return new AuthToken() { }; } diff --git a/server/src/main/java/org/opensearch/identity/tokens/TokenManager.java b/server/src/main/java/org/opensearch/identity/tokens/TokenManager.java index b76c8fdc615b1..791f37bae410b 100644 --- a/server/src/main/java/org/opensearch/identity/tokens/TokenManager.java +++ b/server/src/main/java/org/opensearch/identity/tokens/TokenManager.java @@ -8,7 +8,7 @@ package org.opensearch.identity.tokens; -import java.util.List; +import java.util.Map; import org.opensearch.identity.Subject; /** @@ -22,7 +22,7 @@ public interface TokenManager { * @param claims: A list of claims for the token to be generated with * @return A new auth token */ - public AuthToken issueOnBehalfOfToken(List claims); + public AuthToken issueOnBehalfOfToken(Map claims); /** * Authenticates a provided authToken From d937ca96d0db1da865fdb65569a656f1ce1f74d6 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Fri, 14 Jul 2023 12:31:17 -0400 Subject: [PATCH 11/33] Update with Craig's feedback Signed-off-by: Stephen Crawford --- .../identity/shiro/ShiroTokenManager.java | 2 +- .../rest/RestSendToExtensionAction.java | 3 +- .../identity/tokens/StandardTokenClaims.java | 39 +++++++++++++++++++ .../rest/RestSendToExtensionActionTests.java | 4 -- 4 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 server/src/main/java/org/opensearch/identity/tokens/StandardTokenClaims.java diff --git a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java index 94ee5a5499cb7..0c33bb3e44735 100644 --- a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java +++ b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java @@ -60,7 +60,7 @@ public Optional translateAuthToken(org.opensearch.identity. public AuthToken issueOnBehalfOfToken(Map claims) { String password = generatePassword(); - final byte[] rawEncoded = Base64.getEncoder().encode((claims.get("aud") + ":" + password).getBytes(UTF_8)); + final byte[] rawEncoded = Base64.getEncoder().encode((claims.get("aud") + ":" + password).getBytes(UTF_8)); // Make a new ShiroSubject w/ audience as name final String usernamePassword = new String(rawEncoded, UTF_8); final String header = "Basic " + usernamePassword; BasicAuthToken token = new BasicAuthToken(header); diff --git a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java index 6146c44a515a1..c9d6bf4671eda 100644 --- a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java +++ b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java @@ -32,6 +32,7 @@ import org.opensearch.extensions.ExtensionsManager; import org.opensearch.http.HttpRequest; import org.opensearch.identity.IdentityService; +import org.opensearch.identity.tokens.StandardTokenClaims; import org.opensearch.rest.BaseRestHandler; import org.opensearch.rest.BytesRestResponse; import org.opensearch.rest.NamedRoute; @@ -251,7 +252,7 @@ public String executor() { contentType, content, identityService.getTokenManager() - .issueOnBehalfOfToken(Map.of("aud", discoveryExtensionNode.getId())) + .issueOnBehalfOfToken(Map.of(StandardTokenClaims.AUDIENCE.getName(), discoveryExtensionNode.getId())) // This gets an extensions uniqueId .toString(), httpVersion ), diff --git a/server/src/main/java/org/opensearch/identity/tokens/StandardTokenClaims.java b/server/src/main/java/org/opensearch/identity/tokens/StandardTokenClaims.java new file mode 100644 index 0000000000000..992e2e2e54450 --- /dev/null +++ b/server/src/main/java/org/opensearch/identity/tokens/StandardTokenClaims.java @@ -0,0 +1,39 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.identity.tokens; + +public enum StandardTokenClaims { + + ISSUER("iss"), + SUBJECT("sub"), + AUDIENCE("aud"), + EXPIRATION_TIME("exp"), + NOT_BEFORE("nbf"), + ISSUED_AT("iat"), + JWT_ID("jti"); + + private final String name; + + StandardTokenClaims(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return name; + } + + public static StandardTokenClaims fromString(String name) { + return StandardTokenClaims.valueOf(name); + } +} diff --git a/server/src/test/java/org/opensearch/extensions/rest/RestSendToExtensionActionTests.java b/server/src/test/java/org/opensearch/extensions/rest/RestSendToExtensionActionTests.java index c98a466ad6f5b..74f708f22d75f 100644 --- a/server/src/test/java/org/opensearch/extensions/rest/RestSendToExtensionActionTests.java +++ b/server/src/test/java/org/opensearch/extensions/rest/RestSendToExtensionActionTests.java @@ -522,8 +522,4 @@ public void testRestSendToExtensionActionMissingDeprecatedUri() throws Exception ) ); } - - public void testRestSendToExtensionActionIncludesToken() { - - } } From af9d2d78e543c49a22d4372dfa27c91807a860fb Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Fri, 14 Jul 2023 13:16:48 -0400 Subject: [PATCH 12/33] Add javadoc Signed-off-by: Stephen Crawford --- .../org/opensearch/identity/tokens/StandardTokenClaims.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/src/main/java/org/opensearch/identity/tokens/StandardTokenClaims.java b/server/src/main/java/org/opensearch/identity/tokens/StandardTokenClaims.java index 992e2e2e54450..09f60521d0e30 100644 --- a/server/src/main/java/org/opensearch/identity/tokens/StandardTokenClaims.java +++ b/server/src/main/java/org/opensearch/identity/tokens/StandardTokenClaims.java @@ -8,6 +8,9 @@ package org.opensearch.identity.tokens; +/** + * This enum represents the standard claims that are used in the JWTs for OnBehalfOf tokens + */ public enum StandardTokenClaims { ISSUER("iss"), From f6209d41427bbf75dd67ad365cfffff067cc0ea6 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Fri, 14 Jul 2023 13:18:06 -0400 Subject: [PATCH 13/33] add annotation Signed-off-by: Stephen Crawford --- .../org/opensearch/identity/shiro/ShiroTokenManager.java | 4 +++- .../extensions/rest/RestSendToExtensionAction.java | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java index 0c33bb3e44735..f319d05a0876f 100644 --- a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java +++ b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java @@ -60,7 +60,9 @@ public Optional translateAuthToken(org.opensearch.identity. public AuthToken issueOnBehalfOfToken(Map claims) { String password = generatePassword(); - final byte[] rawEncoded = Base64.getEncoder().encode((claims.get("aud") + ":" + password).getBytes(UTF_8)); // Make a new ShiroSubject w/ audience as name + final byte[] rawEncoded = Base64.getEncoder().encode((claims.get("aud") + ":" + password).getBytes(UTF_8)); // Make a new + // ShiroSubject w/ + // audience as name final String usernamePassword = new String(rawEncoded, UTF_8); final String header = "Basic " + usernamePassword; BasicAuthToken token = new BasicAuthToken(header); diff --git a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java index c9d6bf4671eda..35ca3f7c5c68f 100644 --- a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java +++ b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java @@ -252,7 +252,10 @@ public String executor() { contentType, content, identityService.getTokenManager() - .issueOnBehalfOfToken(Map.of(StandardTokenClaims.AUDIENCE.getName(), discoveryExtensionNode.getId())) // This gets an extensions uniqueId + .issueOnBehalfOfToken(Map.of(StandardTokenClaims.AUDIENCE.getName(), discoveryExtensionNode.getId())) // This gets + // an + // extensions + // uniqueId .toString(), httpVersion ), From acd33303925cce19682f5ba670ce88350fbbcdd5 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Fri, 14 Jul 2023 13:49:24 -0400 Subject: [PATCH 14/33] Fix missing path import Signed-off-by: Stephen Crawford --- .../extensions/ExtensionsManagerTests.java | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/server/src/test/java/org/opensearch/extensions/ExtensionsManagerTests.java b/server/src/test/java/org/opensearch/extensions/ExtensionsManagerTests.java index 96085cdf6402d..fb2dde747251e 100644 --- a/server/src/test/java/org/opensearch/extensions/ExtensionsManagerTests.java +++ b/server/src/test/java/org/opensearch/extensions/ExtensionsManagerTests.java @@ -10,8 +10,12 @@ import java.io.IOException; import java.net.InetAddress; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; +import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; +import static java.util.Collections.emptySet; import java.util.HashMap; import java.util.List; import java.util.Set; @@ -21,6 +25,14 @@ import org.apache.logging.log4j.LogManager; import org.junit.After; import org.junit.Before; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import org.opensearch.OpenSearchException; import org.opensearch.Version; import org.opensearch.action.ActionModule; @@ -55,6 +67,7 @@ import org.opensearch.indices.breaker.NoneCircuitBreakerService; import org.opensearch.plugins.ExtensionAwarePlugin; import org.opensearch.rest.RestController; +import static org.opensearch.test.ClusterServiceUtils.createClusterService; import org.opensearch.test.FeatureFlagSetter; import org.opensearch.test.MockLogAppender; import org.opensearch.test.OpenSearchTestCase; @@ -67,18 +80,6 @@ import org.opensearch.transport.TransportService; import org.opensearch.transport.nio.MockNioTransport; import org.opensearch.usage.UsageService; -import static java.util.Collections.emptyList; -import static java.util.Collections.emptyMap; -import static java.util.Collections.emptySet; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.opensearch.test.ClusterServiceUtils.createClusterService; public class ExtensionsManagerTests extends OpenSearchTestCase { private TransportService transportService; From ed2d09c43e6f2a06cf80097bb81df616e9feeadb Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Fri, 14 Jul 2023 15:35:41 -0400 Subject: [PATCH 15/33] Fix test Signed-off-by: Stephen Crawford --- .../org/opensearch/identity/shiro/ShiroIdentityPlugin.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroIdentityPlugin.java b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroIdentityPlugin.java index 1cb3483be6e78..77cab13880c27 100644 --- a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroIdentityPlugin.java +++ b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroIdentityPlugin.java @@ -8,7 +8,6 @@ package org.opensearch.identity.shiro; -import java.util.List; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.shiro.SecurityUtils; @@ -29,7 +28,6 @@ public final class ShiroIdentityPlugin extends Plugin implements IdentityPlugin private final Settings settings; private final ShiroTokenManager authTokenHandler; - private List shiroSubjectList = List.of(); /** * Create a new instance of the Shiro Identity Plugin @@ -51,9 +49,7 @@ public ShiroIdentityPlugin(final Settings settings) { */ @Override public Subject getSubject() { - ShiroSubject newShiroSubject = new ShiroSubject(authTokenHandler, SecurityUtils.getSubject()); - shiroSubjectList.add(newShiroSubject); - return newShiroSubject; + return new ShiroSubject(authTokenHandler, SecurityUtils.getSubject()); } /** From 4fdfaf7269f50ee656065ebfb5f55782ce95ad7d Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Fri, 14 Jul 2023 16:55:20 -0400 Subject: [PATCH 16/33] boost coverage Signed-off-by: Stephen Crawford --- .../identity/shiro/AuthTokenHandlerTests.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/plugins/identity-shiro/src/test/java/org/opensearch/identity/shiro/AuthTokenHandlerTests.java b/plugins/identity-shiro/src/test/java/org/opensearch/identity/shiro/AuthTokenHandlerTests.java index 98d0ae4b9e2b6..e90457df41ce6 100644 --- a/plugins/identity-shiro/src/test/java/org/opensearch/identity/shiro/AuthTokenHandlerTests.java +++ b/plugins/identity-shiro/src/test/java/org/opensearch/identity/shiro/AuthTokenHandlerTests.java @@ -14,9 +14,11 @@ import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.UsernamePasswordToken; import org.junit.Before; +import org.opensearch.identity.noop.NoopTokenManager; import org.opensearch.identity.tokens.AuthToken; import org.opensearch.identity.tokens.BasicAuthToken; import org.opensearch.identity.tokens.BearerAuthToken; +import org.opensearch.identity.tokens.StandardTokenClaims; import org.opensearch.test.OpenSearchTestCase; import org.passay.CharacterCharacteristicsRule; import org.passay.CharacterRule; @@ -153,4 +155,20 @@ public void testIssueOnBehalfOfTokenFromClaims() { assertTrue(shiroAuthTokenHandler.getShiroTokenPasswordMap().containsKey(authToken)); assertEquals(shiroAuthTokenHandler.getShiroTokenPasswordMap().get(authToken), new String(translatedToken.getPassword())); } + + public void testTokenNoopIssuance() { + NoopTokenManager tokenManager = new NoopTokenManager(); + AuthToken token = tokenManager.issueOnBehalfOfToken(Map.of("test", "test")); + assertTrue(token instanceof AuthToken); + } + + public void testStandardTokenClaims() { + assertEquals(StandardTokenClaims.AUDIENCE.getName(), "aud"); + assertEquals(StandardTokenClaims.ISSUED_AT.getName(), "iat"); + assertEquals(StandardTokenClaims.ISSUER.getName(), "iss"); + assertEquals(StandardTokenClaims.EXPIRATION_TIME.getName(), "exp"); + assertEquals(StandardTokenClaims.JWT_ID.getName(), "jti"); + assertEquals(StandardTokenClaims.NOT_BEFORE.getName(), "nbf"); + assertEquals(StandardTokenClaims.SUBJECT.getName(), "sub"); + } } From a74620205d5817d8be973f1c071bf999489a35ef Mon Sep 17 00:00:00 2001 From: Ryan Liang Date: Tue, 18 Jul 2023 16:01:00 -0700 Subject: [PATCH 17/33] Add interface for AuthToken Signed-off-by: Ryan Liang --- .../extensions/rest/RestSendToExtensionAction.java | 2 +- .../java/org/opensearch/identity/tokens/AuthToken.java | 2 +- .../org/opensearch/identity/tokens/BasicAuthToken.java | 9 +++++++++ .../org/opensearch/identity/tokens/BearerAuthToken.java | 5 +++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java index 35ca3f7c5c68f..bc3ce5acd78e2 100644 --- a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java +++ b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java @@ -256,7 +256,7 @@ public String executor() { // an // extensions // uniqueId - .toString(), + .getTokenValue(), httpVersion ), restExecuteOnExtensionResponseHandler diff --git a/server/src/main/java/org/opensearch/identity/tokens/AuthToken.java b/server/src/main/java/org/opensearch/identity/tokens/AuthToken.java index 6e113f6eaa96a..2f4e191237302 100644 --- a/server/src/main/java/org/opensearch/identity/tokens/AuthToken.java +++ b/server/src/main/java/org/opensearch/identity/tokens/AuthToken.java @@ -14,5 +14,5 @@ * @opensearch.experimental */ public interface AuthToken { - + String getTokenValue(); } diff --git a/server/src/main/java/org/opensearch/identity/tokens/BasicAuthToken.java b/server/src/main/java/org/opensearch/identity/tokens/BasicAuthToken.java index 9cd6cb6b6208a..da3a29944e784 100644 --- a/server/src/main/java/org/opensearch/identity/tokens/BasicAuthToken.java +++ b/server/src/main/java/org/opensearch/identity/tokens/BasicAuthToken.java @@ -51,4 +51,13 @@ public void revoke() { this.password = ""; this.user = ""; } + + @Override + public String getTokenValue() { + if (user == null || password == null) { + return null; + } + String usernamepassword = user + ":" + password; + return Base64.getEncoder().encodeToString(usernamepassword.getBytes(StandardCharsets.UTF_8)); + } } diff --git a/server/src/main/java/org/opensearch/identity/tokens/BearerAuthToken.java b/server/src/main/java/org/opensearch/identity/tokens/BearerAuthToken.java index eac164af1c5d3..32ec32673851a 100644 --- a/server/src/main/java/org/opensearch/identity/tokens/BearerAuthToken.java +++ b/server/src/main/java/org/opensearch/identity/tokens/BearerAuthToken.java @@ -58,4 +58,9 @@ public String getTokenIdentifier() { public String toString() { return "Bearer auth token with header=" + header + ", payload=" + payload + ", signature=" + signature; } + + @Override + public String getTokenValue() { + return completeToken; + } } From acf6c76bc3b4052957866d6e43f8662c5f4d4b0d Mon Sep 17 00:00:00 2001 From: Stephen Crawford <65832608+scrawfor99@users.noreply.github.com> Date: Thu, 20 Jul 2023 12:12:06 -0400 Subject: [PATCH 18/33] Update server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java Co-authored-by: Peter Nied Signed-off-by: Stephen Crawford <65832608+scrawfor99@users.noreply.github.com> --- .../java/org/opensearch/identity/noop/NoopTokenManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java b/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java index d4b7a0ac2cb28..e64522979b024 100644 --- a/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java +++ b/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java @@ -28,7 +28,7 @@ public class NoopTokenManager implements TokenManager { * @return a new Noop Token */ @Override - public AuthToken issueOnBehalfOfToken(Map claims) { + public AuthToken issueOnBehalfOfToken(final Subject subject, final OnBehalfOfClaims claims) { return new AuthToken() { }; } From 1070564a5d7b31efeef917228099dd48a6857fc8 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Mon, 24 Jul 2023 14:45:50 -0400 Subject: [PATCH 19/33] Resolve comments Signed-off-by: Stephen Crawford --- .../identity/shiro/ShiroTokenManager.java | 9 +-- .../identity/shiro/AuthTokenHandlerTests.java | 25 +++----- .../rest/RestSendToExtensionAction.java | 17 +++--- .../identity/noop/NoopTokenManager.java | 6 +- .../opensearch/identity/tokens/AuthToken.java | 2 +- .../identity/tokens/OnBehalfOfClaims.java | 58 +++++++++++++++++++ .../identity/tokens/StandardTokenClaims.java | 42 -------------- .../identity/tokens/TokenManager.java | 3 +- .../main/java/org/opensearch/node/Node.java | 5 +- 9 files changed, 91 insertions(+), 76 deletions(-) create mode 100644 server/src/main/java/org/opensearch/identity/tokens/OnBehalfOfClaims.java delete mode 100644 server/src/main/java/org/opensearch/identity/tokens/StandardTokenClaims.java diff --git a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java index f319d05a0876f..429acfcd55128 100644 --- a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java +++ b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroTokenManager.java @@ -26,6 +26,7 @@ import org.opensearch.identity.noop.NoopSubject; import org.opensearch.identity.tokens.AuthToken; import org.opensearch.identity.tokens.BasicAuthToken; +import org.opensearch.identity.tokens.OnBehalfOfClaims; import org.opensearch.identity.tokens.TokenManager; import org.passay.CharacterRule; import org.passay.EnglishCharacterData; @@ -57,12 +58,12 @@ public Optional translateAuthToken(org.opensearch.identity. } @Override - public AuthToken issueOnBehalfOfToken(Map claims) { + public AuthToken issueOnBehalfOfToken(Subject subject, OnBehalfOfClaims claims) { String password = generatePassword(); - final byte[] rawEncoded = Base64.getEncoder().encode((claims.get("aud") + ":" + password).getBytes(UTF_8)); // Make a new - // ShiroSubject w/ - // audience as name + final byte[] rawEncoded = Base64.getEncoder().encode((claims.getAudience() + ":" + password).getBytes(UTF_8)); // Make a new + // ShiroSubject w/ + // audience as name final String usernamePassword = new String(rawEncoded, UTF_8); final String header = "Basic " + usernamePassword; BasicAuthToken token = new BasicAuthToken(header); diff --git a/plugins/identity-shiro/src/test/java/org/opensearch/identity/shiro/AuthTokenHandlerTests.java b/plugins/identity-shiro/src/test/java/org/opensearch/identity/shiro/AuthTokenHandlerTests.java index e90457df41ce6..f7ae9bd1ad8e6 100644 --- a/plugins/identity-shiro/src/test/java/org/opensearch/identity/shiro/AuthTokenHandlerTests.java +++ b/plugins/identity-shiro/src/test/java/org/opensearch/identity/shiro/AuthTokenHandlerTests.java @@ -8,17 +8,17 @@ package org.opensearch.identity.shiro; -import java.util.HashMap; -import java.util.Map; import java.util.Optional; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.UsernamePasswordToken; import org.junit.Before; +import org.opensearch.identity.Subject; +import org.opensearch.identity.noop.NoopSubject; import org.opensearch.identity.noop.NoopTokenManager; import org.opensearch.identity.tokens.AuthToken; import org.opensearch.identity.tokens.BasicAuthToken; import org.opensearch.identity.tokens.BearerAuthToken; -import org.opensearch.identity.tokens.StandardTokenClaims; +import org.opensearch.identity.tokens.OnBehalfOfClaims; import org.opensearch.test.OpenSearchTestCase; import org.passay.CharacterCharacteristicsRule; import org.passay.CharacterRule; @@ -146,9 +146,9 @@ public void testGeneratedPasswordContents() { } public void testIssueOnBehalfOfTokenFromClaims() { - Map claims = new HashMap<>(); - claims.put("aud", "test"); - BasicAuthToken authToken = (BasicAuthToken) shiroAuthTokenHandler.issueOnBehalfOfToken(claims); + Subject subject = new NoopSubject(); + OnBehalfOfClaims claims = new OnBehalfOfClaims("test", "test"); + BasicAuthToken authToken = (BasicAuthToken) shiroAuthTokenHandler.issueOnBehalfOfToken(subject, claims); assertTrue(authToken instanceof BasicAuthToken); UsernamePasswordToken translatedToken = (UsernamePasswordToken) shiroAuthTokenHandler.translateAuthToken(authToken).get(); assertEquals(authToken.getPassword(), new String(translatedToken.getPassword())); @@ -158,17 +158,10 @@ public void testIssueOnBehalfOfTokenFromClaims() { public void testTokenNoopIssuance() { NoopTokenManager tokenManager = new NoopTokenManager(); - AuthToken token = tokenManager.issueOnBehalfOfToken(Map.of("test", "test")); + OnBehalfOfClaims claims = new OnBehalfOfClaims("test", "test"); + Subject subject = new NoopSubject(); + AuthToken token = tokenManager.issueOnBehalfOfToken(subject, claims); assertTrue(token instanceof AuthToken); } - public void testStandardTokenClaims() { - assertEquals(StandardTokenClaims.AUDIENCE.getName(), "aud"); - assertEquals(StandardTokenClaims.ISSUED_AT.getName(), "iat"); - assertEquals(StandardTokenClaims.ISSUER.getName(), "iss"); - assertEquals(StandardTokenClaims.EXPIRATION_TIME.getName(), "exp"); - assertEquals(StandardTokenClaims.JWT_ID.getName(), "jti"); - assertEquals(StandardTokenClaims.NOT_BEFORE.getName(), "nbf"); - assertEquals(StandardTokenClaims.SUBJECT.getName(), "sub"); - } } diff --git a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java index bc3ce5acd78e2..85e65b441d2ec 100644 --- a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java +++ b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java @@ -32,7 +32,9 @@ import org.opensearch.extensions.ExtensionsManager; import org.opensearch.http.HttpRequest; import org.opensearch.identity.IdentityService; -import org.opensearch.identity.tokens.StandardTokenClaims; +import org.opensearch.identity.Subject; +import org.opensearch.identity.tokens.OnBehalfOfClaims; +import org.opensearch.identity.tokens.TokenManager; import org.opensearch.rest.BaseRestHandler; import org.opensearch.rest.BytesRestResponse; import org.opensearch.rest.NamedRoute; @@ -236,8 +238,14 @@ public String executor() { try { + // Will be replaced with ExtensionTokenProcessor and PrincipalIdentifierToken classes from feature/identity + Map> filteredHeaders = filterHeaders(headers, allowList, denyList); + TokenManager tokenManager = identityService.getTokenManager(); + Subject subject = this.identityService.getSubject(); + OnBehalfOfClaims claims = new OnBehalfOfClaims(discoveryExtensionNode.getId(), subject.getPrincipal().getName()); + transportService.sendRequest( discoveryExtensionNode, ExtensionsManager.REQUEST_REST_EXECUTE_ON_EXTENSION_ACTION, @@ -251,12 +259,7 @@ public String executor() { filteredHeaders, contentType, content, - identityService.getTokenManager() - .issueOnBehalfOfToken(Map.of(StandardTokenClaims.AUDIENCE.getName(), discoveryExtensionNode.getId())) // This gets - // an - // extensions - // uniqueId - .getTokenValue(), + tokenManager.issueOnBehalfOfToken(subject, claims).getTokenValue(), httpVersion ), restExecuteOnExtensionResponseHandler diff --git a/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java b/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java index e64522979b024..c8b5800e5db06 100644 --- a/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java +++ b/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java @@ -8,12 +8,12 @@ package org.opensearch.identity.noop; -import java.util.Map; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.opensearch.identity.IdentityService; import org.opensearch.identity.Subject; import org.opensearch.identity.tokens.AuthToken; +import org.opensearch.identity.tokens.OnBehalfOfClaims; import org.opensearch.identity.tokens.TokenManager; /** @@ -30,6 +30,10 @@ public class NoopTokenManager implements TokenManager { @Override public AuthToken issueOnBehalfOfToken(final Subject subject, final OnBehalfOfClaims claims) { return new AuthToken() { + @Override + public String getTokenValue() { + return null; + } }; } diff --git a/server/src/main/java/org/opensearch/identity/tokens/AuthToken.java b/server/src/main/java/org/opensearch/identity/tokens/AuthToken.java index 2f4e191237302..a6be823297def 100644 --- a/server/src/main/java/org/opensearch/identity/tokens/AuthToken.java +++ b/server/src/main/java/org/opensearch/identity/tokens/AuthToken.java @@ -14,5 +14,5 @@ * @opensearch.experimental */ public interface AuthToken { - String getTokenValue(); + String getTokenValue(); } diff --git a/server/src/main/java/org/opensearch/identity/tokens/OnBehalfOfClaims.java b/server/src/main/java/org/opensearch/identity/tokens/OnBehalfOfClaims.java new file mode 100644 index 0000000000000..15a1a17c01cc4 --- /dev/null +++ b/server/src/main/java/org/opensearch/identity/tokens/OnBehalfOfClaims.java @@ -0,0 +1,58 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.identity.tokens; + +public class OnBehalfOfClaims { + + private final String audience; + private final String issuer; + private final Long expiration; + private final Long not_before; + private final Long issued_at; + + public OnBehalfOfClaims(String aud, String issuer, Long expiration, Long not_before, Long issued_at) { + this.audience = aud; + this.issuer = issuer; + this.expiration = expiration; + this.not_before = not_before; + this.issued_at = issued_at; + } + + public OnBehalfOfClaims(String aud, String issuer, Long expiration, Long not_before) { + this(aud, issuer, expiration, not_before, System.nanoTime() / 1000000); + } + + public OnBehalfOfClaims(String aud, String issuer, Long expiration) { + this(aud, issuer, expiration, System.nanoTime() / 1000000); + } + + public OnBehalfOfClaims(String aud, String issuer) { + this(aud, issuer, System.nanoTime() / 1000000 + 300000); + } + + public String getAudience() { + return audience; + } + + public String getIssuer() { + return issuer; + } + + public Long getExpiration() { + return expiration; + } + + public Long getNot_before() { + return not_before; + } + + public Long getIssued_at() { + return issued_at; + } +} diff --git a/server/src/main/java/org/opensearch/identity/tokens/StandardTokenClaims.java b/server/src/main/java/org/opensearch/identity/tokens/StandardTokenClaims.java deleted file mode 100644 index 09f60521d0e30..0000000000000 --- a/server/src/main/java/org/opensearch/identity/tokens/StandardTokenClaims.java +++ /dev/null @@ -1,42 +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. - */ - -package org.opensearch.identity.tokens; - -/** - * This enum represents the standard claims that are used in the JWTs for OnBehalfOf tokens - */ -public enum StandardTokenClaims { - - ISSUER("iss"), - SUBJECT("sub"), - AUDIENCE("aud"), - EXPIRATION_TIME("exp"), - NOT_BEFORE("nbf"), - ISSUED_AT("iat"), - JWT_ID("jti"); - - private final String name; - - StandardTokenClaims(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - @Override - public String toString() { - return name; - } - - public static StandardTokenClaims fromString(String name) { - return StandardTokenClaims.valueOf(name); - } -} diff --git a/server/src/main/java/org/opensearch/identity/tokens/TokenManager.java b/server/src/main/java/org/opensearch/identity/tokens/TokenManager.java index 791f37bae410b..4f6ddeb48dea3 100644 --- a/server/src/main/java/org/opensearch/identity/tokens/TokenManager.java +++ b/server/src/main/java/org/opensearch/identity/tokens/TokenManager.java @@ -8,7 +8,6 @@ package org.opensearch.identity.tokens; -import java.util.Map; import org.opensearch.identity.Subject; /** @@ -22,7 +21,7 @@ public interface TokenManager { * @param claims: A list of claims for the token to be generated with * @return A new auth token */ - public AuthToken issueOnBehalfOfToken(Map claims); + public AuthToken issueOnBehalfOfToken(final Subject subject, final OnBehalfOfClaims claims); /** * Authenticates a provided authToken diff --git a/server/src/main/java/org/opensearch/node/Node.java b/server/src/main/java/org/opensearch/node/Node.java index 6348f204ea4ef..b86d962aa9e4b 100644 --- a/server/src/main/java/org/opensearch/node/Node.java +++ b/server/src/main/java/org/opensearch/node/Node.java @@ -115,9 +115,6 @@ import org.opensearch.common.inject.Module; import org.opensearch.common.inject.ModulesBuilder; import org.opensearch.common.lease.Releasables; - -import org.opensearch.core.common.io.stream.NamedWriteableRegistry; - import org.opensearch.common.logging.DeprecationLogger; import org.opensearch.common.logging.HeaderWarning; import org.opensearch.common.logging.NodeAndClusterIdStateListener; @@ -142,6 +139,7 @@ import org.opensearch.common.util.PageCacheRecycler; import org.opensearch.common.util.io.IOUtils; import org.opensearch.core.Assertions; +import org.opensearch.core.common.io.stream.NamedWriteableRegistry; import org.opensearch.core.xcontent.NamedXContentRegistry; import org.opensearch.discovery.Discovery; import org.opensearch.discovery.DiscoveryModule; @@ -247,6 +245,7 @@ import org.opensearch.telemetry.TelemetryModule; import org.opensearch.telemetry.TelemetrySettings; import org.opensearch.telemetry.tracing.NoopTracerFactory; +import org.opensearch.telemetry.tracing.Tracer; import org.opensearch.telemetry.tracing.TracerFactory; import org.opensearch.threadpool.ExecutorBuilder; import org.opensearch.threadpool.RunnableTaskExecutionListener; From 3ae548c35f90bb62df8d5799d061ae81ed06e980 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Mon, 24 Jul 2023 17:17:07 -0400 Subject: [PATCH 20/33] Add javadoc Signed-off-by: Stephen Crawford --- .../rest/RestSendToExtensionAction.java | 1 - .../identity/tokens/OnBehalfOfClaims.java | 29 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java index 4d0662343225f..3156d6863fb1a 100644 --- a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java +++ b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java @@ -24,7 +24,6 @@ import org.apache.logging.log4j.Logger; import org.opensearch.action.ActionModule.DynamicActionRegistry; import org.opensearch.client.node.NodeClient; -import org.opensearch.common.xcontent.XContentType; import org.opensearch.core.common.bytes.BytesReference; import org.opensearch.core.common.io.stream.StreamInput; import org.opensearch.core.rest.RestStatus; diff --git a/server/src/main/java/org/opensearch/identity/tokens/OnBehalfOfClaims.java b/server/src/main/java/org/opensearch/identity/tokens/OnBehalfOfClaims.java index 15a1a17c01cc4..a398f0c4f9b64 100644 --- a/server/src/main/java/org/opensearch/identity/tokens/OnBehalfOfClaims.java +++ b/server/src/main/java/org/opensearch/identity/tokens/OnBehalfOfClaims.java @@ -8,6 +8,9 @@ package org.opensearch.identity.tokens; +/** + * This class represents the claims of an OnBehalfOf token. + */ public class OnBehalfOfClaims { private final String audience; @@ -16,6 +19,14 @@ public class OnBehalfOfClaims { private final Long not_before; private final Long issued_at; + /** + * Constructor for OnBehalfOfClaims + * @param aud the Audience for the token + * @param issuer the Issuer of the token + * @param expiration the expiration time in seconds for the token + * @param not_before the not_before time in seconds for the token + * @param issued_at the issued_at time in seconds for the token + */ public OnBehalfOfClaims(String aud, String issuer, Long expiration, Long not_before, Long issued_at) { this.audience = aud; this.issuer = issuer; @@ -24,14 +35,32 @@ public OnBehalfOfClaims(String aud, String issuer, Long expiration, Long not_bef this.issued_at = issued_at; } + /** + * A constructor that sets a default issued at time of the current time + * @param aud the Audience for the token + * @param issuer the Issuer of the token + * @param expiration the expiration time in seconds for the token + * @param not_before the not_before time in seconds for the token + */ public OnBehalfOfClaims(String aud, String issuer, Long expiration, Long not_before) { this(aud, issuer, expiration, not_before, System.nanoTime() / 1000000); } + /** + * A constructor which sets a default not before time of the current time + * @param aud the Audience for the token + * @param issuer the Issuer of the token + * @param expiration the expiration time in seconds for the token + */ public OnBehalfOfClaims(String aud, String issuer, Long expiration) { this(aud, issuer, expiration, System.nanoTime() / 1000000); } + /** + * A constructor which sets the default expiration time of 5 minutes from the current time + * @param aud the Audience for the token + * @param issuer the Issuer of the token + */ public OnBehalfOfClaims(String aud, String issuer) { this(aud, issuer, System.nanoTime() / 1000000 + 300000); } From a7b91072a7825343f012c975e3546b15a8361782 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Thu, 27 Jul 2023 10:51:29 -0400 Subject: [PATCH 21/33] Make token check happen before write Signed-off-by: Stephen Crawford --- .../extensions/rest/ExtensionRestRequest.java | 16 ++++- .../rest/RestSendToExtensionAction.java | 30 ++++----- .../identity/noop/NoopTokenManager.java | 2 +- .../rest/ExtensionRestRequestTests.java | 63 ++++++++++++++++++- 4 files changed, 93 insertions(+), 18 deletions(-) diff --git a/server/src/main/java/org/opensearch/extensions/rest/ExtensionRestRequest.java b/server/src/main/java/org/opensearch/extensions/rest/ExtensionRestRequest.java index e6df6e964a31b..09cab4d7c2cb6 100644 --- a/server/src/main/java/org/opensearch/extensions/rest/ExtensionRestRequest.java +++ b/server/src/main/java/org/opensearch/extensions/rest/ExtensionRestRequest.java @@ -8,6 +8,7 @@ package org.opensearch.extensions.rest; +import org.opensearch.OpenSearchException; import org.opensearch.OpenSearchParseException; import org.opensearch.Version; import org.opensearch.common.xcontent.LoggingDeprecationHandler; @@ -118,6 +119,7 @@ public ExtensionRestRequest(StreamInput in) throws IOException { @Override public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); + validateRequestIssuerIdentity(); out.writeEnum(method); out.writeString(uri); out.writeString(path); @@ -280,7 +282,7 @@ public boolean isContentConsumed() { } /** - * Gets a parser for the contents of this request if there is content and an xContentType. + * Gets a parser for the contents of this request if there is content, an xContentType, and a principal identifier. * * @param xContentRegistry The extension's xContentRegistry * @return A parser for the given content and content type. @@ -291,6 +293,9 @@ public final XContentParser contentParser(NamedXContentRegistry xContentRegistry if (!hasContent() || getXContentType() == null) { throw new OpenSearchParseException("There is no request body or the ContentType is invalid."); } + if (!hasContent() || getRequestIssuerIdentity() == null) { + throw new OpenSearchParseException("There is no request body or the requester identity is invalid."); + } return getXContentType().xContent().createParser(xContentRegistry, LoggingDeprecationHandler.INSTANCE, content.streamInput()); } @@ -301,6 +306,15 @@ public String getRequestIssuerIdentity() { return principalIdentifierToken; } + /** + * Assert that the principal identifier token is not null. + */ + public void validateRequestIssuerIdentity() { + if (principalIdentifierToken == null) { + throw new OpenSearchException("Principal identifier token is null"); + } + } + /** * @return This REST request's HTTP protocol version */ diff --git a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java index 3156d6863fb1a..3c798c292b868 100644 --- a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java +++ b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java @@ -8,29 +8,15 @@ package org.opensearch.extensions.rest; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.stream.Collectors; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.opensearch.action.ActionModule.DynamicActionRegistry; import org.opensearch.client.node.NodeClient; import org.opensearch.core.common.bytes.BytesReference; import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.core.rest.RestStatus; import org.opensearch.core.xcontent.MediaType; import org.opensearch.extensions.DiscoveryExtensionNode; import org.opensearch.extensions.ExtensionsManager; -import org.opensearch.http.HttpRequest; import org.opensearch.identity.IdentityService; import org.opensearch.identity.Subject; import org.opensearch.identity.tokens.OnBehalfOfClaims; @@ -40,10 +26,26 @@ import org.opensearch.rest.NamedRoute; import org.opensearch.rest.RestRequest; import org.opensearch.rest.RestRequest.Method; +import org.opensearch.core.rest.RestStatus; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.TransportException; import org.opensearch.transport.TransportResponseHandler; import org.opensearch.transport.TransportService; +import org.opensearch.http.HttpRequest; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + import static java.util.Collections.emptyList; import static java.util.Collections.emptyMap; import static java.util.Collections.unmodifiableList; diff --git a/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java b/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java index c8b5800e5db06..60d7e7c289d97 100644 --- a/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java +++ b/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java @@ -32,7 +32,7 @@ public AuthToken issueOnBehalfOfToken(final Subject subject, final OnBehalfOfCla return new AuthToken() { @Override public String getTokenValue() { - return null; + return "noopToken"; } }; } diff --git a/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java b/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java index e12549b93ab53..beb131caad799 100644 --- a/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java +++ b/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java @@ -8,6 +8,8 @@ package org.opensearch.extensions.rest; +import org.opensearch.OpenSearchException; +import org.opensearch.common.settings.Settings; import org.opensearch.core.rest.RestStatus; import org.opensearch.OpenSearchParseException; import org.opensearch.core.common.bytes.BytesArray; @@ -19,6 +21,10 @@ import org.opensearch.core.xcontent.XContentParser; import org.opensearch.common.xcontent.XContentType; import org.opensearch.core.common.io.stream.NamedWriteableAwareStreamInput; +import org.opensearch.identity.IdentityService; +import org.opensearch.identity.Subject; +import org.opensearch.identity.tokens.OnBehalfOfClaims; +import org.opensearch.identity.tokens.TokenManager; import org.opensearch.rest.BytesRestResponse; import org.opensearch.rest.RestRequest.Method; import org.opensearch.http.HttpRequest; @@ -44,10 +50,11 @@ public class ExtensionRestRequestTests extends OpenSearchTestCase { String extensionUniqueId1; Principal userPrincipal; HttpRequest.HttpVersion expectedHttpVersion; - // Will be replaced with ExtensionTokenProcessor and PrincipalIdentifierToken classes from feature/identity + // Will be replaced with PrincipalIdentifierToken classes from feature/identity String extensionTokenProcessor; String expectedRequestIssuerIdentity; NamedWriteableRegistry registry; + private IdentityService identityService; public void setUp() throws Exception { super.setUp(); @@ -65,7 +72,13 @@ public void setUp() throws Exception { userPrincipal = () -> "user1"; expectedHttpVersion = HttpRequest.HttpVersion.HTTP_1_1; extensionTokenProcessor = "placeholder_extension_token_processor"; - expectedRequestIssuerIdentity = "placeholder_request_issuer_identity"; + identityService = new IdentityService(Settings.EMPTY, List.of()); + TokenManager tokenManager = identityService.getTokenManager(); + Subject subject = this.identityService.getSubject(); + OnBehalfOfClaims claims = new OnBehalfOfClaims("testID", subject.getPrincipal().getName()); + expectedRequestIssuerIdentity = identityService.getTokenManager() + .issueOnBehalfOfToken(identityService.getSubject(), claims) + .getTokenValue(); } public void testExtensionRestRequest() throws Exception { @@ -129,6 +142,52 @@ public void testExtensionRestRequest() throws Exception { } } + public void testExtensionRestRequestWithNoIdentityToken() throws Exception { + ExtensionRestRequest request = new ExtensionRestRequest( + expectedMethod, + expectedUri, + expectedPath, + expectedParams, + expectedHeaders, + expectedContentType, + expectedContent, + null, + expectedHttpVersion + ); + + assertEquals(expectedMethod, request.method()); + assertEquals(expectedUri, request.uri()); + assertEquals(expectedPath, request.path()); + + assertEquals(expectedParams, request.params()); + assertEquals(expectedHttpVersion, request.protocolVersion()); + + assertEquals(Collections.emptyList(), request.consumedParams()); + assertTrue(request.hasParam("foo")); + assertFalse(request.hasParam("bar")); + assertEquals("bar", request.param("foo")); + assertEquals("baz", request.param("bar", "baz")); + assertEquals(42L, request.paramAsLong("baz", 0L)); + assertEquals(0L, request.paramAsLong("bar", 0L)); + assertTrue(request.consumedParams().contains("foo")); + assertTrue(request.consumedParams().contains("baz")); + + assertEquals(expectedContentType, request.getXContentType()); + assertTrue(request.hasContent()); + assertFalse(request.isContentConsumed()); + assertEquals(expectedContent, request.content()); + assertTrue(request.isContentConsumed()); + + XContentParser parser = request.contentParser(NamedXContentRegistry.EMPTY); + Map contentMap = parser.mapStrings(); + assertEquals("value", contentMap.get("key")); + + try (BytesStreamOutput out = new BytesStreamOutput()) { + OpenSearchException ex = assertThrows(OpenSearchException.class, () -> request.writeTo(out)); + assertEquals("Principal identifier token is null", ex.getMessage()); + } + } + public void testExtensionRestRequestWithNoContent() throws Exception { ExtensionRestRequest request = new ExtensionRestRequest( expectedMethod, From d7cf2eaf0f7e257e8addc010d30d99e8e39b2048 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Thu, 27 Jul 2023 14:37:51 -0400 Subject: [PATCH 22/33] Fix test Signed-off-by: Stephen Crawford --- .../extensions/rest/ExtensionRestRequestTests.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java b/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java index beb131caad799..27f6cd551dc9e 100644 --- a/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java +++ b/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java @@ -178,13 +178,12 @@ public void testExtensionRestRequestWithNoIdentityToken() throws Exception { assertEquals(expectedContent, request.content()); assertTrue(request.isContentConsumed()); - XContentParser parser = request.contentParser(NamedXContentRegistry.EMPTY); - Map contentMap = parser.mapStrings(); - assertEquals("value", contentMap.get("key")); + OpenSearchParseException ex = assertThrows(OpenSearchParseException.class,() -> request.contentParser(NamedXContentRegistry.EMPTY)); + assertTrue(ex.getMessage().contains("There is no request body or the requester identity is invalid.")); try (BytesStreamOutput out = new BytesStreamOutput()) { - OpenSearchException ex = assertThrows(OpenSearchException.class, () -> request.writeTo(out)); - assertEquals("Principal identifier token is null", ex.getMessage()); + OpenSearchException ex2 = assertThrows(OpenSearchException.class, () -> request.writeTo(out)); + assertEquals("Principal identifier token is null", ex2.getMessage()); } } From 5db917808d998fbadb1e8363ff15ff53f96dcb80 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Thu, 27 Jul 2023 14:51:19 -0400 Subject: [PATCH 23/33] Spotless Signed-off-by: Stephen Crawford --- .../extensions/rest/ExtensionRestRequestTests.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java b/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java index 27f6cd551dc9e..c48194b6b3745 100644 --- a/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java +++ b/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java @@ -178,7 +178,10 @@ public void testExtensionRestRequestWithNoIdentityToken() throws Exception { assertEquals(expectedContent, request.content()); assertTrue(request.isContentConsumed()); - OpenSearchParseException ex = assertThrows(OpenSearchParseException.class,() -> request.contentParser(NamedXContentRegistry.EMPTY)); + OpenSearchParseException ex = assertThrows( + OpenSearchParseException.class, + () -> request.contentParser(NamedXContentRegistry.EMPTY) + ); assertTrue(ex.getMessage().contains("There is no request body or the requester identity is invalid.")); try (BytesStreamOutput out = new BytesStreamOutput()) { From 2aa6d4f6365b9d4d12e4a13937db56b17e5ea1b0 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Thu, 27 Jul 2023 16:19:59 -0400 Subject: [PATCH 24/33] trigger retry Signed-off-by: Stephen Crawford --- .../opensearch/extensions/rest/ExtensionRestRequestTests.java | 1 - 1 file changed, 1 deletion(-) diff --git a/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java b/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java index c48194b6b3745..39a35b3427f7a 100644 --- a/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java +++ b/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java @@ -50,7 +50,6 @@ public class ExtensionRestRequestTests extends OpenSearchTestCase { String extensionUniqueId1; Principal userPrincipal; HttpRequest.HttpVersion expectedHttpVersion; - // Will be replaced with PrincipalIdentifierToken classes from feature/identity String extensionTokenProcessor; String expectedRequestIssuerIdentity; NamedWriteableRegistry registry; From f073f5cdbef2e471bb5962a2a0af7cda50944d76 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Fri, 28 Jul 2023 10:16:24 -0400 Subject: [PATCH 25/33] changes Signed-off-by: Stephen Crawford --- .../rest/RestSendToExtensionAction.java | 2 +- .../identity/noop/NoopTokenManager.java | 2 +- .../opensearch/identity/tokens/AuthToken.java | 3 +- .../identity/tokens/BasicAuthToken.java | 2 +- .../identity/tokens/BearerAuthToken.java | 2 +- .../main/java/org/opensearch/node/Node.java | 138 +++++++++--------- .../rest/ExtensionRestRequestTests.java | 25 +--- 7 files changed, 77 insertions(+), 97 deletions(-) diff --git a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java index 3c798c292b868..29217b2cd7e36 100644 --- a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java +++ b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java @@ -261,7 +261,7 @@ public String executor() { filteredHeaders, contentType, content, - tokenManager.issueOnBehalfOfToken(subject, claims).getTokenValue(), + tokenManager.issueOnBehalfOfToken(subject, claims).asAuthHeaderValue(), httpVersion ), restExecuteOnExtensionResponseHandler diff --git a/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java b/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java index 60d7e7c289d97..1255e822cea6e 100644 --- a/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java +++ b/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java @@ -31,7 +31,7 @@ public class NoopTokenManager implements TokenManager { public AuthToken issueOnBehalfOfToken(final Subject subject, final OnBehalfOfClaims claims) { return new AuthToken() { @Override - public String getTokenValue() { + public String asAuthHeaderValue() { return "noopToken"; } }; diff --git a/server/src/main/java/org/opensearch/identity/tokens/AuthToken.java b/server/src/main/java/org/opensearch/identity/tokens/AuthToken.java index a6be823297def..c929e7421b3d8 100644 --- a/server/src/main/java/org/opensearch/identity/tokens/AuthToken.java +++ b/server/src/main/java/org/opensearch/identity/tokens/AuthToken.java @@ -14,5 +14,6 @@ * @opensearch.experimental */ public interface AuthToken { - String getTokenValue(); + + String asAuthHeaderValue(); } diff --git a/server/src/main/java/org/opensearch/identity/tokens/BasicAuthToken.java b/server/src/main/java/org/opensearch/identity/tokens/BasicAuthToken.java index da3a29944e784..71b8fe504a5d1 100644 --- a/server/src/main/java/org/opensearch/identity/tokens/BasicAuthToken.java +++ b/server/src/main/java/org/opensearch/identity/tokens/BasicAuthToken.java @@ -53,7 +53,7 @@ public void revoke() { } @Override - public String getTokenValue() { + public String asAuthHeaderValue() { if (user == null || password == null) { return null; } diff --git a/server/src/main/java/org/opensearch/identity/tokens/BearerAuthToken.java b/server/src/main/java/org/opensearch/identity/tokens/BearerAuthToken.java index 32ec32673851a..217538c7b001b 100644 --- a/server/src/main/java/org/opensearch/identity/tokens/BearerAuthToken.java +++ b/server/src/main/java/org/opensearch/identity/tokens/BearerAuthToken.java @@ -60,7 +60,7 @@ public String toString() { } @Override - public String getTokenValue() { + public String asAuthHeaderValue() { return completeToken; } } diff --git a/server/src/main/java/org/opensearch/node/Node.java b/server/src/main/java/org/opensearch/node/Node.java index b86d962aa9e4b..28c12f05f405d 100644 --- a/server/src/main/java/org/opensearch/node/Node.java +++ b/server/src/main/java/org/opensearch/node/Node.java @@ -32,40 +32,47 @@ package org.opensearch.node; -import java.io.BufferedWriter; -import java.io.Closeable; -import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardCopyOption; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Executor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Function; -import java.util.function.UnaryOperator; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import javax.net.ssl.SNIHostName; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.lucene.util.Constants; -import org.opensearch.Build; import org.opensearch.ExceptionsHelper; +import org.opensearch.common.SetOnce; +import org.opensearch.common.settings.SettingsException; +import org.opensearch.common.unit.ByteSizeUnit; +import org.opensearch.common.unit.ByteSizeValue; +import org.opensearch.common.util.FeatureFlags; +import org.opensearch.cluster.routing.allocation.AwarenessReplicaBalance; +import org.opensearch.index.IndexModule; +import org.opensearch.index.IndexingPressureService; +import org.opensearch.index.store.remote.filecache.FileCache; +import org.opensearch.index.store.remote.filecache.FileCacheCleaner; +import org.opensearch.index.store.remote.filecache.FileCacheFactory; +import org.opensearch.indices.replication.SegmentReplicationSourceFactory; +import org.opensearch.indices.replication.SegmentReplicationTargetService; +import org.opensearch.indices.replication.SegmentReplicationSourceService; +import org.opensearch.extensions.ExtensionsManager; +import org.opensearch.extensions.NoopExtensionsManager; +import org.opensearch.monitor.fs.FsInfo; +import org.opensearch.monitor.fs.FsProbe; +import org.opensearch.plugins.ExtensionAwarePlugin; +import org.opensearch.plugins.SearchPipelinePlugin; +import org.opensearch.telemetry.tracing.NoopTracerFactory; +import org.opensearch.telemetry.tracing.Tracer; +import org.opensearch.telemetry.tracing.TracerFactory; +import org.opensearch.search.backpressure.SearchBackpressureService; +import org.opensearch.search.backpressure.settings.SearchBackpressureSettings; +import org.opensearch.search.pipeline.SearchPipelineService; +import org.opensearch.tasks.TaskCancellationMonitoringService; +import org.opensearch.tasks.TaskCancellationMonitoringSettings; +import org.opensearch.tasks.TaskResourceTrackingService; +import org.opensearch.tasks.consumer.TopNSearchTasksLogger; +import org.opensearch.threadpool.RunnableTaskExecutionListener; +import org.opensearch.index.store.RemoteSegmentStoreDirectoryFactory; +import org.opensearch.telemetry.TelemetryModule; +import org.opensearch.telemetry.TelemetrySettings; +import org.opensearch.watcher.ResourceWatcherService; +import org.opensearch.core.Assertions; +import org.opensearch.Build; import org.opensearch.OpenSearchException; import org.opensearch.OpenSearchTimeoutException; import org.opensearch.Version; @@ -102,10 +109,8 @@ import org.opensearch.cluster.node.DiscoveryNodeRole; import org.opensearch.cluster.routing.BatchedRerouteService; import org.opensearch.cluster.routing.RerouteService; -import org.opensearch.cluster.routing.allocation.AwarenessReplicaBalance; import org.opensearch.cluster.routing.allocation.DiskThresholdMonitor; import org.opensearch.cluster.service.ClusterService; -import org.opensearch.common.SetOnce; import org.opensearch.common.StopWatch; import org.opensearch.common.breaker.CircuitBreaker; import org.opensearch.common.component.Lifecycle; @@ -114,7 +119,7 @@ import org.opensearch.common.inject.Key; import org.opensearch.common.inject.Module; import org.opensearch.common.inject.ModulesBuilder; -import org.opensearch.common.lease.Releasables; +import org.opensearch.core.common.io.stream.NamedWriteableRegistry; import org.opensearch.common.logging.DeprecationLogger; import org.opensearch.common.logging.HeaderWarning; import org.opensearch.common.logging.NodeAndClusterIdStateListener; @@ -127,27 +132,20 @@ import org.opensearch.common.settings.Setting.Property; import org.opensearch.common.settings.SettingUpgrader; import org.opensearch.common.settings.Settings; -import org.opensearch.common.settings.SettingsException; import org.opensearch.common.settings.SettingsModule; import org.opensearch.common.transport.BoundTransportAddress; import org.opensearch.common.transport.TransportAddress; -import org.opensearch.common.unit.ByteSizeUnit; -import org.opensearch.common.unit.ByteSizeValue; import org.opensearch.common.unit.TimeValue; import org.opensearch.common.util.BigArrays; -import org.opensearch.common.util.FeatureFlags; import org.opensearch.common.util.PageCacheRecycler; import org.opensearch.common.util.io.IOUtils; -import org.opensearch.core.Assertions; -import org.opensearch.core.common.io.stream.NamedWriteableRegistry; +import org.opensearch.common.lease.Releasables; import org.opensearch.core.xcontent.NamedXContentRegistry; import org.opensearch.discovery.Discovery; import org.opensearch.discovery.DiscoveryModule; import org.opensearch.env.Environment; import org.opensearch.env.NodeEnvironment; import org.opensearch.env.NodeMetadata; -import org.opensearch.extensions.ExtensionsManager; -import org.opensearch.extensions.NoopExtensionsManager; import org.opensearch.gateway.GatewayAllocator; import org.opensearch.gateway.GatewayMetaState; import org.opensearch.gateway.GatewayModule; @@ -156,15 +154,9 @@ import org.opensearch.gateway.PersistedClusterStateService; import org.opensearch.http.HttpServerTransport; import org.opensearch.identity.IdentityService; -import org.opensearch.index.IndexModule; import org.opensearch.index.IndexSettings; -import org.opensearch.index.IndexingPressureService; import org.opensearch.index.analysis.AnalysisRegistry; import org.opensearch.index.engine.EngineFactory; -import org.opensearch.index.store.RemoteSegmentStoreDirectoryFactory; -import org.opensearch.index.store.remote.filecache.FileCache; -import org.opensearch.index.store.remote.filecache.FileCacheCleaner; -import org.opensearch.index.store.remote.filecache.FileCacheFactory; import org.opensearch.indices.IndicesModule; import org.opensearch.indices.IndicesService; import org.opensearch.indices.ShardLimitValidator; @@ -179,15 +171,10 @@ import org.opensearch.indices.recovery.PeerRecoverySourceService; import org.opensearch.indices.recovery.PeerRecoveryTargetService; import org.opensearch.indices.recovery.RecoverySettings; -import org.opensearch.indices.replication.SegmentReplicationSourceFactory; -import org.opensearch.indices.replication.SegmentReplicationSourceService; -import org.opensearch.indices.replication.SegmentReplicationTargetService; import org.opensearch.indices.store.IndicesStore; import org.opensearch.ingest.IngestService; import org.opensearch.monitor.MonitorService; import org.opensearch.monitor.fs.FsHealthService; -import org.opensearch.monitor.fs.FsInfo; -import org.opensearch.monitor.fs.FsProbe; import org.opensearch.monitor.jvm.JvmInfo; import org.opensearch.persistent.PersistentTasksClusterService; import org.opensearch.persistent.PersistentTasksExecutor; @@ -199,7 +186,6 @@ import org.opensearch.plugins.ClusterPlugin; import org.opensearch.plugins.DiscoveryPlugin; import org.opensearch.plugins.EnginePlugin; -import org.opensearch.plugins.ExtensionAwarePlugin; import org.opensearch.plugins.IdentityPlugin; import org.opensearch.plugins.IndexStorePlugin; import org.opensearch.plugins.IngestPlugin; @@ -211,7 +197,6 @@ import org.opensearch.plugins.PluginsService; import org.opensearch.plugins.RepositoryPlugin; import org.opensearch.plugins.ScriptPlugin; -import org.opensearch.plugins.SearchPipelinePlugin; import org.opensearch.plugins.SearchPlugin; import org.opensearch.plugins.SystemIndexPlugin; import org.opensearch.plugins.TelemetryPlugin; @@ -225,10 +210,7 @@ import org.opensearch.search.SearchModule; import org.opensearch.search.SearchService; import org.opensearch.search.aggregations.support.AggregationUsageService; -import org.opensearch.search.backpressure.SearchBackpressureService; -import org.opensearch.search.backpressure.settings.SearchBackpressureSettings; import org.opensearch.search.fetch.FetchPhase; -import org.opensearch.search.pipeline.SearchPipelineService; import org.opensearch.search.query.QueryPhase; import org.opensearch.snapshots.InternalSnapshotsInfoService; import org.opensearch.snapshots.RestoreService; @@ -236,26 +218,46 @@ import org.opensearch.snapshots.SnapshotsInfoService; import org.opensearch.snapshots.SnapshotsService; import org.opensearch.tasks.Task; -import org.opensearch.tasks.TaskCancellationMonitoringService; -import org.opensearch.tasks.TaskCancellationMonitoringSettings; import org.opensearch.tasks.TaskCancellationService; -import org.opensearch.tasks.TaskResourceTrackingService; import org.opensearch.tasks.TaskResultsService; -import org.opensearch.tasks.consumer.TopNSearchTasksLogger; -import org.opensearch.telemetry.TelemetryModule; -import org.opensearch.telemetry.TelemetrySettings; -import org.opensearch.telemetry.tracing.NoopTracerFactory; -import org.opensearch.telemetry.tracing.Tracer; -import org.opensearch.telemetry.tracing.TracerFactory; import org.opensearch.threadpool.ExecutorBuilder; -import org.opensearch.threadpool.RunnableTaskExecutionListener; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.RemoteClusterService; import org.opensearch.transport.Transport; import org.opensearch.transport.TransportInterceptor; import org.opensearch.transport.TransportService; import org.opensearch.usage.UsageService; -import org.opensearch.watcher.ResourceWatcherService; + +import javax.net.ssl.SNIHostName; +import java.io.BufferedWriter; +import java.io.Closeable; +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; +import java.util.function.UnaryOperator; +import java.util.stream.Collectors; +import java.util.stream.Stream; + import static java.util.stream.Collectors.toList; import static org.opensearch.common.util.FeatureFlags.TELEMETRY; import static org.opensearch.env.NodeEnvironment.collectFileCacheDataPath; diff --git a/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java b/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java index 39a35b3427f7a..08f07b2ffa297 100644 --- a/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java +++ b/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java @@ -77,7 +77,7 @@ public void setUp() throws Exception { OnBehalfOfClaims claims = new OnBehalfOfClaims("testID", subject.getPrincipal().getName()); expectedRequestIssuerIdentity = identityService.getTokenManager() .issueOnBehalfOfToken(identityService.getSubject(), claims) - .getTokenValue(); + .asAuthHeaderValue(); } public void testExtensionRestRequest() throws Exception { @@ -154,29 +154,6 @@ public void testExtensionRestRequestWithNoIdentityToken() throws Exception { expectedHttpVersion ); - assertEquals(expectedMethod, request.method()); - assertEquals(expectedUri, request.uri()); - assertEquals(expectedPath, request.path()); - - assertEquals(expectedParams, request.params()); - assertEquals(expectedHttpVersion, request.protocolVersion()); - - assertEquals(Collections.emptyList(), request.consumedParams()); - assertTrue(request.hasParam("foo")); - assertFalse(request.hasParam("bar")); - assertEquals("bar", request.param("foo")); - assertEquals("baz", request.param("bar", "baz")); - assertEquals(42L, request.paramAsLong("baz", 0L)); - assertEquals(0L, request.paramAsLong("bar", 0L)); - assertTrue(request.consumedParams().contains("foo")); - assertTrue(request.consumedParams().contains("baz")); - - assertEquals(expectedContentType, request.getXContentType()); - assertTrue(request.hasContent()); - assertFalse(request.isContentConsumed()); - assertEquals(expectedContent, request.content()); - assertTrue(request.isContentConsumed()); - OpenSearchParseException ex = assertThrows( OpenSearchParseException.class, () -> request.contentParser(NamedXContentRegistry.EMPTY) From 46a6812bbe2ceea087935fc1ed7bc318f9b67a2a Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Fri, 28 Jul 2023 11:19:51 -0400 Subject: [PATCH 26/33] Swap issuer with subject Signed-off-by: Stephen Crawford --- .../identity/tokens/OnBehalfOfClaims.java | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/server/src/main/java/org/opensearch/identity/tokens/OnBehalfOfClaims.java b/server/src/main/java/org/opensearch/identity/tokens/OnBehalfOfClaims.java index a398f0c4f9b64..77939cbc24cdb 100644 --- a/server/src/main/java/org/opensearch/identity/tokens/OnBehalfOfClaims.java +++ b/server/src/main/java/org/opensearch/identity/tokens/OnBehalfOfClaims.java @@ -14,7 +14,7 @@ public class OnBehalfOfClaims { private final String audience; - private final String issuer; + private final String subject; private final Long expiration; private final Long not_before; private final Long issued_at; @@ -22,14 +22,14 @@ public class OnBehalfOfClaims { /** * Constructor for OnBehalfOfClaims * @param aud the Audience for the token - * @param issuer the Issuer of the token + * @param subject the subject of the token * @param expiration the expiration time in seconds for the token * @param not_before the not_before time in seconds for the token * @param issued_at the issued_at time in seconds for the token */ - public OnBehalfOfClaims(String aud, String issuer, Long expiration, Long not_before, Long issued_at) { + public OnBehalfOfClaims(String aud, String subject, Long expiration, Long not_before, Long issued_at) { this.audience = aud; - this.issuer = issuer; + this.subject = subject; this.expiration = expiration; this.not_before = not_before; this.issued_at = issued_at; @@ -38,39 +38,39 @@ public OnBehalfOfClaims(String aud, String issuer, Long expiration, Long not_bef /** * A constructor that sets a default issued at time of the current time * @param aud the Audience for the token - * @param issuer the Issuer of the token + * @param subject the subject of the token * @param expiration the expiration time in seconds for the token * @param not_before the not_before time in seconds for the token */ - public OnBehalfOfClaims(String aud, String issuer, Long expiration, Long not_before) { - this(aud, issuer, expiration, not_before, System.nanoTime() / 1000000); + public OnBehalfOfClaims(String aud, String subject, Long expiration, Long not_before) { + this(aud, subject, expiration, not_before, System.nanoTime() / 1000000); } /** * A constructor which sets a default not before time of the current time * @param aud the Audience for the token - * @param issuer the Issuer of the token + * @param subject the subject of the token * @param expiration the expiration time in seconds for the token */ - public OnBehalfOfClaims(String aud, String issuer, Long expiration) { - this(aud, issuer, expiration, System.nanoTime() / 1000000); + public OnBehalfOfClaims(String aud, String subject, Long expiration) { + this(aud, subject, expiration, System.nanoTime() / 1000000); } /** * A constructor which sets the default expiration time of 5 minutes from the current time * @param aud the Audience for the token - * @param issuer the Issuer of the token + * @param subject the subject of the token */ - public OnBehalfOfClaims(String aud, String issuer) { - this(aud, issuer, System.nanoTime() / 1000000 + 300000); + public OnBehalfOfClaims(String aud, String subject) { + this(aud, subject, System.nanoTime() / 1000000 + 300000); } public String getAudience() { return audience; } - public String getIssuer() { - return issuer; + public String getSubject() { + return subject; } public Long getExpiration() { From 45c3dcd1020ae45261689371bb144cfae4ee7dbc Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Mon, 31 Jul 2023 11:09:21 -0400 Subject: [PATCH 27/33] Boost coverage Signed-off-by: Stephen Crawford --- .../org/opensearch/identity/shiro/AuthTokenHandlerTests.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/identity-shiro/src/test/java/org/opensearch/identity/shiro/AuthTokenHandlerTests.java b/plugins/identity-shiro/src/test/java/org/opensearch/identity/shiro/AuthTokenHandlerTests.java index f7ae9bd1ad8e6..e443bb7deef9e 100644 --- a/plugins/identity-shiro/src/test/java/org/opensearch/identity/shiro/AuthTokenHandlerTests.java +++ b/plugins/identity-shiro/src/test/java/org/opensearch/identity/shiro/AuthTokenHandlerTests.java @@ -42,6 +42,7 @@ public void testSetup() { public void testShouldExtractBasicAuthTokenSuccessfully() { final BasicAuthToken authToken = new BasicAuthToken("Basic YWRtaW46YWRtaW4="); // admin:admin + assertEquals(authToken.asAuthHeaderValue(), "YWRtaW46YWRtaW4="); final AuthenticationToken translatedToken = shiroAuthTokenHandler.translateAuthToken(authToken).get(); assertThat(translatedToken, is(instanceOf(UsernamePasswordToken.class))); @@ -122,6 +123,7 @@ public void testVerifyBearerTokenObject() { assertEquals(testGoodToken.getPayload(), "payload"); assertEquals(testGoodToken.getSignature(), "signature"); assertEquals(testGoodToken.toString(), "Bearer auth token with header=header, payload=payload, signature=signature"); + assertEquals(testGoodToken.asAuthHeaderValue(), "header.payload.signature"); } public void testGeneratedPasswordContents() { From 67806ed5a7affeee0d704308e52c72f8b9132a4d Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Mon, 31 Jul 2023 11:12:18 -0400 Subject: [PATCH 28/33] Boost coverage Signed-off-by: Stephen Crawford --- .../org/opensearch/identity/shiro/AuthTokenHandlerTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/identity-shiro/src/test/java/org/opensearch/identity/shiro/AuthTokenHandlerTests.java b/plugins/identity-shiro/src/test/java/org/opensearch/identity/shiro/AuthTokenHandlerTests.java index e443bb7deef9e..448a138e68181 100644 --- a/plugins/identity-shiro/src/test/java/org/opensearch/identity/shiro/AuthTokenHandlerTests.java +++ b/plugins/identity-shiro/src/test/java/org/opensearch/identity/shiro/AuthTokenHandlerTests.java @@ -108,7 +108,7 @@ public void testShoudPassMapLookupWithToken() { assertTrue(authToken.getPassword().equals(shiroAuthTokenHandler.getShiroTokenPasswordMap().get(authToken))); } - public void testShouldPassThrougbResetToken(AuthToken token) { + public void testShouldPassThroughResetToken() { final BearerAuthToken bearerAuthToken = new BearerAuthToken("header.payload.signature"); shiroAuthTokenHandler.resetToken(bearerAuthToken); } From d990651663670efdd072111d564dc8f78892e975 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Fri, 11 Aug 2023 09:55:25 -0400 Subject: [PATCH 29/33] Fix Signed-off-by: Stephen Crawford --- .../extensions/rest/ExtensionRestRequest.java | 15 +++------------ .../identity/tokens/OnBehalfOfClaims.java | 6 +++--- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/server/src/main/java/org/opensearch/extensions/rest/ExtensionRestRequest.java b/server/src/main/java/org/opensearch/extensions/rest/ExtensionRestRequest.java index 1922c256b9a39..18bf52cd03af5 100644 --- a/server/src/main/java/org/opensearch/extensions/rest/ExtensionRestRequest.java +++ b/server/src/main/java/org/opensearch/extensions/rest/ExtensionRestRequest.java @@ -31,6 +31,7 @@ import java.util.Map; import java.util.Objects; import java.util.Set; +import static java.util.Objects.requireNonNull; /** * Request to execute REST actions on extension node. @@ -87,7 +88,7 @@ public ExtensionRestRequest( this.headers = headers; this.mediaType = mediaType; this.content = content; - this.principalIdentifierToken = principalIdentifier; + this.principalIdentifierToken = requireNonNull(principalIdentifier); this.httpVersion = httpVersion; } @@ -119,7 +120,6 @@ public ExtensionRestRequest(StreamInput in) throws IOException { @Override public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); - validateRequestIssuerIdentity(); out.writeEnum(method); out.writeString(uri); out.writeString(path); @@ -293,7 +293,7 @@ public final XContentParser contentParser(NamedXContentRegistry xContentRegistry if (!hasContent() || getXContentType() == null) { throw new OpenSearchParseException("There is no request body or the ContentType is invalid."); } - if (!hasContent() || getRequestIssuerIdentity() == null) { + if (getRequestIssuerIdentity() == null) { throw new OpenSearchParseException("There is no request body or the requester identity is invalid."); } return getXContentType().xContent().createParser(xContentRegistry, LoggingDeprecationHandler.INSTANCE, content.streamInput()); @@ -306,15 +306,6 @@ public String getRequestIssuerIdentity() { return principalIdentifierToken; } - /** - * Assert that the principal identifier token is not null. - */ - public void validateRequestIssuerIdentity() { - if (principalIdentifierToken == null) { - throw new OpenSearchException("Principal identifier token is null"); - } - } - /** * @return This REST request's HTTP protocol version */ diff --git a/server/src/main/java/org/opensearch/identity/tokens/OnBehalfOfClaims.java b/server/src/main/java/org/opensearch/identity/tokens/OnBehalfOfClaims.java index 77939cbc24cdb..3fef248ee6d3a 100644 --- a/server/src/main/java/org/opensearch/identity/tokens/OnBehalfOfClaims.java +++ b/server/src/main/java/org/opensearch/identity/tokens/OnBehalfOfClaims.java @@ -43,7 +43,7 @@ public OnBehalfOfClaims(String aud, String subject, Long expiration, Long not_be * @param not_before the not_before time in seconds for the token */ public OnBehalfOfClaims(String aud, String subject, Long expiration, Long not_before) { - this(aud, subject, expiration, not_before, System.nanoTime() / 1000000); + this(aud, subject, expiration, not_before, System.currentTimeMillis() / 1000); } /** @@ -53,7 +53,7 @@ public OnBehalfOfClaims(String aud, String subject, Long expiration, Long not_be * @param expiration the expiration time in seconds for the token */ public OnBehalfOfClaims(String aud, String subject, Long expiration) { - this(aud, subject, expiration, System.nanoTime() / 1000000); + this(aud, subject, expiration, System.currentTimeMillis() / 1000); } /** @@ -62,7 +62,7 @@ public OnBehalfOfClaims(String aud, String subject, Long expiration) { * @param subject the subject of the token */ public OnBehalfOfClaims(String aud, String subject) { - this(aud, subject, System.nanoTime() / 1000000 + 300000); + this(aud, subject, System.currentTimeMillis() / 1000 + 300); } public String getAudience() { From 5479019612bfdd2788cdff0d9b5974abe8ec7220 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Fri, 11 Aug 2023 10:04:33 -0400 Subject: [PATCH 30/33] spotless Signed-off-by: Stephen Crawford --- .../org/opensearch/extensions/rest/ExtensionRestRequest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/server/src/main/java/org/opensearch/extensions/rest/ExtensionRestRequest.java b/server/src/main/java/org/opensearch/extensions/rest/ExtensionRestRequest.java index 18bf52cd03af5..f49c5a8291c7f 100644 --- a/server/src/main/java/org/opensearch/extensions/rest/ExtensionRestRequest.java +++ b/server/src/main/java/org/opensearch/extensions/rest/ExtensionRestRequest.java @@ -8,7 +8,6 @@ package org.opensearch.extensions.rest; -import org.opensearch.OpenSearchException; import org.opensearch.OpenSearchParseException; import org.opensearch.Version; import org.opensearch.common.xcontent.LoggingDeprecationHandler; From d2b7519c9f786e2ba2f8b286ec013b7f3d0236ec Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Fri, 11 Aug 2023 13:11:12 -0400 Subject: [PATCH 31/33] remove bad decleration Signed-off-by: Stephen Crawford --- .../extensions/ExtensionsManagerTests.java | 2 -- .../rest/ExtensionRestRequestTests.java | 26 ------------------- 2 files changed, 28 deletions(-) diff --git a/server/src/test/java/org/opensearch/extensions/ExtensionsManagerTests.java b/server/src/test/java/org/opensearch/extensions/ExtensionsManagerTests.java index 3608d6fe0b7b1..b3e2214a21ee7 100644 --- a/server/src/test/java/org/opensearch/extensions/ExtensionsManagerTests.java +++ b/server/src/test/java/org/opensearch/extensions/ExtensionsManagerTests.java @@ -10,7 +10,6 @@ import java.io.IOException; import java.net.InetAddress; -import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; import static java.util.Collections.emptyList; @@ -94,7 +93,6 @@ public class ExtensionsManagerTests extends OpenSearchTestCase { private NodeClient client; private MockNioTransport transport; private IdentityService identityService; - private Path extensionDir; private final ThreadPool threadPool = new TestThreadPool(ExtensionsManagerTests.class.getSimpleName()); private final Settings settings = Settings.builder() diff --git a/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java b/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java index 08f07b2ffa297..efb8ecc99c764 100644 --- a/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java +++ b/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java @@ -8,7 +8,6 @@ package org.opensearch.extensions.rest; -import org.opensearch.OpenSearchException; import org.opensearch.common.settings.Settings; import org.opensearch.core.rest.RestStatus; import org.opensearch.OpenSearchParseException; @@ -141,31 +140,6 @@ public void testExtensionRestRequest() throws Exception { } } - public void testExtensionRestRequestWithNoIdentityToken() throws Exception { - ExtensionRestRequest request = new ExtensionRestRequest( - expectedMethod, - expectedUri, - expectedPath, - expectedParams, - expectedHeaders, - expectedContentType, - expectedContent, - null, - expectedHttpVersion - ); - - OpenSearchParseException ex = assertThrows( - OpenSearchParseException.class, - () -> request.contentParser(NamedXContentRegistry.EMPTY) - ); - assertTrue(ex.getMessage().contains("There is no request body or the requester identity is invalid.")); - - try (BytesStreamOutput out = new BytesStreamOutput()) { - OpenSearchException ex2 = assertThrows(OpenSearchException.class, () -> request.writeTo(out)); - assertEquals("Principal identifier token is null", ex2.getMessage()); - } - } - public void testExtensionRestRequestWithNoContent() throws Exception { ExtensionRestRequest request = new ExtensionRestRequest( expectedMethod, From 40afb9e5537d9d3988eb907bd0549d4e985cfbbf Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Fri, 11 Aug 2023 15:59:42 -0400 Subject: [PATCH 32/33] Fix changelog Signed-off-by: Stephen Crawford --- CHANGELOG.md | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f247fa1b73fe..2820aff8c1c17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,10 +9,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Add getter for path field in NestedQueryBuilder ([#4636](https://github.com/opensearch-project/OpenSearch/pull/4636)) - Allow mmap to use new JDK-19 preview APIs in Apache Lucene 9.4+ ([#5151](https://github.com/opensearch-project/OpenSearch/pull/5151)) - Add events correlation engine plugin ([#6854](https://github.com/opensearch-project/OpenSearch/issues/6854)) -- Add support for ignoring missing Javadoc on generated code using annotation ([#7604](https://github.com/opensearch-project/OpenSearch/pull/7604)) -- Add partial results support for concurrent segment search ([#8306](https://github.com/opensearch-project/OpenSearch/pull/8306)) -- Pass OnBehalfOfToken in RestSendToExtensionAction ([#8679](https://github.com/opensearch-project/OpenSearch/pull/8679)) - Introduce new dynamic cluster setting to control slice computation for concurrent segment search ([#9107](https://github.com/opensearch-project/OpenSearch/pull/9107)) +- Pass OnBehalfOfToken in RestSendToExtensionAction ([#8679](https://github.com/opensearch-project/OpenSearch/pull/8679)) ### Dependencies - Bump `log4j-core` from 2.18.0 to 2.19.0 @@ -92,10 +90,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Dependencies - Bump `org.apache.logging.log4j:log4j-core` from 2.17.1 to 2.20.0 ([#8307](https://github.com/opensearch-project/OpenSearch/pull/8307)) -- Bump `io.grpc:grpc-context` from 1.46.0 to 1.56.1 ([#8726](https://github.com/opensearch-project/OpenSearch/pull/8726)) +- Bump `io.grpc:grpc-context` from 1.46.0 to 1.57.1 ([#8726](https://github.com/opensearch-project/OpenSearch/pull/8726), [#9145](https://github.com/opensearch-project/OpenSearch/pull/9145)) - Bump `com.netflix.nebula:gradle-info-plugin` from 12.1.5 to 12.1.6 ([#8724](https://github.com/opensearch-project/OpenSearch/pull/8724)) - Bump `commons-codec:commons-codec` from 1.15 to 1.16.0 ([#8725](https://github.com/opensearch-project/OpenSearch/pull/8725)) -- Bump `org.apache.zookeeper:zookeeper` from 3.8.1 to 3.8.2 ([#8844](https://github.com/opensearch-project/OpenSearch/pull/8844)) +- Bump `org.apache.zookeeper:zookeeper` from 3.8.1 to 3.9.0 ([#8844](https://github.com/opensearch-project/OpenSearch/pull/8844), [#9146](https://github.com/opensearch-project/OpenSearch/pull/9146)) - Bump `org.gradle.test-retry` from 1.5.3 to 1.5.4 ([#8842](https://github.com/opensearch-project/OpenSearch/pull/8842)) - Bump `com.netflix.nebula.ospackage-base` from 11.3.0 to 11.4.0 ([#8838](https://github.com/opensearch-project/OpenSearch/pull/8838)) - Bump `com.google.http-client:google-http-client-gson` from 1.43.2 to 1.43.3 ([#8840](https://github.com/opensearch-project/OpenSearch/pull/8840)) @@ -109,17 +107,29 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Bump `netty` from 4.1.94.Final to 4.1.96.Final ([#9030](https://github.com/opensearch-project/OpenSearch/pull/9030)) - Bump `io.projectreactor.netty:reactor-netty-http` from 1.1.8 to 1.1.9 ([#9147](https://github.com/opensearch-project/OpenSearch/pull/9147)) - Bump `org.apache.maven:maven-model` from 3.9.3 to 3.9.4 ([#9148](https://github.com/opensearch-project/OpenSearch/pull/9148)) +- Bump `com.azure:azure-storage-blob` from 12.22.3 to 12.23.0 ([#9231](https://github.com/opensearch-project/OpenSearch/pull/9231)) +- Bump `com.diffplug.spotless` from 6.19.0 to 6.20.0 ([#9227](https://github.com/opensearch-project/OpenSearch/pull/9227)) +- Bump `org.xerial.snappy:snappy-java` from 1.1.8.2 to 1.1.10.3 ([#9252](https://github.com/opensearch-project/OpenSearch/pull/9252)) +- Bump `com.squareup.okhttp3:okhttp` from 4.9.3 to 4.11.0 ([#9252](https://github.com/opensearch-project/OpenSearch/pull/9252)) +- Bump `com.squareup.okio:okio` from 2.8.0 to 3.5.0 ([#9252](https://github.com/opensearch-project/OpenSearch/pull/9252)) +- Bump `com.google.code.gson:gson` from 2.9.0 to 2.10.1 ([#9230](https://github.com/opensearch-project/OpenSearch/pull/9230)) +- Bump `lycheeverse/lychee-action` from 1.2.0 to 1.8.0 ([#9228](https://github.com/opensearch-project/OpenSearch/pull/9228)) +- Bump `snakeyaml` from 2.0 to 2.1 ([#9269](https://github.com/opensearch-project/OpenSearch/pull/9269)) ### Changed - Perform aggregation postCollection in ContextIndexSearcher after searching leaves ([#8303](https://github.com/opensearch-project/OpenSearch/pull/8303)) - Make Span exporter configurable ([#8620](https://github.com/opensearch-project/OpenSearch/issues/8620)) - Change InternalSignificantTerms to sum shard-level superset counts only in final reduce ([#8735](https://github.com/opensearch-project/OpenSearch/pull/8735)) - Exclude 'benchmarks' from codecov report ([#8805](https://github.com/opensearch-project/OpenSearch/pull/8805)) +- Adds support for tracing runnable scenarios ([#8831](https://github.com/opensearch-project/OpenSearch/pull/8831)) - [Refactor] MediaTypeParser to MediaTypeParserRegistry ([#8636](https://github.com/opensearch-project/OpenSearch/pull/8636)) - Create separate SourceLookup instance per segment slice in SignificantTextAggregatorFactory ([#8807](https://github.com/opensearch-project/OpenSearch/pull/8807)) - Add support for aggregation profiler with concurrent aggregation ([#8801](https://github.com/opensearch-project/OpenSearch/pull/8801)) - [Remove] Deprecated Fractional ByteSizeValue support #9005 ([#9005](https://github.com/opensearch-project/OpenSearch/pull/9005)) - Make MultiBucketConsumerService thread safe to use across slices during search ([#9047](https://github.com/opensearch-project/OpenSearch/pull/9047)) +- Change shard_size and shard_min_doc_count evaluation to happen in shard level reduce phase ([#9085](https://github.com/opensearch-project/OpenSearch/pull/9085)) +- Add attributes to startSpan methods ([#9199](https://github.com/opensearch-project/OpenSearch/pull/9199)) + ### Deprecated ### Removed @@ -130,4 +140,4 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Security [Unreleased 3.0]: https://github.com/opensearch-project/OpenSearch/compare/2.x...HEAD -[Unreleased 2.x]: https://github.com/opensearch-project/OpenSearch/compare/2.10...2.x \ No newline at end of file +[Unreleased 2.x]: https://github.com/opensearch-project/OpenSearch/compare/2.10...2.x From 5d17b266380dd6796ad6ad90203f4191ba4c61ea Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Fri, 11 Aug 2023 16:01:52 -0400 Subject: [PATCH 33/33] Changelog Signed-off-by: Stephen Crawford --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2820aff8c1c17..d336ddfc8d35e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Allow mmap to use new JDK-19 preview APIs in Apache Lucene 9.4+ ([#5151](https://github.com/opensearch-project/OpenSearch/pull/5151)) - Add events correlation engine plugin ([#6854](https://github.com/opensearch-project/OpenSearch/issues/6854)) - Introduce new dynamic cluster setting to control slice computation for concurrent segment search ([#9107](https://github.com/opensearch-project/OpenSearch/pull/9107)) -- Pass OnBehalfOfToken in RestSendToExtensionAction ([#8679](https://github.com/opensearch-project/OpenSearch/pull/8679)) +- Implement on behalf of token passing for extensions ([#8679](https://github.com/opensearch-project/OpenSearch/pull/8679)) ### Dependencies - Bump `log4j-core` from 2.18.0 to 2.19.0