From eee8b01af63e1b40285554fe9737e100f181108f Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Tue, 29 Aug 2023 09:26:36 -0400 Subject: [PATCH 01/22] Add transport action Signed-off-by: Stephen Crawford --- .../identity/shiro/ShiroTokenManager.java | 13 ++++ .../extensions/ExtensionsManager.java | 53 +++++++++++++- .../action/IssueServiceAccountRequest.java | 57 +++++++++++++++ .../action/IssueServiceAccountResponse.java | 69 +++++++++++++++++++ .../rest/RestInitializeExtensionAction.java | 1 + .../identity/noop/NoopTokenManager.java | 14 ++++ .../identity/tokens/TokenManager.java | 8 +++ .../main/java/org/opensearch/node/Node.java | 2 +- 8 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountRequest.java create mode 100644 server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.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 60239d609a08a..1c3b754edecf0 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 @@ -75,6 +75,19 @@ public AuthToken issueOnBehalfOfToken(Subject subject, OnBehalfOfClaims claims) return token; } + @Override + public AuthToken issueServiceAccountToken(String audience) { + + String password = generatePassword(); + final byte[] rawEncoded = Base64.getEncoder().encode((audience + ":" + password).getBytes(UTF_8)); // Make a new + final String usernamePassword = new String(rawEncoded, UTF_8); + final String header = "Basic " + usernamePassword; + + BasicAuthToken token = new BasicAuthToken(header); + shiroTokenPasswordMap.put(token, password); + return token; + } + @Override public Subject authenticateToken(AuthToken authToken) { return new NoopSubject(); diff --git a/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java b/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java index 61a6e2faa09e0..fe4cd900f6a1d 100644 --- a/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java +++ b/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java @@ -33,6 +33,8 @@ import org.opensearch.extensions.action.ExtensionActionRequest; import org.opensearch.extensions.action.ExtensionActionResponse; import org.opensearch.extensions.action.ExtensionTransportActionsHandler; +import org.opensearch.extensions.action.IssueServiceAccountRequest; +import org.opensearch.extensions.action.IssueServiceAccountResponse; import org.opensearch.extensions.action.RegisterTransportActionsRequest; import org.opensearch.extensions.action.RemoteExtensionActionResponse; import org.opensearch.extensions.action.TransportActionRequestFromExtension; @@ -41,6 +43,7 @@ import org.opensearch.extensions.settings.CustomSettingsRequestHandler; import org.opensearch.extensions.settings.RegisterCustomSettingsRequest; import org.opensearch.identity.IdentityService; +import org.opensearch.identity.tokens.AuthToken; import org.opensearch.threadpool.ThreadPool; import org.opensearch.transport.ConnectTransportException; import org.opensearch.transport.TransportException; @@ -76,6 +79,7 @@ public class ExtensionsManager { public static final String REQUEST_REST_EXECUTE_ON_EXTENSION_ACTION = "internal:extensions/restexecuteonextensiontaction"; public static final String REQUEST_EXTENSION_HANDLE_TRANSPORT_ACTION = "internal:extensions/handle-transportaction"; public static final String REQUEST_EXTENSION_HANDLE_REMOTE_TRANSPORT_ACTION = "internal:extensions/handle-remote-transportaction"; + public static final String REQUEST_EXTENSION_ISSUE_SERVICE_ACCOUNT = "internal:extensions/issue-service-account"; public static final String TRANSPORT_ACTION_REQUEST_FROM_EXTENSION = "internal:extensions/request-transportaction-from-extension"; public static final int EXTENSION_REQUEST_WAIT_TIMEOUT = 10; private static final Logger logger = LogManager.getLogger(ExtensionsManager.class); @@ -101,6 +105,7 @@ public static enum OpenSearchRequestType { private Settings environmentSettings; private AddSettingsUpdateConsumerRequestHandler addSettingsUpdateConsumerRequestHandler; private NodeClient client; + private IdentityService identityService; /** * Instantiate a new ExtensionsManager object to handle requests and responses from extensions. This is called during Node bootstrap. @@ -108,7 +113,7 @@ public static enum OpenSearchRequestType { * @param additionalSettings Additional settings to read in from extension initialization request * @throws IOException If the extensions discovery file is not properly retrieved. */ - public ExtensionsManager(Set> additionalSettings) throws IOException { + public ExtensionsManager(Set> additionalSettings, IdentityService identityService) throws IOException { logger.info("ExtensionsManager initialized"); this.initializedExtensions = new HashMap(); this.extensionIdMap = new HashMap(); @@ -123,6 +128,7 @@ public ExtensionsManager(Set> additionalSettings) throws IOException } this.client = null; this.extensionTransportActionsHandler = null; + this.identityService = identityService; } /** @@ -443,6 +449,51 @@ TransportResponse handleExtensionRequest(ExtensionRequest extensionRequest) thro } } + public void issueServiceAccount(Extension extension) { + DiscoveryExtensionNode discoveryExtensionNode = extensionIdMap.get(extension.getUniqueId()); + AuthToken serviceAccountToken = identityService.getTokenManager().issueServiceAccountToken(extension.getUniqueId()); + String authTokenAsString = serviceAccountToken.asAuthHeaderValue(); + final CompletableFuture inProgressFuture = new CompletableFuture<>(); + final TransportResponseHandler issueServiceAccountResponseHandler = new TransportResponseHandler< + IssueServiceAccountResponse>() { + + @Override + public IssueServiceAccountResponse read(StreamInput in) throws IOException { + return new IssueServiceAccountResponse(in); + } + + @Override + public void handleResponse(IssueServiceAccountResponse response) { + for (DiscoveryExtensionNode extension : extensionIdMap.values()) { + if (extension.getName().equals(response.getName()) + && (serviceAccountToken.equals(response.getServiceAccountString()))) { + logger.info("Successfully issued service account token to extension: " + extension.getName()); + break; + } + } + inProgressFuture.complete(response); + } + + @Override + public void handleException(TransportException exp) { + logger.error(new ParameterizedMessage("Issuance of service account token failed"), exp); + inProgressFuture.completeExceptionally(exp); + } + + @Override + public String executor() { + return ThreadPool.Names.GENERIC; + } + }; + + transportService.sendRequest( + discoveryExtensionNode, + REQUEST_EXTENSION_ISSUE_SERVICE_ACCOUNT, + new IssueServiceAccountRequest(authTokenAsString), + issueServiceAccountResponseHandler + ); + } + static String getRequestExtensionActionName() { return REQUEST_EXTENSION_ACTION_NAME; } diff --git a/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountRequest.java b/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountRequest.java new file mode 100644 index 0000000000000..450317626f06f --- /dev/null +++ b/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountRequest.java @@ -0,0 +1,57 @@ +/* + * 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.extensions.action; + +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.transport.TransportRequest; + +import java.io.IOException; +import java.util.Objects; + +public class IssueServiceAccountRequest extends TransportRequest { + + private final String serviceAccountToken; + + public IssueServiceAccountRequest(String serviceAccountToken) { + this.serviceAccountToken = serviceAccountToken; + } + + public IssueServiceAccountRequest(StreamInput in) throws IOException { + super(in); + this.serviceAccountToken = in.readString(); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + } + + public String getServiceAccountToken() { + return this.serviceAccountToken; + } + + @Override + public String toString() { + return "IssueServiceAccountRequest {" + "serviceAccountToken=" + serviceAccountToken + "}"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + IssueServiceAccountRequest that = (IssueServiceAccountRequest) o; + return Objects.equals(serviceAccountToken, that.serviceAccountToken); + } + + @Override + public int hashCode() { + return Objects.hash(serviceAccountToken); + } +} diff --git a/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java b/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java new file mode 100644 index 0000000000000..119dc57c19e70 --- /dev/null +++ b/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java @@ -0,0 +1,69 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.extensions.action; + +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.transport.TransportResponse; + +import java.io.IOException; +import java.util.Objects; + +public class IssueServiceAccountResponse extends TransportResponse { + + private String name; + private String serviceAccountString; + + public IssueServiceAccountResponse(String name, String serviceAccountString) { + this.name = name; + this.serviceAccountString = serviceAccountString; + } + + public IssueServiceAccountResponse(StreamInput in) throws IOException { + this.name = in.readString(); + this.serviceAccountString = in.readString(); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(name); + out.writeString(serviceAccountString); + } + + /** + * @return the node that is currently leading, according to the responding node. + */ + + public String getName() { + return this.name; + } + + public String getServiceAccountString() { + return this.serviceAccountString; + } + + @Override + public String toString() { + return "InitializeExtensionResponse{" + "name = " + name + " , " + "received service account = " + serviceAccountString + "}"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + IssueServiceAccountResponse that = (IssueServiceAccountResponse) o; + return Objects.equals(name, that.name) && Objects.equals(serviceAccountString, that.serviceAccountString); + } + + @Override + public int hashCode() { + return Objects.hash(name, serviceAccountString); + } + +} diff --git a/server/src/main/java/org/opensearch/extensions/rest/RestInitializeExtensionAction.java b/server/src/main/java/org/opensearch/extensions/rest/RestInitializeExtensionAction.java index 4b622b841a040..bf81ead212043 100644 --- a/server/src/main/java/org/opensearch/extensions/rest/RestInitializeExtensionAction.java +++ b/server/src/main/java/org/opensearch/extensions/rest/RestInitializeExtensionAction.java @@ -161,6 +161,7 @@ public RestChannelConsumer prepareRequest(RestRequest request, NodeClient client try { extensionsManager.loadExtension(extension); extensionsManager.initialize(); + extensionsManager.issueServiceAccount(extension); } catch (CompletionException e) { Throwable cause = e.getCause(); if (cause instanceof TimeoutException) { 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 1255e822cea6e..1dc3a58916b5c 100644 --- a/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java +++ b/server/src/main/java/org/opensearch/identity/noop/NoopTokenManager.java @@ -37,6 +37,20 @@ public String asAuthHeaderValue() { }; } + /** + * Issue a new Noop Token + * @return a new Noop Token + */ + @Override + public AuthToken issueServiceAccountToken(final String audience) { + return new AuthToken() { + @Override + public String asAuthHeaderValue() { + return "noopToken"; + } + }; + } + @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 4f6ddeb48dea3..b4048251a06a2 100644 --- a/server/src/main/java/org/opensearch/identity/tokens/TokenManager.java +++ b/server/src/main/java/org/opensearch/identity/tokens/TokenManager.java @@ -23,6 +23,14 @@ public interface TokenManager { */ public AuthToken issueOnBehalfOfToken(final Subject subject, final OnBehalfOfClaims claims); + /** + * Create a new service account token + * + * @param audience: A string representing the unique id of the extension for which a service account token should be generated + * @return a new auth token + */ + public AuthToken issueServiceAccountToken(final String audience); + /** * Authenticates a provided authToken * @param authToken: The authToken to authenticate diff --git a/server/src/main/java/org/opensearch/node/Node.java b/server/src/main/java/org/opensearch/node/Node.java index 51cc7c9007159..67d619fc20cb4 100644 --- a/server/src/main/java/org/opensearch/node/Node.java +++ b/server/src/main/java/org/opensearch/node/Node.java @@ -484,7 +484,7 @@ protected Node( for (ExtensionAwarePlugin extAwarePlugin : extensionAwarePlugins) { additionalSettings.addAll(extAwarePlugin.getExtensionSettings()); } - this.extensionsManager = new ExtensionsManager(additionalSettings); + this.extensionsManager = new ExtensionsManager(additionalSettings, identityService); } else { this.extensionsManager = new NoopExtensionsManager(); } From 3bdc4e45e1004e60c780ade5484cf2c8cc5a86ca Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Tue, 29 Aug 2023 10:13:30 -0400 Subject: [PATCH 02/22] Update changelog Signed-off-by: Stephen Crawford --- CHANGELOG.md | 1 + .../identity/shiro/AuthTokenHandlerTests.java | 9 +++++ .../extensions/NoopExtensionsManager.java | 3 +- .../extensions/ExtensionsManagerTests.java | 36 +++++++++---------- 4 files changed, 30 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c26302cb2272..105c1414f78b7 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)) - Introduce new dynamic cluster setting to control slice computation for concurrent segment search ([#9107](https://github.com/opensearch-project/OpenSearch/pull/9107)) - Implement on behalf of token passing for extensions ([#8679](https://github.com/opensearch-project/OpenSearch/pull/8679)) +- Implement service account issuance and fetching for extensions ([#9618](https://github.com/opensearch-project/OpenSearch/pull/9618)) ### Dependencies - Bump `log4j-core` from 2.18.0 to 2.19.0 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 7c7414843d86f..1598ad2ec621f 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 @@ -169,4 +169,13 @@ public void testTokenNoopIssuance() { assertTrue(token instanceof AuthToken); } + public void testShouldSucceedIssueServiceAccountToken() { + + + } + + public void testShouldFailIssueServiceAccountToken() { + + } + } diff --git a/server/src/main/java/org/opensearch/extensions/NoopExtensionsManager.java b/server/src/main/java/org/opensearch/extensions/NoopExtensionsManager.java index 34aa3ec1367a7..16114622d3b1a 100644 --- a/server/src/main/java/org/opensearch/extensions/NoopExtensionsManager.java +++ b/server/src/main/java/org/opensearch/extensions/NoopExtensionsManager.java @@ -8,6 +8,7 @@ package org.opensearch.extensions; +import java.util.List; import org.opensearch.action.ActionModule; import org.opensearch.client.node.NodeClient; import org.opensearch.cluster.service.ClusterService; @@ -31,7 +32,7 @@ public class NoopExtensionsManager extends ExtensionsManager { public NoopExtensionsManager() throws IOException { - super(Set.of()); + super(Set.of(), new IdentityService(Settings.EMPTY, List.of())); } @Override diff --git a/server/src/test/java/org/opensearch/extensions/ExtensionsManagerTests.java b/server/src/test/java/org/opensearch/extensions/ExtensionsManagerTests.java index 697cc92e82a5e..ac64b9f0c251e 100644 --- a/server/src/test/java/org/opensearch/extensions/ExtensionsManagerTests.java +++ b/server/src/test/java/org/opensearch/extensions/ExtensionsManagerTests.java @@ -182,7 +182,7 @@ public void testLoadExtensions() throws Exception { Set> additionalSettings = extAwarePlugin.getExtensionSettings().stream().collect(Collectors.toSet()); ExtensionScopedSettings extensionScopedSettings = new ExtensionScopedSettings(additionalSettings); - ExtensionsManager extensionsManager = new ExtensionsManager(additionalSettings); + ExtensionsManager extensionsManager = new ExtensionsManager(additionalSettings, identityService); ExtensionDependency dependentExtension = new ExtensionDependency("uniqueid0", Version.fromString("2.0.0")); Extension firstExtension = new Extension( @@ -278,7 +278,7 @@ public void testNonUniqueLoadedExtensions() throws Exception { null, null ); - ExtensionsManager extensionsManager = new ExtensionsManager(Set.of()); + ExtensionsManager extensionsManager = new ExtensionsManager(Set.of(), identityService); extensionsManager.loadExtension(firstExtension); IOException exception = expectThrows(IOException.class, () -> extensionsManager.loadExtension(secondExtension)); assertEquals( @@ -317,7 +317,7 @@ public void testNonUniqueLoadedExtensions() throws Exception { public void testMissingRequiredFieldsWhileLoadingExtension() throws Exception { Extension firstExtension = new Extension("firstExtension", "uniqueid1", "127.0.0.0", "9300", "0.0.7", "3.0.0", "", null, null); - ExtensionsManager extensionsManager = new ExtensionsManager(Set.of()); + ExtensionsManager extensionsManager = new ExtensionsManager(Set.of(), identityService); IOException exception = expectThrows(IOException.class, () -> extensionsManager.loadExtension(firstExtension)); assertEquals("Required field [minimum opensearch version] is missing in the request", exception.getMessage()); @@ -374,7 +374,7 @@ public void testExtensionDependency() throws Exception { } public void testInitialize() throws Exception { - ExtensionsManager extensionsManager = new ExtensionsManager(Set.of()); + ExtensionsManager extensionsManager = new ExtensionsManager(Set.of(), identityService); initialize(extensionsManager); @@ -416,7 +416,7 @@ public void testInitialize() throws Exception { public void testHandleRegisterRestActionsRequest() throws Exception { - ExtensionsManager extensionsManager = new ExtensionsManager(Set.of()); + ExtensionsManager extensionsManager = new ExtensionsManager(Set.of(), identityService); initialize(extensionsManager); String uniqueIdStr = "uniqueid1"; @@ -430,7 +430,7 @@ public void testHandleRegisterRestActionsRequest() throws Exception { } public void testHandleRegisterSettingsRequest() throws Exception { - ExtensionsManager extensionsManager = new ExtensionsManager(Set.of()); + ExtensionsManager extensionsManager = new ExtensionsManager(Set.of(), identityService); initialize(extensionsManager); String uniqueIdStr = "uniqueid1"; @@ -446,7 +446,7 @@ public void testHandleRegisterSettingsRequest() throws Exception { } public void testHandleRegisterRestActionsRequestWithInvalidMethod() throws Exception { - ExtensionsManager extensionsManager = new ExtensionsManager(Set.of()); + ExtensionsManager extensionsManager = new ExtensionsManager(Set.of(), identityService); initialize(extensionsManager); String uniqueIdStr = "uniqueid1"; @@ -461,7 +461,7 @@ public void testHandleRegisterRestActionsRequestWithInvalidMethod() throws Excep } public void testHandleRegisterRestActionsRequestWithInvalidDeprecatedMethod() throws Exception { - ExtensionsManager extensionsManager = new ExtensionsManager(Set.of()); + ExtensionsManager extensionsManager = new ExtensionsManager(Set.of(), identityService); initialize(extensionsManager); String uniqueIdStr = "uniqueid1"; @@ -476,7 +476,7 @@ public void testHandleRegisterRestActionsRequestWithInvalidDeprecatedMethod() th } public void testHandleRegisterRestActionsRequestWithInvalidUri() throws Exception { - ExtensionsManager extensionsManager = new ExtensionsManager(Set.of()); + ExtensionsManager extensionsManager = new ExtensionsManager(Set.of(), identityService); initialize(extensionsManager); String uniqueIdStr = "uniqueid1"; List actionsList = List.of("GET", "PUT /bar", "POST /baz"); @@ -490,7 +490,7 @@ public void testHandleRegisterRestActionsRequestWithInvalidUri() throws Exceptio } public void testHandleRegisterRestActionsRequestWithInvalidDeprecatedUri() throws Exception { - ExtensionsManager extensionsManager = new ExtensionsManager(Set.of()); + ExtensionsManager extensionsManager = new ExtensionsManager(Set.of(), identityService); initialize(extensionsManager); String uniqueIdStr = "uniqueid1"; List actionsList = List.of("GET /foo", "PUT /bar", "POST /baz"); @@ -504,7 +504,7 @@ public void testHandleRegisterRestActionsRequestWithInvalidDeprecatedUri() throw } public void testHandleExtensionRequest() throws Exception { - ExtensionsManager extensionsManager = new ExtensionsManager(Set.of()); + ExtensionsManager extensionsManager = new ExtensionsManager(Set.of(), identityService); initialize(extensionsManager); ExtensionRequest clusterStateRequest = new ExtensionRequest(ExtensionRequestProto.RequestType.REQUEST_EXTENSION_CLUSTER_STATE); @@ -658,7 +658,7 @@ public void testEnvironmentSettingsDefaultValue() throws Exception { } public void testAddSettingsUpdateConsumerRequest() throws Exception { - ExtensionsManager extensionsManager = new ExtensionsManager(Set.of()); + ExtensionsManager extensionsManager = new ExtensionsManager(Set.of(), identityService); initialize(extensionsManager); List> componentSettings = List.of( @@ -702,7 +702,7 @@ public void testAddSettingsUpdateConsumerRequest() throws Exception { } public void testHandleAddSettingsUpdateConsumerRequest() throws Exception { - ExtensionsManager extensionsManager = new ExtensionsManager(Set.of()); + ExtensionsManager extensionsManager = new ExtensionsManager(Set.of(), identityService); initialize(extensionsManager); List> componentSettings = List.of( @@ -722,7 +722,7 @@ public void testHandleAddSettingsUpdateConsumerRequest() throws Exception { } public void testUpdateSettingsRequest() throws Exception { - ExtensionsManager extensionsManager = new ExtensionsManager(Set.of()); + ExtensionsManager extensionsManager = new ExtensionsManager(Set.of(), identityService); initialize(extensionsManager); Setting componentSetting = Setting.boolSetting("falseSetting", false, Property.Dynamic); @@ -751,7 +751,7 @@ public void testUpdateSettingsRequest() throws Exception { public void testRegisterHandler() throws Exception { - ExtensionsManager extensionsManager = new ExtensionsManager(Set.of()); + ExtensionsManager extensionsManager = new ExtensionsManager(Set.of(), identityService); TransportService mockTransportService = spy( new TransportService( @@ -778,7 +778,7 @@ public void testRegisterHandler() throws Exception { } public void testIncompatibleExtensionRegistration() throws IOException { - ExtensionsManager extensionsManager = new ExtensionsManager(Set.of()); + ExtensionsManager extensionsManager = new ExtensionsManager(Set.of(), identityService); Extension firstExtension = new Extension( "firstExtension", "uniqueid1", @@ -819,7 +819,7 @@ public List> getExtensionSettings() { extensionScopedSettings ); - ExtensionsManager extensionsManager = new ExtensionsManager(additionalSettings); + ExtensionsManager extensionsManager = new ExtensionsManager(additionalSettings, identityService); extensionsManager.loadExtension(firstExtension); DiscoveryExtensionNode extension = new DiscoveryExtensionNode( @@ -857,7 +857,7 @@ public void testAdditionalExtensionSettingsForExtensionWithoutCustomSettingSet() extensionScopedSettings ); - ExtensionsManager extensionsManager = new ExtensionsManager(additionalSettings); + ExtensionsManager extensionsManager = new ExtensionsManager(additionalSettings, identityService); extensionsManager.loadExtension(firstExtension); DiscoveryExtensionNode extension = new DiscoveryExtensionNode( From 6b7849fbfe3d1aee66ac79ffb81ace07da76f079 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Tue, 29 Aug 2023 10:13:57 -0400 Subject: [PATCH 03/22] Update 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 105c1414f78b7..7a576b2f3fe31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -181,4 +181,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 427d633d5878cf7175ad604c9899b8f31873fc65 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Tue, 29 Aug 2023 10:35:33 -0400 Subject: [PATCH 04/22] Add tests Signed-off-by: Stephen Crawford --- .../identity/shiro/AuthTokenHandlerTests.java | 14 ++++---- .../extensions/NoopExtensionsManager.java | 2 +- .../opensearch/action/ActionModuleTests.java | 2 +- .../IssueServiceAccountRequestTests.java | 31 +++++++++++++++++ .../IssueServiceAccountResponseTests.java | 33 +++++++++++++++++++ .../RestInitializeExtensionActionTests.java | 13 ++++++-- .../rest/RestSendToExtensionActionTests.java | 2 +- 7 files changed, 84 insertions(+), 13 deletions(-) create mode 100644 server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountRequestTests.java create mode 100644 server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountResponseTests.java 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 1598ad2ec621f..70218bca5d4cd 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 @@ -170,12 +170,12 @@ public void testTokenNoopIssuance() { } public void testShouldSucceedIssueServiceAccountToken() { - - - } - - public void testShouldFailIssueServiceAccountToken() { - + String audience = "testExtensionName"; + BasicAuthToken authToken = (BasicAuthToken) shiroAuthTokenHandler.issueServiceAccountToken(audience); + 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/extensions/NoopExtensionsManager.java b/server/src/main/java/org/opensearch/extensions/NoopExtensionsManager.java index 16114622d3b1a..81b1b91b11481 100644 --- a/server/src/main/java/org/opensearch/extensions/NoopExtensionsManager.java +++ b/server/src/main/java/org/opensearch/extensions/NoopExtensionsManager.java @@ -8,7 +8,6 @@ package org.opensearch.extensions; -import java.util.List; import org.opensearch.action.ActionModule; import org.opensearch.client.node.NodeClient; import org.opensearch.cluster.service.ClusterService; @@ -21,6 +20,7 @@ import org.opensearch.transport.TransportService; import java.io.IOException; +import java.util.List; import java.util.Optional; import java.util.Set; diff --git a/server/src/test/java/org/opensearch/action/ActionModuleTests.java b/server/src/test/java/org/opensearch/action/ActionModuleTests.java index deb0bb58a5c4d..8479f011adf48 100644 --- a/server/src/test/java/org/opensearch/action/ActionModuleTests.java +++ b/server/src/test/java/org/opensearch/action/ActionModuleTests.java @@ -143,7 +143,7 @@ public void testSetupRestHandlerContainsKnownBuiltin() throws IOException { usageService, null, new IdentityService(Settings.EMPTY, new ArrayList<>()), - new ExtensionsManager(Set.of()) + new ExtensionsManager(Set.of(), new IdentityService(Settings.EMPTY, List.of())) ); actionModule.initRestHandlers(null); // At this point the easiest way to confirm that a handler is loaded is to try to register another one on top of it and to fail diff --git a/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountRequestTests.java b/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountRequestTests.java new file mode 100644 index 0000000000000..bc4d4318b32e6 --- /dev/null +++ b/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountRequestTests.java @@ -0,0 +1,31 @@ +/* + * 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.extensions.action; + +import org.opensearch.common.io.stream.BytesStreamOutput; +import org.opensearch.core.common.bytes.BytesReference; +import org.opensearch.core.common.io.stream.BytesStreamInput; +import org.opensearch.test.OpenSearchTestCase; + +public class IssueServiceAccountRequestTests extends OpenSearchTestCase { + + public void testIssueServiceAccountRequest() throws Exception { + String serviceAccountToken = "testToken"; + IssueServiceAccountRequest request = new IssueServiceAccountRequest(serviceAccountToken); + + assertEquals(serviceAccountToken, request.getServiceAccountToken()); + + BytesStreamOutput out = new BytesStreamOutput(); + request.writeTo(out); + BytesStreamInput in = new BytesStreamInput(BytesReference.toBytes(out.bytes())); + request = new IssueServiceAccountRequest(in); + + assertEquals(serviceAccountToken, request.getServiceAccountToken()); + } +} diff --git a/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountResponseTests.java b/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountResponseTests.java new file mode 100644 index 0000000000000..465811f08a5bb --- /dev/null +++ b/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountResponseTests.java @@ -0,0 +1,33 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.extensions.action; + +import org.opensearch.common.io.stream.BytesStreamOutput; +import org.opensearch.core.common.bytes.BytesReference; +import org.opensearch.core.common.io.stream.BytesStreamInput; +import org.opensearch.test.OpenSearchTestCase; + +public class IssueServiceAccountResponseTests extends OpenSearchTestCase { + + public void testIssueServiceAccountResponse() throws Exception { + String extensionName = "testExtension"; + String serviceAccountToken = "testToken"; + IssueServiceAccountResponse response = new IssueServiceAccountResponse(extensionName, serviceAccountToken); + + assertEquals(extensionName, response.getName()); + assertEquals(serviceAccountToken, response.getServiceAccountString()); + + BytesStreamOutput out = new BytesStreamOutput(); + response.writeTo(out); + BytesStreamInput in = new BytesStreamInput(BytesReference.toBytes(out.bytes())); + response = new IssueServiceAccountResponse(in); + assertEquals(extensionName, response.getName()); + assertEquals(serviceAccountToken, response.getServiceAccountString()); + } +} diff --git a/server/src/test/java/org/opensearch/extensions/rest/RestInitializeExtensionActionTests.java b/server/src/test/java/org/opensearch/extensions/rest/RestInitializeExtensionActionTests.java index 455c9eef19bc7..d10a2805dfb29 100644 --- a/server/src/test/java/org/opensearch/extensions/rest/RestInitializeExtensionActionTests.java +++ b/server/src/test/java/org/opensearch/extensions/rest/RestInitializeExtensionActionTests.java @@ -21,6 +21,7 @@ import org.opensearch.core.xcontent.MediaTypeRegistry; import org.opensearch.extensions.ExtensionsManager; import org.opensearch.extensions.ExtensionsSettings; +import org.opensearch.identity.IdentityService; import org.opensearch.rest.RestRequest; import org.opensearch.test.OpenSearchTestCase; import org.opensearch.test.rest.FakeRestChannel; @@ -116,7 +117,7 @@ public void testRestInitializeExtensionActionResponse() throws Exception { } public void testRestInitializeExtensionActionFailure() throws Exception { - ExtensionsManager extensionsManager = new ExtensionsManager(Set.of()); + ExtensionsManager extensionsManager = new ExtensionsManager(Set.of(), new IdentityService(Settings.EMPTY, List.of())); RestInitializeExtensionAction restInitializeExtensionAction = new RestInitializeExtensionAction(extensionsManager); final String content = "{\"name\":\"ad-extension\",\"uniqueId\":\"\",\"hostAddress\":\"127.0.0.1\"," @@ -149,7 +150,10 @@ public void testRestInitializeExtensionActionResponseWithAdditionalSettings() th Function.identity(), Setting.Property.ExtensionScope ); - ExtensionsManager extensionsManager = new ExtensionsManager(Set.of(boolSetting, stringSetting, intSetting, listSetting)); + ExtensionsManager extensionsManager = new ExtensionsManager( + Set.of(boolSetting, stringSetting, intSetting, listSetting), + new IdentityService(Settings.EMPTY, List.of()) + ); ExtensionsManager spy = spy(extensionsManager); // optionally, you can stub out some methods: @@ -196,7 +200,10 @@ public void testRestInitializeExtensionActionResponseWithAdditionalSettingsUsing Function.identity(), Setting.Property.ExtensionScope ); - ExtensionsManager extensionsManager = new ExtensionsManager(Set.of(boolSetting, stringSetting, intSetting, listSetting)); + ExtensionsManager extensionsManager = new ExtensionsManager( + Set.of(boolSetting, stringSetting, intSetting, listSetting), + new IdentityService(Settings.EMPTY, List.of()) + ); ExtensionsManager spy = spy(extensionsManager); // optionally, you can stub out some methods: 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 0e75f0a8dacff..0e263b29f1e8d 100644 --- a/server/src/test/java/org/opensearch/extensions/rest/RestSendToExtensionActionTests.java +++ b/server/src/test/java/org/opensearch/extensions/rest/RestSendToExtensionActionTests.java @@ -120,7 +120,7 @@ public void setup() throws Exception { usageService, null, new IdentityService(Settings.EMPTY, new ArrayList<>()), - new ExtensionsManager(Set.of()) + new ExtensionsManager(Set.of(), new IdentityService(Settings.EMPTY, List.of())) ); identityService = new IdentityService(Settings.EMPTY, new ArrayList<>()); dynamicActionRegistry = actionModule.getDynamicActionRegistry(); From c8032a526e9f2eccf1e3e27abedec37f9bb2b339 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Tue, 29 Aug 2023 10:41:48 -0400 Subject: [PATCH 05/22] add docs Signed-off-by: Stephen Crawford --- .../org/opensearch/extensions/ExtensionsManager.java | 4 ++++ .../action/IssueServiceAccountRequest.java | 11 +++++++++++ .../action/IssueServiceAccountResponse.java | 12 ++++++++++++ 3 files changed, 27 insertions(+) diff --git a/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java b/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java index fe4cd900f6a1d..7b33775ce021e 100644 --- a/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java +++ b/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java @@ -449,6 +449,10 @@ TransportResponse handleExtensionRequest(ExtensionRequest extensionRequest) thro } } + /** + * A separate transport action handler used to issue service accounts to extensions during initialization + * @param extension The extension to be issued a service account + */ public void issueServiceAccount(Extension extension) { DiscoveryExtensionNode discoveryExtensionNode = extensionIdMap.get(extension.getUniqueId()); AuthToken serviceAccountToken = identityService.getTokenManager().issueServiceAccountToken(extension.getUniqueId()); diff --git a/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountRequest.java b/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountRequest.java index 450317626f06f..22b2c2b207936 100644 --- a/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountRequest.java +++ b/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountRequest.java @@ -15,14 +15,25 @@ import java.io.IOException; import java.util.Objects; +/** + * This class represents a Transport Request for issuing a service account to an extension. + */ public class IssueServiceAccountRequest extends TransportRequest { private final String serviceAccountToken; + /** + * This takes a string representing a service account token + * @param serviceAccountToken The string making up the service account token + */ public IssueServiceAccountRequest(String serviceAccountToken) { this.serviceAccountToken = serviceAccountToken; } + /** + * This takes a stream representing a service account token + * @param in The stream passing the token + */ public IssueServiceAccountRequest(StreamInput in) throws IOException { super(in); this.serviceAccountToken = in.readString(); diff --git a/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java b/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java index 119dc57c19e70..a8f4f779d121f 100644 --- a/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java +++ b/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java @@ -15,16 +15,28 @@ import java.io.IOException; import java.util.Objects; +/** + * This class represents a Transport Request for issuing a service account to an extension. + */ public class IssueServiceAccountResponse extends TransportResponse { private String name; private String serviceAccountString; + /** + * This takes in a name for the extension and the service account token string + * @param name The name of the extension + * @param serviceAccountString A string encapsulating the service account token + */ public IssueServiceAccountResponse(String name, String serviceAccountString) { this.name = name; this.serviceAccountString = serviceAccountString; } + /** + * This takes in a stream containing for the extension and the service account token + * @param in the stream containing the extension name and the service account token + */ public IssueServiceAccountResponse(StreamInput in) throws IOException { this.name = in.readString(); this.serviceAccountString = in.readString(); From 474839f4cd92bb47e315285096125c6ce7ec0873 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Tue, 29 Aug 2023 11:57:45 -0400 Subject: [PATCH 06/22] Fix tests Signed-off-by: Stephen Crawford --- .../extensions/action/IssueServiceAccountRequest.java | 2 +- .../extensions/rest/RestInitializeExtensionActionTests.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountRequest.java b/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountRequest.java index 22b2c2b207936..12c926dbb0063 100644 --- a/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountRequest.java +++ b/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountRequest.java @@ -35,13 +35,13 @@ public IssueServiceAccountRequest(String serviceAccountToken) { * @param in The stream passing the token */ public IssueServiceAccountRequest(StreamInput in) throws IOException { - super(in); this.serviceAccountToken = in.readString(); } @Override public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); + out.writeString(serviceAccountToken); } public String getServiceAccountToken() { diff --git a/server/src/test/java/org/opensearch/extensions/rest/RestInitializeExtensionActionTests.java b/server/src/test/java/org/opensearch/extensions/rest/RestInitializeExtensionActionTests.java index d10a2805dfb29..91bfc9cf9dc22 100644 --- a/server/src/test/java/org/opensearch/extensions/rest/RestInitializeExtensionActionTests.java +++ b/server/src/test/java/org/opensearch/extensions/rest/RestInitializeExtensionActionTests.java @@ -46,6 +46,7 @@ import static java.util.Collections.emptyMap; import static java.util.Collections.emptySet; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; @@ -158,6 +159,7 @@ public void testRestInitializeExtensionActionResponseWithAdditionalSettings() th // optionally, you can stub out some methods: when(spy.getAdditionalSettings()).thenCallRealMethod(); + doNothing().when(spy).issueServiceAccount(any()); Mockito.doCallRealMethod().when(spy).loadExtension(any(ExtensionsSettings.Extension.class)); Mockito.doNothing().when(spy).initialize(); RestInitializeExtensionAction restInitializeExtensionAction = new RestInitializeExtensionAction(spy); @@ -208,6 +210,7 @@ public void testRestInitializeExtensionActionResponseWithAdditionalSettingsUsing // optionally, you can stub out some methods: when(spy.getAdditionalSettings()).thenCallRealMethod(); + doNothing().when(spy).issueServiceAccount(any()); Mockito.doCallRealMethod().when(spy).loadExtension(any(ExtensionsSettings.Extension.class)); Mockito.doNothing().when(spy).initialize(); RestInitializeExtensionAction restInitializeExtensionAction = new RestInitializeExtensionAction(spy); From dccf05714f5c28985fda6f727fcba6e5ed14f0c4 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Tue, 29 Aug 2023 13:16:14 -0400 Subject: [PATCH 07/22] Fix test Signed-off-by: Stephen Crawford --- .../opensearch/extensions/action/IssueServiceAccountRequest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountRequest.java b/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountRequest.java index 12c926dbb0063..7d152a33e800a 100644 --- a/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountRequest.java +++ b/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountRequest.java @@ -35,6 +35,7 @@ public IssueServiceAccountRequest(String serviceAccountToken) { * @param in The stream passing the token */ public IssueServiceAccountRequest(StreamInput in) throws IOException { + super(in); this.serviceAccountToken = in.readString(); } From 27cdc5316a9a1b6357961c67524b8bcf009a5641 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Tue, 29 Aug 2023 15:40:36 -0400 Subject: [PATCH 08/22] Coverage Signed-off-by: Stephen Crawford --- .../opensearch/identity/shiro/AuthTokenHandlerTests.java | 3 +++ .../extensions/action/IssueServiceAccountResponse.java | 2 +- .../action/IssueServiceAccountRequestTests.java | 6 ++++++ .../action/IssueServiceAccountResponseTests.java | 9 +++++++++ 4 files changed, 19 insertions(+), 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 70218bca5d4cd..db77ced298991 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 @@ -167,6 +167,9 @@ public void testTokenNoopIssuance() { Subject subject = new NoopSubject(); AuthToken token = tokenManager.issueOnBehalfOfToken(subject, claims); assertTrue(token instanceof AuthToken); + AuthToken serviceAccountToken = tokenManager.issueServiceAccountToken("test"); + assertTrue(serviceAccountToken instanceof AuthToken); + assertEquals(serviceAccountToken.asAuthHeaderValue(), "noopToken"); } public void testShouldSucceedIssueServiceAccountToken() { diff --git a/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java b/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java index a8f4f779d121f..711674026c48b 100644 --- a/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java +++ b/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java @@ -62,7 +62,7 @@ public String getServiceAccountString() { @Override public String toString() { - return "InitializeExtensionResponse{" + "name = " + name + " , " + "received service account = " + serviceAccountString + "}"; + return "IssueServiceAccountResponse{" + "name = " + name + " , " + "received service account = " + serviceAccountString + "}"; } @Override diff --git a/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountRequestTests.java b/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountRequestTests.java index bc4d4318b32e6..947c17f488112 100644 --- a/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountRequestTests.java +++ b/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountRequestTests.java @@ -27,5 +27,11 @@ public void testIssueServiceAccountRequest() throws Exception { request = new IssueServiceAccountRequest(in); assertEquals(serviceAccountToken, request.getServiceAccountToken()); + + IssueServiceAccountRequest request2 = new IssueServiceAccountRequest(serviceAccountToken); + + assertEquals(request, request2); + assertEquals(request.hashCode(), request2.hashCode()); + assertEquals(request.toString(), "IssueServiceAccountRequest {" + "serviceAccountToken=" + serviceAccountToken + "}"); } } diff --git a/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountResponseTests.java b/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountResponseTests.java index 465811f08a5bb..d1fbcaeedbecc 100644 --- a/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountResponseTests.java +++ b/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountResponseTests.java @@ -29,5 +29,14 @@ public void testIssueServiceAccountResponse() throws Exception { response = new IssueServiceAccountResponse(in); assertEquals(extensionName, response.getName()); assertEquals(serviceAccountToken, response.getServiceAccountString()); + + IssueServiceAccountResponse response2 = new IssueServiceAccountResponse(extensionName, serviceAccountToken); + + assertEquals(response, response2); + assertEquals(response.hashCode(), response2.hashCode()); + assertEquals( + response.toString(), + "InitializeExtensionResponse{" + "name = " + extensionName + " , " + "received service account = " + serviceAccountToken + "}" + ); } } From 58d2d79d0b8349907a00e7504d342e5819741c42 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Tue, 29 Aug 2023 16:11:27 -0400 Subject: [PATCH 09/22] fix typo Signed-off-by: Stephen Crawford --- .../extensions/action/IssueServiceAccountResponseTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountResponseTests.java b/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountResponseTests.java index d1fbcaeedbecc..5e73dbceb83be 100644 --- a/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountResponseTests.java +++ b/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountResponseTests.java @@ -36,7 +36,7 @@ public void testIssueServiceAccountResponse() throws Exception { assertEquals(response.hashCode(), response2.hashCode()); assertEquals( response.toString(), - "InitializeExtensionResponse{" + "name = " + extensionName + " , " + "received service account = " + serviceAccountToken + "}" + "IssueServiceAccountResponse{" + "name = " + extensionName + " , " + "received service account = " + serviceAccountToken + "}" ); } } From af81d6fbaf1653341a147f91f16b24ab56f2f927 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Wed, 30 Aug 2023 10:35:11 -0400 Subject: [PATCH 10/22] rename Signed-off-by: Stephen Crawford --- .../action/IssueServiceAccountResponse.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java b/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java index 711674026c48b..78e41f1806e9e 100644 --- a/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java +++ b/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java @@ -21,16 +21,16 @@ public class IssueServiceAccountResponse extends TransportResponse { private String name; - private String serviceAccountString; + private String serviceAccountToken; /** * This takes in a name for the extension and the service account token string * @param name The name of the extension - * @param serviceAccountString A string encapsulating the service account token + * @param serviceAccountToken A string encapsulating the service account token */ - public IssueServiceAccountResponse(String name, String serviceAccountString) { + public IssueServiceAccountResponse(String name, String serviceAccountToken) { this.name = name; - this.serviceAccountString = serviceAccountString; + this.serviceAccountToken = serviceAccountToken; } /** @@ -39,13 +39,13 @@ public IssueServiceAccountResponse(String name, String serviceAccountString) { */ public IssueServiceAccountResponse(StreamInput in) throws IOException { this.name = in.readString(); - this.serviceAccountString = in.readString(); + this.serviceAccountToken = in.readString(); } @Override public void writeTo(StreamOutput out) throws IOException { out.writeString(name); - out.writeString(serviceAccountString); + out.writeString(serviceAccountToken); } /** @@ -57,12 +57,12 @@ public String getName() { } public String getServiceAccountString() { - return this.serviceAccountString; + return this.serviceAccountToken; } @Override public String toString() { - return "IssueServiceAccountResponse{" + "name = " + name + " , " + "received service account = " + serviceAccountString + "}"; + return "IssueServiceAccountResponse{" + "name = " + name + " , " + "received service account = " + serviceAccountToken + "}"; } @Override @@ -70,12 +70,12 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; IssueServiceAccountResponse that = (IssueServiceAccountResponse) o; - return Objects.equals(name, that.name) && Objects.equals(serviceAccountString, that.serviceAccountString); + return Objects.equals(name, that.name) && Objects.equals(serviceAccountToken, that.serviceAccountToken); } @Override public int hashCode() { - return Objects.hash(name, serviceAccountString); + return Objects.hash(name, serviceAccountToken); } } From fb817fcb2e61bc59b3852e0b2d19c3a8f303d5a8 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Tue, 5 Sep 2023 09:53:32 -0400 Subject: [PATCH 11/22] trigger retry Signed-off-by: Stephen Crawford --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4eafc8d6ed769..46e0c48a7ca52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,9 +11,9 @@ 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)) - Introduce new dynamic cluster setting to control slice computation for concurrent segment search ([#9107](https://github.com/opensearch-project/OpenSearch/pull/9107)) - Implement on behalf of token passing for extensions ([#8679](https://github.com/opensearch-project/OpenSearch/pull/8679)) -- Implement service account issuance and fetching for extensions ([#9618](https://github.com/opensearch-project/OpenSearch/pull/9618)) - Added encryption-sdk lib to provide encryption and decryption capabilities ([#8466](https://github.com/opensearch-project/OpenSearch/pull/8466)) - Added crypto-kms plugin to provide AWS KMS based key providers for encryption/decryption. ([#8465](https://github.com/opensearch-project/OpenSearch/pull/8465)) +- Implement service account issuance and fetching for extensions ([#9618](https://github.com/opensearch-project/OpenSearch/pull/9618)) ### Dependencies - Bump `log4j-core` from 2.18.0 to 2.19.0 From 5c0065085448204a319a3ef73941ef0b5879e7b5 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Thu, 14 Sep 2023 12:11:52 -0400 Subject: [PATCH 12/22] Swap to URL encoder Signed-off-by: Stephen Crawford --- .../java/org/opensearch/identity/shiro/ShiroTokenManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 1c3b754edecf0..a1efca8483bdf 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 @@ -64,7 +64,7 @@ public Optional translateAuthToken(org.opensearch.identity. public AuthToken issueOnBehalfOfToken(Subject subject, OnBehalfOfClaims claims) { String password = generatePassword(); - final byte[] rawEncoded = Base64.getEncoder().encode((claims.getAudience() + ":" + password).getBytes(UTF_8)); // Make a new + final byte[] rawEncoded = Base64.getUrlEncoder().encode((claims.getAudience() + ":" + password).getBytes(UTF_8)); // Make a new // ShiroSubject w/ // audience as name final String usernamePassword = new String(rawEncoded, UTF_8); From 3e2de547a834e0bebda4e80cdb6c782c52c85432 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Thu, 14 Sep 2023 12:12:20 -0400 Subject: [PATCH 13/22] remove paddign Signed-off-by: Stephen Crawford --- .../java/org/opensearch/identity/shiro/ShiroTokenManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 a1efca8483bdf..0de5816f0e5fe 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 @@ -79,7 +79,7 @@ public AuthToken issueOnBehalfOfToken(Subject subject, OnBehalfOfClaims claims) public AuthToken issueServiceAccountToken(String audience) { String password = generatePassword(); - final byte[] rawEncoded = Base64.getEncoder().encode((audience + ":" + password).getBytes(UTF_8)); // Make a new + final byte[] rawEncoded = Base64.getEncoder().withoutPadding().encode((audience + ":" + password).getBytes(UTF_8)); // Make a new final String usernamePassword = new String(rawEncoded, UTF_8); final String header = "Basic " + usernamePassword; From 25987f744992017e482ef8ab659d78fd10e26f07 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Thu, 14 Sep 2023 12:18:09 -0400 Subject: [PATCH 14/22] fix Signed-off-by: Stephen Crawford --- .../java/org/opensearch/identity/shiro/ShiroTokenManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 0de5816f0e5fe..d41f91b4193ff 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 @@ -79,7 +79,7 @@ public AuthToken issueOnBehalfOfToken(Subject subject, OnBehalfOfClaims claims) public AuthToken issueServiceAccountToken(String audience) { String password = generatePassword(); - final byte[] rawEncoded = Base64.getEncoder().withoutPadding().encode((audience + ":" + password).getBytes(UTF_8)); // Make a new + final byte[] rawEncoded = Base64.getUrlEncoder().withoutPadding().encode((audience + ":" + password).getBytes(UTF_8)); // Make a new final String usernamePassword = new String(rawEncoded, UTF_8); final String header = "Basic " + usernamePassword; From 6ba712c17fa17cbef221fd46fec1cfaa0cdf4310 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Thu, 14 Sep 2023 12:32:13 -0400 Subject: [PATCH 15/22] Spotless Signed-off-by: Stephen Crawford --- .../org/opensearch/identity/shiro/ShiroTokenManager.java | 5 +++-- 1 file changed, 3 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 d41f91b4193ff..3878035c291a6 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 @@ -65,8 +65,9 @@ public AuthToken issueOnBehalfOfToken(Subject subject, OnBehalfOfClaims claims) String password = generatePassword(); final byte[] rawEncoded = Base64.getUrlEncoder().encode((claims.getAudience() + ":" + password).getBytes(UTF_8)); // Make a new - // ShiroSubject w/ - // audience as name + // ShiroSubject w/ + // audience as + // name final String usernamePassword = new String(rawEncoded, UTF_8); final String header = "Basic " + usernamePassword; BasicAuthToken token = new BasicAuthToken(header); From 187c06dd942dea08aa001c1c7ee5074e10f395b2 Mon Sep 17 00:00:00 2001 From: Stephen Crawford <65832608+scrawfor99@users.noreply.github.com> Date: Thu, 14 Sep 2023 14:11:34 -0400 Subject: [PATCH 16/22] Update server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java Co-authored-by: Owais Kazi Signed-off-by: Stephen Crawford <65832608+scrawfor99@users.noreply.github.com> --- .../extensions/action/IssueServiceAccountResponse.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java b/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java index 78e41f1806e9e..f02bd88fdae9c 100644 --- a/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java +++ b/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java @@ -56,7 +56,7 @@ public String getName() { return this.name; } - public String getServiceAccountString() { + public String getServiceAccount() { return this.serviceAccountToken; } From 4228df08358494d6949849bb6dcca72430203f5e Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Thu, 14 Sep 2023 14:14:54 -0400 Subject: [PATCH 17/22] Owais' feedback Signed-off-by: Stephen Crawford --- .../org/opensearch/identity/shiro/ShiroTokenManager.java | 7 +++---- .../java/org/opensearch/extensions/ExtensionsManager.java | 2 +- .../extensions/action/IssueServiceAccountResponse.java | 2 +- .../action/IssueServiceAccountResponseTests.java | 4 ++-- 4 files changed, 7 insertions(+), 8 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 3878035c291a6..ddfb99e626718 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 @@ -64,10 +64,9 @@ public Optional translateAuthToken(org.opensearch.identity. public AuthToken issueOnBehalfOfToken(Subject subject, OnBehalfOfClaims claims) { String password = generatePassword(); - final byte[] rawEncoded = Base64.getUrlEncoder().encode((claims.getAudience() + ":" + password).getBytes(UTF_8)); // Make a new - // ShiroSubject w/ - // audience as - // name + // Make a new ShiroSubject audience as name + final byte[] rawEncoded = Base64.getUrlEncoder().encode((claims.getAudience() + ":" + 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/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java b/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java index 7b33775ce021e..98121afed83ea 100644 --- a/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java +++ b/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java @@ -470,7 +470,7 @@ public IssueServiceAccountResponse read(StreamInput in) throws IOException { public void handleResponse(IssueServiceAccountResponse response) { for (DiscoveryExtensionNode extension : extensionIdMap.values()) { if (extension.getName().equals(response.getName()) - && (serviceAccountToken.equals(response.getServiceAccountString()))) { + && (serviceAccountToken.equals(response.getServiceAccount()))) { logger.info("Successfully issued service account token to extension: " + extension.getName()); break; } diff --git a/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java b/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java index f02bd88fdae9c..8f292961ccdcd 100644 --- a/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java +++ b/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java @@ -62,7 +62,7 @@ public String getServiceAccount() { @Override public String toString() { - return "IssueServiceAccountResponse{" + "name = " + name + " , " + "received service account = " + serviceAccountToken + "}"; + return "IssueServiceAccountResponse{" + "name = " + name + " , " + "received a service account." + "}"; } @Override diff --git a/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountResponseTests.java b/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountResponseTests.java index 5e73dbceb83be..51669666f5f34 100644 --- a/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountResponseTests.java +++ b/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountResponseTests.java @@ -21,14 +21,14 @@ public void testIssueServiceAccountResponse() throws Exception { IssueServiceAccountResponse response = new IssueServiceAccountResponse(extensionName, serviceAccountToken); assertEquals(extensionName, response.getName()); - assertEquals(serviceAccountToken, response.getServiceAccountString()); + assertEquals(serviceAccountToken, response.getServiceAccount()); BytesStreamOutput out = new BytesStreamOutput(); response.writeTo(out); BytesStreamInput in = new BytesStreamInput(BytesReference.toBytes(out.bytes())); response = new IssueServiceAccountResponse(in); assertEquals(extensionName, response.getName()); - assertEquals(serviceAccountToken, response.getServiceAccountString()); + assertEquals(serviceAccountToken, response.getServiceAccount()); IssueServiceAccountResponse response2 = new IssueServiceAccountResponse(extensionName, serviceAccountToken); From 266f3af9b91b5f83cf47be1a22e0e0da315f4ea0 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Thu, 14 Sep 2023 15:52:24 -0400 Subject: [PATCH 18/22] spotless Signed-off-by: Stephen Crawford --- .../main/java/org/opensearch/extensions/ExtensionsManager.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java b/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java index 98121afed83ea..a913f4f31e106 100644 --- a/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java +++ b/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java @@ -469,8 +469,7 @@ public IssueServiceAccountResponse read(StreamInput in) throws IOException { @Override public void handleResponse(IssueServiceAccountResponse response) { for (DiscoveryExtensionNode extension : extensionIdMap.values()) { - if (extension.getName().equals(response.getName()) - && (serviceAccountToken.equals(response.getServiceAccount()))) { + if (extension.getName().equals(response.getName()) && (serviceAccountToken.equals(response.getServiceAccount()))) { logger.info("Successfully issued service account token to extension: " + extension.getName()); break; } From f3411461e313cf1f0689901c9ed8f0579d350a83 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Thu, 14 Sep 2023 17:33:14 -0400 Subject: [PATCH 19/22] Fix test Signed-off-by: Stephen Crawford --- .../extensions/action/IssueServiceAccountResponse.java | 2 +- .../extensions/action/IssueServiceAccountResponseTests.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java b/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java index 8f292961ccdcd..e84c277276c76 100644 --- a/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java +++ b/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java @@ -62,7 +62,7 @@ public String getServiceAccount() { @Override public String toString() { - return "IssueServiceAccountResponse{" + "name = " + name + " , " + "received a service account." + "}"; + return "IssueServiceAccountResponse{" + "name = " + name + ", " + "received a service account." + "}"; } @Override diff --git a/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountResponseTests.java b/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountResponseTests.java index 51669666f5f34..b9da4ac52e5d0 100644 --- a/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountResponseTests.java +++ b/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountResponseTests.java @@ -36,7 +36,7 @@ public void testIssueServiceAccountResponse() throws Exception { assertEquals(response.hashCode(), response2.hashCode()); assertEquals( response.toString(), - "IssueServiceAccountResponse{" + "name = " + extensionName + " , " + "received service account = " + serviceAccountToken + "}" + "IssueServiceAccountResponse{" + "name = " + extensionName + ", " + "received a service account." + "}" ); } } From caae0796cfe74438d1ff0ee0c9746949f701f179 Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Tue, 19 Sep 2023 16:19:27 -0400 Subject: [PATCH 20/22] move into initialize Signed-off-by: Stephen Crawford --- .../discovery/InitializeExtensionRequest.java | 14 +++- .../extensions/ExtensionsManager.java | 51 ++---------- .../action/IssueServiceAccountRequest.java | 69 ---------------- .../action/IssueServiceAccountResponse.java | 81 ------------------- .../rest/RestInitializeExtensionAction.java | 1 - .../InitializeExtensionRequestTests.java | 9 ++- .../IssueServiceAccountRequestTests.java | 37 --------- .../IssueServiceAccountResponseTests.java | 42 ---------- 8 files changed, 25 insertions(+), 279 deletions(-) delete mode 100644 server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountRequest.java delete mode 100644 server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java delete mode 100644 server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountRequestTests.java delete mode 100644 server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountResponseTests.java diff --git a/server/src/main/java/org/opensearch/discovery/InitializeExtensionRequest.java b/server/src/main/java/org/opensearch/discovery/InitializeExtensionRequest.java index 33cdad3045780..6e9fb8b7201a4 100644 --- a/server/src/main/java/org/opensearch/discovery/InitializeExtensionRequest.java +++ b/server/src/main/java/org/opensearch/discovery/InitializeExtensionRequest.java @@ -25,16 +25,19 @@ public class InitializeExtensionRequest extends TransportRequest { private final DiscoveryNode sourceNode; private final DiscoveryExtensionNode extension; + private final String serviceAccountHeader; - public InitializeExtensionRequest(DiscoveryNode sourceNode, DiscoveryExtensionNode extension) { + public InitializeExtensionRequest(DiscoveryNode sourceNode, DiscoveryExtensionNode extension, String serviceAccountHeader) { this.sourceNode = sourceNode; this.extension = extension; + this.serviceAccountHeader = serviceAccountHeader; } public InitializeExtensionRequest(StreamInput in) throws IOException { super(in); sourceNode = new DiscoveryNode(in); extension = new DiscoveryExtensionNode(in); + serviceAccountHeader = in.readString(); } @Override @@ -42,6 +45,7 @@ public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); sourceNode.writeTo(out); extension.writeTo(out); + out.writeString(serviceAccountHeader); } public DiscoveryNode getSourceNode() { @@ -52,6 +56,10 @@ public DiscoveryExtensionNode getExtension() { return extension; } + public String getServiceAccountHeader() { + return serviceAccountHeader; + } + @Override public String toString() { return "InitializeExtensionsRequest{" + "sourceNode=" + sourceNode + ", extension=" + extension + '}'; @@ -62,7 +70,9 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; InitializeExtensionRequest that = (InitializeExtensionRequest) o; - return Objects.equals(sourceNode, that.sourceNode) && Objects.equals(extension, that.extension); + return Objects.equals(sourceNode, that.sourceNode) + && Objects.equals(extension, that.extension) + && Objects.equals(serviceAccountHeader, that.getServiceAccountHeader()); } @Override diff --git a/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java b/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java index a913f4f31e106..86762687c5823 100644 --- a/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java +++ b/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java @@ -33,8 +33,6 @@ import org.opensearch.extensions.action.ExtensionActionRequest; import org.opensearch.extensions.action.ExtensionActionResponse; import org.opensearch.extensions.action.ExtensionTransportActionsHandler; -import org.opensearch.extensions.action.IssueServiceAccountRequest; -import org.opensearch.extensions.action.IssueServiceAccountResponse; import org.opensearch.extensions.action.RegisterTransportActionsRequest; import org.opensearch.extensions.action.RemoteExtensionActionResponse; import org.opensearch.extensions.action.TransportActionRequestFromExtension; @@ -406,7 +404,7 @@ protected void doRun() throws Exception { transportService.sendRequest( extension, REQUEST_EXTENSION_ACTION_NAME, - new InitializeExtensionRequest(transportService.getLocalNode(), extension), + new InitializeExtensionRequest(transportService.getLocalNode(), extension, issueServiceAccount(extension)), initializeExtensionResponseHandler ); } @@ -450,51 +448,12 @@ TransportResponse handleExtensionRequest(ExtensionRequest extensionRequest) thro } /** - * A separate transport action handler used to issue service accounts to extensions during initialization + * A helper method called during initialization that issues a service accounts to extensions * @param extension The extension to be issued a service account */ - public void issueServiceAccount(Extension extension) { - DiscoveryExtensionNode discoveryExtensionNode = extensionIdMap.get(extension.getUniqueId()); - AuthToken serviceAccountToken = identityService.getTokenManager().issueServiceAccountToken(extension.getUniqueId()); - String authTokenAsString = serviceAccountToken.asAuthHeaderValue(); - final CompletableFuture inProgressFuture = new CompletableFuture<>(); - final TransportResponseHandler issueServiceAccountResponseHandler = new TransportResponseHandler< - IssueServiceAccountResponse>() { - - @Override - public IssueServiceAccountResponse read(StreamInput in) throws IOException { - return new IssueServiceAccountResponse(in); - } - - @Override - public void handleResponse(IssueServiceAccountResponse response) { - for (DiscoveryExtensionNode extension : extensionIdMap.values()) { - if (extension.getName().equals(response.getName()) && (serviceAccountToken.equals(response.getServiceAccount()))) { - logger.info("Successfully issued service account token to extension: " + extension.getName()); - break; - } - } - inProgressFuture.complete(response); - } - - @Override - public void handleException(TransportException exp) { - logger.error(new ParameterizedMessage("Issuance of service account token failed"), exp); - inProgressFuture.completeExceptionally(exp); - } - - @Override - public String executor() { - return ThreadPool.Names.GENERIC; - } - }; - - transportService.sendRequest( - discoveryExtensionNode, - REQUEST_EXTENSION_ISSUE_SERVICE_ACCOUNT, - new IssueServiceAccountRequest(authTokenAsString), - issueServiceAccountResponseHandler - ); + public String issueServiceAccount(DiscoveryExtensionNode extension) { + AuthToken serviceAccountToken = identityService.getTokenManager().issueServiceAccountToken(extension.getId()); + return serviceAccountToken.asAuthHeaderValue(); } static String getRequestExtensionActionName() { diff --git a/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountRequest.java b/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountRequest.java deleted file mode 100644 index 7d152a33e800a..0000000000000 --- a/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountRequest.java +++ /dev/null @@ -1,69 +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.extensions.action; - -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.core.common.io.stream.StreamOutput; -import org.opensearch.transport.TransportRequest; - -import java.io.IOException; -import java.util.Objects; - -/** - * This class represents a Transport Request for issuing a service account to an extension. - */ -public class IssueServiceAccountRequest extends TransportRequest { - - private final String serviceAccountToken; - - /** - * This takes a string representing a service account token - * @param serviceAccountToken The string making up the service account token - */ - public IssueServiceAccountRequest(String serviceAccountToken) { - this.serviceAccountToken = serviceAccountToken; - } - - /** - * This takes a stream representing a service account token - * @param in The stream passing the token - */ - public IssueServiceAccountRequest(StreamInput in) throws IOException { - super(in); - this.serviceAccountToken = in.readString(); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeString(serviceAccountToken); - } - - public String getServiceAccountToken() { - return this.serviceAccountToken; - } - - @Override - public String toString() { - return "IssueServiceAccountRequest {" + "serviceAccountToken=" + serviceAccountToken + "}"; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - IssueServiceAccountRequest that = (IssueServiceAccountRequest) o; - return Objects.equals(serviceAccountToken, that.serviceAccountToken); - } - - @Override - public int hashCode() { - return Objects.hash(serviceAccountToken); - } -} diff --git a/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java b/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java deleted file mode 100644 index e84c277276c76..0000000000000 --- a/server/src/main/java/org/opensearch/extensions/action/IssueServiceAccountResponse.java +++ /dev/null @@ -1,81 +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.extensions.action; - -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.core.common.io.stream.StreamOutput; -import org.opensearch.core.transport.TransportResponse; - -import java.io.IOException; -import java.util.Objects; - -/** - * This class represents a Transport Request for issuing a service account to an extension. - */ -public class IssueServiceAccountResponse extends TransportResponse { - - private String name; - private String serviceAccountToken; - - /** - * This takes in a name for the extension and the service account token string - * @param name The name of the extension - * @param serviceAccountToken A string encapsulating the service account token - */ - public IssueServiceAccountResponse(String name, String serviceAccountToken) { - this.name = name; - this.serviceAccountToken = serviceAccountToken; - } - - /** - * This takes in a stream containing for the extension and the service account token - * @param in the stream containing the extension name and the service account token - */ - public IssueServiceAccountResponse(StreamInput in) throws IOException { - this.name = in.readString(); - this.serviceAccountToken = in.readString(); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - out.writeString(name); - out.writeString(serviceAccountToken); - } - - /** - * @return the node that is currently leading, according to the responding node. - */ - - public String getName() { - return this.name; - } - - public String getServiceAccount() { - return this.serviceAccountToken; - } - - @Override - public String toString() { - return "IssueServiceAccountResponse{" + "name = " + name + ", " + "received a service account." + "}"; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - IssueServiceAccountResponse that = (IssueServiceAccountResponse) o; - return Objects.equals(name, that.name) && Objects.equals(serviceAccountToken, that.serviceAccountToken); - } - - @Override - public int hashCode() { - return Objects.hash(name, serviceAccountToken); - } - -} diff --git a/server/src/main/java/org/opensearch/extensions/rest/RestInitializeExtensionAction.java b/server/src/main/java/org/opensearch/extensions/rest/RestInitializeExtensionAction.java index bf81ead212043..4b622b841a040 100644 --- a/server/src/main/java/org/opensearch/extensions/rest/RestInitializeExtensionAction.java +++ b/server/src/main/java/org/opensearch/extensions/rest/RestInitializeExtensionAction.java @@ -161,7 +161,6 @@ public RestChannelConsumer prepareRequest(RestRequest request, NodeClient client try { extensionsManager.loadExtension(extension); extensionsManager.initialize(); - extensionsManager.issueServiceAccount(extension); } catch (CompletionException e) { Throwable cause = e.getCause(); if (cause instanceof TimeoutException) { diff --git a/server/src/test/java/org/opensearch/discovery/InitializeExtensionRequestTests.java b/server/src/test/java/org/opensearch/discovery/InitializeExtensionRequestTests.java index ca94a3b52a56c..daa42d3abbc50 100644 --- a/server/src/test/java/org/opensearch/discovery/InitializeExtensionRequestTests.java +++ b/server/src/test/java/org/opensearch/discovery/InitializeExtensionRequestTests.java @@ -27,6 +27,7 @@ public class InitializeExtensionRequestTests extends OpenSearchTestCase { public void testInitializeExtensionRequest() throws Exception { String expectedUniqueId = "test uniqueid"; Version expectedVersion = Version.fromString("2.0.0"); + String expectedServiceAccountHeader = "test"; ExtensionDependency expectedDependency = new ExtensionDependency(expectedUniqueId, expectedVersion); DiscoveryExtensionNode expectedExtensionNode = new DiscoveryExtensionNode( "firstExtension", @@ -46,9 +47,14 @@ public void testInitializeExtensionRequest() throws Exception { Version.CURRENT ); - InitializeExtensionRequest initializeExtensionRequest = new InitializeExtensionRequest(expectedSourceNode, expectedExtensionNode); + InitializeExtensionRequest initializeExtensionRequest = new InitializeExtensionRequest( + expectedSourceNode, + expectedExtensionNode, + expectedServiceAccountHeader + ); assertEquals(expectedExtensionNode, initializeExtensionRequest.getExtension()); assertEquals(expectedSourceNode, initializeExtensionRequest.getSourceNode()); + assertEquals(expectedServiceAccountHeader, initializeExtensionRequest.getServiceAccountHeader()); try (BytesStreamOutput out = new BytesStreamOutput()) { initializeExtensionRequest.writeTo(out); @@ -58,6 +64,7 @@ public void testInitializeExtensionRequest() throws Exception { assertEquals(expectedExtensionNode, initializeExtensionRequest.getExtension()); assertEquals(expectedSourceNode, initializeExtensionRequest.getSourceNode()); + assertEquals(expectedServiceAccountHeader, initializeExtensionRequest.getServiceAccountHeader()); } } } diff --git a/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountRequestTests.java b/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountRequestTests.java deleted file mode 100644 index 947c17f488112..0000000000000 --- a/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountRequestTests.java +++ /dev/null @@ -1,37 +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.extensions.action; - -import org.opensearch.common.io.stream.BytesStreamOutput; -import org.opensearch.core.common.bytes.BytesReference; -import org.opensearch.core.common.io.stream.BytesStreamInput; -import org.opensearch.test.OpenSearchTestCase; - -public class IssueServiceAccountRequestTests extends OpenSearchTestCase { - - public void testIssueServiceAccountRequest() throws Exception { - String serviceAccountToken = "testToken"; - IssueServiceAccountRequest request = new IssueServiceAccountRequest(serviceAccountToken); - - assertEquals(serviceAccountToken, request.getServiceAccountToken()); - - BytesStreamOutput out = new BytesStreamOutput(); - request.writeTo(out); - BytesStreamInput in = new BytesStreamInput(BytesReference.toBytes(out.bytes())); - request = new IssueServiceAccountRequest(in); - - assertEquals(serviceAccountToken, request.getServiceAccountToken()); - - IssueServiceAccountRequest request2 = new IssueServiceAccountRequest(serviceAccountToken); - - assertEquals(request, request2); - assertEquals(request.hashCode(), request2.hashCode()); - assertEquals(request.toString(), "IssueServiceAccountRequest {" + "serviceAccountToken=" + serviceAccountToken + "}"); - } -} diff --git a/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountResponseTests.java b/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountResponseTests.java deleted file mode 100644 index b9da4ac52e5d0..0000000000000 --- a/server/src/test/java/org/opensearch/extensions/action/IssueServiceAccountResponseTests.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.extensions.action; - -import org.opensearch.common.io.stream.BytesStreamOutput; -import org.opensearch.core.common.bytes.BytesReference; -import org.opensearch.core.common.io.stream.BytesStreamInput; -import org.opensearch.test.OpenSearchTestCase; - -public class IssueServiceAccountResponseTests extends OpenSearchTestCase { - - public void testIssueServiceAccountResponse() throws Exception { - String extensionName = "testExtension"; - String serviceAccountToken = "testToken"; - IssueServiceAccountResponse response = new IssueServiceAccountResponse(extensionName, serviceAccountToken); - - assertEquals(extensionName, response.getName()); - assertEquals(serviceAccountToken, response.getServiceAccount()); - - BytesStreamOutput out = new BytesStreamOutput(); - response.writeTo(out); - BytesStreamInput in = new BytesStreamInput(BytesReference.toBytes(out.bytes())); - response = new IssueServiceAccountResponse(in); - assertEquals(extensionName, response.getName()); - assertEquals(serviceAccountToken, response.getServiceAccount()); - - IssueServiceAccountResponse response2 = new IssueServiceAccountResponse(extensionName, serviceAccountToken); - - assertEquals(response, response2); - assertEquals(response.hashCode(), response2.hashCode()); - assertEquals( - response.toString(), - "IssueServiceAccountResponse{" + "name = " + extensionName + ", " + "received a service account." + "}" - ); - } -} From c6de74d6e1fa9d5fad3ffe2f6300f71c3347976b Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Wed, 20 Sep 2023 10:03:08 -0400 Subject: [PATCH 21/22] fix flaky test Signed-off-by: Stephen Crawford --- .../java/org/opensearch/identity/tokens/BasicAuthToken.java | 2 +- .../extensions/rest/RestInitializeExtensionActionTests.java | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) 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 71b8fe504a5d1..4ad0bbe67d2a1 100644 --- a/server/src/main/java/org/opensearch/identity/tokens/BasicAuthToken.java +++ b/server/src/main/java/org/opensearch/identity/tokens/BasicAuthToken.java @@ -23,7 +23,7 @@ public final class BasicAuthToken implements AuthToken { public BasicAuthToken(final String headerValue) { final String base64Encoded = headerValue.substring(TOKEN_IDENTIFIER.length()).trim(); - final byte[] rawDecoded = Base64.getDecoder().decode(base64Encoded); + final byte[] rawDecoded = Base64.getUrlDecoder().decode(base64Encoded); final String usernamepassword = new String(rawDecoded, StandardCharsets.UTF_8); final String[] tokenParts = usernamepassword.split(":", 2); diff --git a/server/src/test/java/org/opensearch/extensions/rest/RestInitializeExtensionActionTests.java b/server/src/test/java/org/opensearch/extensions/rest/RestInitializeExtensionActionTests.java index 814baca1972b5..cdddf8e9be1be 100644 --- a/server/src/test/java/org/opensearch/extensions/rest/RestInitializeExtensionActionTests.java +++ b/server/src/test/java/org/opensearch/extensions/rest/RestInitializeExtensionActionTests.java @@ -47,7 +47,6 @@ import static java.util.Collections.emptyMap; import static java.util.Collections.emptySet; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; @@ -161,7 +160,6 @@ public void testRestInitializeExtensionActionResponseWithAdditionalSettings() th // optionally, you can stub out some methods: when(spy.getAdditionalSettings()).thenCallRealMethod(); - doNothing().when(spy).issueServiceAccount(any()); Mockito.doCallRealMethod().when(spy).loadExtension(any(ExtensionsSettings.Extension.class)); Mockito.doNothing().when(spy).initialize(); RestInitializeExtensionAction restInitializeExtensionAction = new RestInitializeExtensionAction(spy); @@ -212,7 +210,6 @@ public void testRestInitializeExtensionActionResponseWithAdditionalSettingsUsing // optionally, you can stub out some methods: when(spy.getAdditionalSettings()).thenCallRealMethod(); - doNothing().when(spy).issueServiceAccount(any()); Mockito.doCallRealMethod().when(spy).loadExtension(any(ExtensionsSettings.Extension.class)); Mockito.doNothing().when(spy).initialize(); RestInitializeExtensionAction restInitializeExtensionAction = new RestInitializeExtensionAction(spy); From 0415f58dbd9592fa0ac80e5669d6e76eba9f7cbc Mon Sep 17 00:00:00 2001 From: Stephen Crawford Date: Thu, 21 Sep 2023 10:01:36 -0400 Subject: [PATCH 22/22] final changes Signed-off-by: Stephen Crawford --- CHANGELOG.md | 11 +++++++++-- .../org/opensearch/extensions/ExtensionsManager.java | 3 +-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d4d4d14ae92d..9973bf7dbca91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,8 +11,6 @@ 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)) - Introduce new dynamic cluster setting to control slice computation for concurrent segment search ([#9107](https://github.com/opensearch-project/OpenSearch/pull/9107)) - Implement on behalf of token passing for extensions ([#8679](https://github.com/opensearch-project/OpenSearch/pull/8679)) -- Added encryption-sdk lib to provide encryption and decryption capabilities ([#8466](https://github.com/opensearch-project/OpenSearch/pull/8466)) -- Added crypto-kms plugin to provide AWS KMS based key providers for encryption/decryption. ([#8465](https://github.com/opensearch-project/OpenSearch/pull/8465)) - Implement service account issuance and fetching for extensions ([#9618](https://github.com/opensearch-project/OpenSearch/pull/9618)) ### Dependencies @@ -44,6 +42,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Bump `org.bouncycastle:bcmail-jdk15on` to `org.bouncycastle:bcmail-jdk15to18` version 1.75 ([#8247](https://github.com/opensearch-project/OpenSearch/pull/8247)) - Bump `org.bouncycastle:bcpkix-jdk15on` to `org.bouncycastle:bcpkix-jdk15to18` version 1.75 ([#8247](https://github.com/opensearch-project/OpenSearch/pull/8247)) - Bump JNA version from 5.5 to 5.13 ([#9963](https://github.com/opensearch-project/OpenSearch/pull/9963)) +- Bumps jetty version to 9.4.52.v20230823 to fix GMS-2023-1857 ([#9822](https://github.com/opensearch-project/OpenSearch/pull/9822)) +- Bump `org.eclipse.jgit` from 6.5.0 to 6.7.0 ([#10147](https://github.com/opensearch-project/OpenSearch/pull/10147)) ### Changed - [CCR] Add getHistoryOperationsFromTranslog method to fetch the history snapshot from translogs ([#3948](https://github.com/opensearch-project/OpenSearch/pull/3948)) @@ -80,7 +80,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased 2.x] ### Added +- Add coordinator level stats for search latency ([#8386](https://github.com/opensearch-project/OpenSearch/issues/8386)) - Add metrics for thread_pool task wait time ([#9681](https://github.com/opensearch-project/OpenSearch/pull/9681)) +- Async blob read support for S3 plugin ([#9694](https://github.com/opensearch-project/OpenSearch/pull/9694)) ### Dependencies - Bump `peter-evans/create-or-update-comment` from 2 to 3 ([#9575](https://github.com/opensearch-project/OpenSearch/pull/9575)) @@ -90,11 +92,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Bump `com.google.cloud:google-cloud-core-http` from 2.21.1 to 2.23.0 ([#9971](https://github.com/opensearch-project/OpenSearch/pull/9971)) - Bump `mockito` from 5.4.0 to 5.5.0 ([#10022](https://github.com/opensearch-project/OpenSearch/pull/10022)) - Bump `bytebuddy` from 1.14.3 to 1.14.7 ([#10022](https://github.com/opensearch-project/OpenSearch/pull/10022)) +- Bump `com.zaxxer:SparseBitSet` from 1.2 to 1.3 ([#10098](https://github.com/opensearch-project/OpenSearch/pull/10098)) +- Bump `tibdex/github-app-token` from 1.5.0 to 2.1.0 ([#10125](https://github.com/opensearch-project/OpenSearch/pull/10125)) +- Bump `org.wiremock:wiremock-standalone` from 2.35.0 to 3.1.0 ([#9752](https://github.com/opensearch-project/OpenSearch/pull/9752)) ### Changed - Add instrumentation in rest and network layer. ([#9415](https://github.com/opensearch-project/OpenSearch/pull/9415)) - Allow parameterization of tests with OpenSearchIntegTestCase.SuiteScopeTestCase annotation ([#9916](https://github.com/opensearch-project/OpenSearch/pull/9916)) - Mute the query profile IT with concurrent execution ([#9840](https://github.com/opensearch-project/OpenSearch/pull/9840)) +- Add instrumentation in transport service. ([#10042](https://github.com/opensearch-project/OpenSearch/pull/10042)) ### Deprecated @@ -102,6 +108,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Fixed - Fix ignore_missing parameter has no effect when using template snippet in rename ingest processor ([#9725](https://github.com/opensearch-project/OpenSearch/pull/9725)) +- Fix broken backward compatibility from 2.7 for IndexSorted field indices ([#10045](https://github.com/opensearch-project/OpenSearch/pull/9725)) ### Security diff --git a/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java b/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java index 86762687c5823..9f9ba548143c6 100644 --- a/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java +++ b/server/src/main/java/org/opensearch/extensions/ExtensionsManager.java @@ -77,7 +77,6 @@ public class ExtensionsManager { public static final String REQUEST_REST_EXECUTE_ON_EXTENSION_ACTION = "internal:extensions/restexecuteonextensiontaction"; public static final String REQUEST_EXTENSION_HANDLE_TRANSPORT_ACTION = "internal:extensions/handle-transportaction"; public static final String REQUEST_EXTENSION_HANDLE_REMOTE_TRANSPORT_ACTION = "internal:extensions/handle-remote-transportaction"; - public static final String REQUEST_EXTENSION_ISSUE_SERVICE_ACCOUNT = "internal:extensions/issue-service-account"; public static final String TRANSPORT_ACTION_REQUEST_FROM_EXTENSION = "internal:extensions/request-transportaction-from-extension"; public static final int EXTENSION_REQUEST_WAIT_TIMEOUT = 10; private static final Logger logger = LogManager.getLogger(ExtensionsManager.class); @@ -451,7 +450,7 @@ TransportResponse handleExtensionRequest(ExtensionRequest extensionRequest) thro * A helper method called during initialization that issues a service accounts to extensions * @param extension The extension to be issued a service account */ - public String issueServiceAccount(DiscoveryExtensionNode extension) { + private String issueServiceAccount(DiscoveryExtensionNode extension) { AuthToken serviceAccountToken = identityService.getTokenManager().issueServiceAccountToken(extension.getId()); return serviceAccountToken.asAuthHeaderValue(); }