Skip to content

Commit

Permalink
expand coverage
Browse files Browse the repository at this point in the history
Signed-off-by: Stephen Crawford <[email protected]>
  • Loading branch information
stephen-crawford committed Jan 12, 2024
1 parent 2f784e5 commit 1ff11fa
Showing 1 changed file with 205 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import org.opensearch.transport.Transport.Connection;
import org.opensearch.transport.TransportInterceptor.AsyncSender;
import org.opensearch.transport.TransportRequest;
import org.opensearch.transport.TransportRequestHandler;
import org.opensearch.transport.TransportRequestOptions;
import org.opensearch.transport.TransportResponseHandler;
import org.opensearch.transport.TransportService;
Expand All @@ -51,6 +52,8 @@

import static java.util.Collections.emptySet;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

Expand Down Expand Up @@ -115,22 +118,22 @@ private void testSendRequestDecorate(Version remoteNodeVersion) {

MockTransport transport = new MockTransport();
TransportService transportService = transport.createTransportService(
Settings.EMPTY,
threadPool,
TransportService.NOOP_TRANSPORT_INTERCEPTOR,
boundTransportAddress -> clusterService.state().nodes().get(SecurityInterceptor.class.getSimpleName()),
null,
emptySet(),
NoopTracer.INSTANCE
Settings.EMPTY,
threadPool,
TransportService.NOOP_TRANSPORT_INTERCEPTOR,
boundTransportAddress -> clusterService.state().nodes().get(SecurityInterceptor.class.getSimpleName()),
null,
emptySet(),
NoopTracer.INSTANCE
);

// CS-SUPPRESS-SINGLE: RegexpSingleline Extensions manager used for creating a mock
OpenSearchSecurityPlugin.GuiceHolder guiceHolder = new OpenSearchSecurityPlugin.GuiceHolder(
mock(RepositoriesService.class),
transportService,
mock(IndicesService.class),
mock(PitService.class),
mock(ExtensionsManager.class)
mock(RepositoriesService.class),
transportService,
mock(IndicesService.class),
mock(PitService.class),
mock(ExtensionsManager.class)
);
// CS-ENFORCE-SINGLE

Expand Down Expand Up @@ -168,11 +171,11 @@ private void testSendRequestDecorate(Version remoteNodeVersion) {
AsyncSender sender = new AsyncSender() {
@Override
public <T extends TransportResponse> void sendRequest(
Connection connection,
String action,
TransportRequest request,
TransportRequestOptions options,
TransportResponseHandler<T> handler
Connection connection,
String action,
TransportRequest request,
TransportRequestOptions options,
TransportResponseHandler<T> handler
) {
User transientUser = threadPool.getThreadContext().getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER);
assertEquals(transientUser, user);
Expand All @@ -191,11 +194,11 @@ public <T extends TransportResponse> void sendRequest(
sender = new AsyncSender() {
@Override
public <T extends TransportResponse> void sendRequest(
Connection connection,
String action,
TransportRequest request,
TransportRequestOptions options,
TransportResponseHandler<T> handler
Connection connection,
String action,
TransportRequest request,
TransportRequestOptions options,
TransportResponseHandler<T> handler
) {
User transientUser = threadPool.getThreadContext().getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER);
assertEquals(transientUser, user);
Expand All @@ -214,11 +217,11 @@ public <T extends TransportResponse> void sendRequest(
sender = new AsyncSender() {
@Override
public <T extends TransportResponse> void sendRequest(
Connection connection,
String action,
TransportRequest request,
TransportRequestOptions options,
TransportResponseHandler<T> handler
Connection connection,
String action,
TransportRequest request,
TransportRequestOptions options,
TransportResponseHandler<T> handler
) {
String serializedUserHeader = threadPool.getThreadContext().getHeader(ConfigConstants.OPENDISTRO_SECURITY_USER_HEADER);
assertEquals(serializedUserHeader, Base64Helper.serializeObject(user, useJDKSerialization));
Expand All @@ -237,11 +240,11 @@ public <T extends TransportResponse> void sendRequest(
sender = new AsyncSender() {
@Override
public <T extends TransportResponse> void sendRequest(
Connection connection,
String action,
TransportRequest request,
TransportRequestOptions options,
TransportResponseHandler<T> handler
Connection connection,
String action,
TransportRequest request,
TransportRequestOptions options,
TransportResponseHandler<T> handler
) {
String serializedUserHeader = threadPool.getThreadContext().getHeader(ConfigConstants.OPENDISTRO_SECURITY_USER_HEADER);
assertEquals(serializedUserHeader, Base64Helper.serializeObject(user, useJDKSerialization));
Expand All @@ -255,6 +258,172 @@ public <T extends TransportResponse> void sendRequest(
User transientUser4 = threadPool.getThreadContext().getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER);
assertEquals(transientUser4, user);
assertEquals(threadPool.getThreadContext().getHeader(ConfigConstants.OPENDISTRO_SECURITY_USER_HEADER), null);

// checking thread context inside sendRequestDecorate for connection1 with null local node -- we should serialize this
sender = new AsyncSender() {
@Override
public <T extends TransportResponse> void sendRequest(
Connection connection,
String action,
TransportRequest request,
TransportRequestOptions options,
TransportResponseHandler<T> handler
) {
String serializedUserHeader = threadPool.getThreadContext().getHeader(ConfigConstants.OPENDISTRO_SECURITY_USER_HEADER);
assertEquals(serializedUserHeader, Base64Helper.serializeObject(user, useJDKSerialization));
}
};

// this is a request where the local node is null; have to use the remote connection since the serialization will fail
securityInterceptor.sendRequestDecorate(sender, connection3, action, request, options, handler, null);

// from original context
User transientUser5 = threadPool.getThreadContext().getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER);
assertEquals(transientUser5, user);
assertEquals(threadPool.getThreadContext().getHeader(ConfigConstants.OPENDISTRO_SECURITY_USER_HEADER), null);

// test sending various missing decorates with missing request info


// checking thread context inside sendRequestDecorate
sender = new AsyncSender() {
@Override
public <T extends TransportResponse> void sendRequest(
Connection connection,
String action,
TransportRequest request,
TransportRequestOptions options,
TransportResponseHandler<T> handler
) {
User transientUser = threadPool.getThreadContext().getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER);
assertEquals(transientUser, user);
}
};

// Having null connection will cause useJDKSerialization to throw npe
AsyncSender finalSender = sender; // Have to do this because of being a runnable
assertThrows(java.lang.NullPointerException.class, () -> securityInterceptor.sendRequestDecorate(finalSender, null, action, request, options, handler, localNode));

// Make the origin null should cause the ensureCorrectHeaders method to populate with Origin.LOCAL.toString()
threadPool.getThreadContext().putHeader(ConfigConstants.OPENDISTRO_SECURITY_ORIGIN, null);


}

private void testSendRequestDecorateWithEmptyUserHeader(Version remoteNodeVersion) {
ClusterName clusterName = ClusterName.DEFAULT;
when(clusterService.getClusterName()).thenReturn(clusterName);

MockTransport transport = new MockTransport();
TransportService transportService = transport.createTransportService(
Settings.EMPTY,
threadPool,
TransportService.NOOP_TRANSPORT_INTERCEPTOR,
boundTransportAddress -> clusterService.state().nodes().get(SecurityInterceptor.class.getSimpleName()),
null,
emptySet(),
NoopTracer.INSTANCE
);

// Add a fake header to show it does not get misinterpreted
threadPool.getThreadContext().putHeader("FAKE_HEADER", "fake_value");

// Add a null header
threadPool.getThreadContext().putHeader(null, null);
threadPool.getThreadContext().putHeader(null, "null");

// Add the other headers we check
threadPool.getThreadContext().putHeader(ConfigConstants.OPENDISTRO_SECURITY_CONF_REQUEST_HEADER, "fake security config request header");
threadPool.getThreadContext().putHeader(ConfigConstants.OPENDISTRO_SECURITY_ORIGIN_HEADER, "fake security origin header");
threadPool.getThreadContext().putHeader(ConfigConstants.OPENDISTRO_SECURITY_REMOTE_ADDRESS_HEADER, "fake security remote address header");
threadPool.getThreadContext().putHeader(ConfigConstants.OPENDISTRO_SECURITY_DLS_QUERY_HEADER, "fake dls query header");
threadPool.getThreadContext().putHeader(ConfigConstants.OPENDISTRO_SECURITY_FLS_FIELDS_HEADER, "fake fls fields header");
threadPool.getThreadContext().putHeader(ConfigConstants.OPENDISTRO_SECURITY_MASKED_FIELD_HEADER, "fake masked field header");
threadPool.getThreadContext().putHeader(ConfigConstants.OPENDISTRO_SECURITY_DOC_ALLOWLIST_HEADER, "fake doc allowlist header");
threadPool.getThreadContext().putHeader(ConfigConstants.OPENDISTRO_SECURITY_FILTER_LEVEL_DLS_DONE, "fake filter level dls header");
threadPool.getThreadContext().putHeader(ConfigConstants.OPENDISTRO_SECURITY_DLS_MODE_HEADER, "fake dls mode header");
threadPool.getThreadContext().putHeader(ConfigConstants.OPENDISTRO_SECURITY_DLS_FILTER_LEVEL_QUERY_HEADER, "fake dls filter header");
threadPool.getThreadContext().putHeader("_opendistro_security_trace", "fake trace value");
threadPool.getThreadContext().putHeader(ConfigConstants.OPENDISTRO_SECURITY_INITIAL_ACTION_CLASS_HEADER, "fake initial action header");
threadPool.getThreadContext().putHeader("_opendistro_security_source_field_context", "fake source field context value");
threadPool.getThreadContext().putHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_ROLES_VALIDATION, "fake injected roles validation string");

// CS-SUPPRESS-SINGLE: RegexpSingleline Extensions manager used for creating a mock
OpenSearchSecurityPlugin.GuiceHolder guiceHolder = new OpenSearchSecurityPlugin.GuiceHolder(
mock(RepositoriesService.class),
transportService,
mock(IndicesService.class),
mock(PitService.class),
mock(ExtensionsManager.class)
);

// CS-ENFORCE-SINGLE

String action = "testAction";
TransportRequest request = mock(TransportRequest.class);
TransportRequestOptions options = mock(TransportRequestOptions.class);
@SuppressWarnings("unchecked")
TransportResponseHandler<TransportResponse> handler = mock(TransportResponseHandler.class);

InetAddress localAddress = null;
try {
localAddress = InetAddress.getByName("0.0.0.0");
} catch (final UnknownHostException uhe) {
throw new RuntimeException(uhe);
}

DiscoveryNode localNode = new DiscoveryNode("local-node1", new TransportAddress(localAddress, 1234), Version.CURRENT);
Connection connection1 = transportService.getConnection(localNode);

DiscoveryNode remoteNode = new DiscoveryNode("remote-node", new TransportAddress(localAddress, 6789), remoteNodeVersion);
Connection connection2 = transportService.getConnection(remoteNode);

// from thread context should be null because there is no header
AsyncSender sender = new AsyncSender() {
@Override
public <T extends TransportResponse> void sendRequest(
Connection connection,
String action,
TransportRequest request,
TransportRequestOptions options,
TransportResponseHandler<T> handler
) {
User transientUser = threadPool.getThreadContext().getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER);
assertEquals(transientUser, null);
}
};

// local node request
securityInterceptor.sendRequestDecorate(sender, connection1, action, request, options, handler, localNode);

// from original context
User transientUser = threadPool.getThreadContext().getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER);
assertEquals(transientUser, null);
assertEquals(threadPool.getThreadContext().getHeader(ConfigConstants.OPENDISTRO_SECURITY_USER_HEADER), null);

// checking thread context for a remote context; does not matter should still be null
sender = new AsyncSender() {
@Override
public <T extends TransportResponse> void sendRequest(
Connection connection,
String action,
TransportRequest request,
TransportRequestOptions options,
TransportResponseHandler<T> handler
) {
User transientUser = threadPool.getThreadContext().getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER);
assertEquals(transientUser, null);
}
};

// this is also a local request
securityInterceptor.sendRequestDecorate(sender, connection2, action, request, options, handler, remoteNode);

// from original context
User transientUser2 = threadPool.getThreadContext().getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER);
assertEquals(transientUser2, null);
assertEquals(threadPool.getThreadContext().getHeader(ConfigConstants.OPENDISTRO_SECURITY_USER_HEADER), null);

}

@Test
Expand All @@ -270,4 +439,8 @@ public void testSendRequestDecorateWhenRemoteNodeUsesJDKSerde() {
testSendRequestDecorate(Version.V_2_0_0);
}

@Test
public void testSendRequestDecorateWithNullUser() {
testSendRequestDecorateWithEmptyUserHeader(Version.CURRENT);
}
}

0 comments on commit 1ff11fa

Please sign in to comment.