Skip to content

Commit

Permalink
added kerberos client test in factory
Browse files Browse the repository at this point in the history
  • Loading branch information
Bilal Al committed Aug 30, 2024
1 parent 87f5586 commit fe52d1c
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 48 deletions.
12 changes: 12 additions & 0 deletions client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -248,5 +248,17 @@
<version>4.0.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.7.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.7.4</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
73 changes: 43 additions & 30 deletions client/src/main/java/io/split/client/SplitFactoryImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -505,9 +505,36 @@ public boolean isDestroyed() {
return isTerminated;
}

private static SplitHttpClient buildSplitHttpClient(String apiToken, SplitClientConfig config,
protected static SplitHttpClient buildSplitHttpClient(String apiToken, SplitClientConfig config,
SDKMetadata sdkMetadata, RequestDecorator requestDecorator)
throws URISyntaxException, IOException {
// setup Kerberos client
if (config.authScheme() == HttpAuthScheme.KERBEROS) {
_log.info("Using Kerberos-Proxy Authentication Scheme.");
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(config.proxy().getHostName(), config.proxy().getPort()));
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
if (config.debugEnabled()) {
logging.setLevel(HttpLoggingInterceptor.Level.HEADERS);
} else {
logging.setLevel(HttpLoggingInterceptor.Level.NONE);
}

Map<String, String> kerberosOptions = new HashMap<String, String>();
kerberosOptions.put("com.sun.security.auth.module.Krb5LoginModule", "required");
kerberosOptions.put("refreshKrb5Config", "false");
kerberosOptions.put("doNotPrompt", "false");
kerberosOptions.put("useTicketCache", "true");

Authenticator proxyAuthenticator = getProxyAuthenticator(config, kerberosOptions);
OkHttpClient client = buildOkHttpClient(proxy, config, logging, proxyAuthenticator);

return SplitHttpClientKerberosImpl.create(
client,
requestDecorator,
apiToken,
sdkMetadata);
}

SSLConnectionSocketFactory sslSocketFactory = SSLConnectionSocketFactoryBuilder.create()
.setSslContext(SSLContexts.createSystemDefault())
.setTlsVersions(TLS.V_1_1, TLS.V_1_2)
Expand Down Expand Up @@ -539,41 +566,27 @@ private static SplitHttpClient buildSplitHttpClient(String apiToken, SplitClient
httpClientbuilder = setupProxy(httpClientbuilder, config);
}

// setup Kerberos client
if (config.authScheme() == HttpAuthScheme.KERBEROS) {
_log.info("Using Kerberos-Proxy Authentication Scheme.");
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(config.proxy().getHostName(), config.proxy().getPort()));
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.HEADERS);

Map<String, String> kerberosOptions = new HashMap<String, String>();
kerberosOptions.put("com.sun.security.auth.module.Krb5LoginModule", "required");
kerberosOptions.put("refreshKrb5Config", "false");
kerberosOptions.put("doNotPrompt", "false");
kerberosOptions.put("useTicketCache", "true");

Authenticator proxyAuthenticator = new HTTPKerberosAuthInterceptor(config.kerberosPrincipalName(), kerberosOptions);
OkHttpClient client = new Builder()
.proxy(proxy)
.readTimeout(config.readTimeout(), TimeUnit.MILLISECONDS)
.connectTimeout(config.connectionTimeout(), TimeUnit.MILLISECONDS)
.addInterceptor(logging)
.proxyAuthenticator(proxyAuthenticator)
.build();

return SplitHttpClientKerberosImpl.create(
client,
requestDecorator,
apiToken,
sdkMetadata);

}
return SplitHttpClientImpl.create(httpClientbuilder.build(),
requestDecorator,
apiToken,
sdkMetadata);
}

protected static OkHttpClient buildOkHttpClient(Proxy proxy, SplitClientConfig config,
HttpLoggingInterceptor logging, Authenticator proxyAuthenticator) {
return new Builder()
.proxy(proxy)
.readTimeout(config.readTimeout(), TimeUnit.MILLISECONDS)
.connectTimeout(config.connectionTimeout(), TimeUnit.MILLISECONDS)
.addInterceptor(logging)
.proxyAuthenticator(proxyAuthenticator)
.build();
}

protected static HTTPKerberosAuthInterceptor getProxyAuthenticator(SplitClientConfig config,
Map<String, String> kerberosOptions) throws IOException {
return new HTTPKerberosAuthInterceptor(config.kerberosPrincipalName(), kerberosOptions);
}
private static CloseableHttpClient buildSSEdHttpClient(String apiToken, SplitClientConfig config,
SDKMetadata sdkMetadata) {
RequestConfig requestConfig = RequestConfig.custom()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,6 @@ public Object run() {
*/
@Override public Request authenticate(Route route, Response response) throws IOException {
String authValue;
System.out.println("Using principal: HTTP/" + host);
try {
authValue = "Negotiate " + buildAuthorizationHeader("HTTP/" + host);
} catch (Exception e) {
Expand Down
75 changes: 58 additions & 17 deletions client/src/test/java/io/split/client/SplitFactoryImplTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.split.client.utils.SDKMetadata;
import io.split.integrations.IntegrationsConfig;
import io.split.service.HttpAuthScheme;
import io.split.service.SplitHttpClient;
import io.split.service.SplitHttpClientKerberosImpl;
import io.split.storages.enums.OperationMode;
import io.split.storages.pluggable.domain.UserStorageWrapper;
Expand All @@ -13,7 +14,14 @@
import junit.framework.TestCase;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.BDDMockito;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import pluggable.CustomStorageWrapper;

import java.io.FileInputStream;
Expand All @@ -24,10 +32,21 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;

import okhttp3.Authenticator;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;

import static io.split.client.SplitClientConfig.splitSdkVersion;
import static org.mockito.Mockito.when;

@RunWith(PowerMockRunner.class)
@PrepareForTest(SplitFactoryImpl.class)
public class SplitFactoryImplTest extends TestCase {
public static final String API_KEY ="29013ionasdasd09u";
public static final String ENDPOINT = "https://sdk.split-stage.io";
Expand Down Expand Up @@ -141,7 +160,7 @@ public void testFactoryConsumerInstantiation() throws Exception {
CustomStorageWrapper customStorageWrapper = Mockito.mock(CustomStorageWrapper.class);
UserStorageWrapper userStorageWrapper = Mockito.mock(UserStorageWrapper.class);
TelemetrySynchronizer telemetrySynchronizer = Mockito.mock(TelemetrySynchronizer.class);
Mockito.when(userStorageWrapper.connect()).thenReturn(true);
when(userStorageWrapper.connect()).thenReturn(true);

SplitClientConfig splitClientConfig = SplitClientConfig.builder()
.enableDebug()
Expand Down Expand Up @@ -179,7 +198,7 @@ public void testFactoryConsumerInstantiation() throws Exception {
public void testFactoryConsumerInstantiationRetryReadiness() throws Exception {
CustomStorageWrapper customStorageWrapper = Mockito.mock(CustomStorageWrapper.class);
UserStorageWrapper userStorageWrapper = Mockito.mock(UserStorageWrapper.class);
Mockito.when(userStorageWrapper.connect()).thenReturn(false).thenReturn(true);
when(userStorageWrapper.connect()).thenReturn(false).thenReturn(true);
SplitClientConfig splitClientConfig = SplitClientConfig.builder()
.enableDebug()
.impressionsMode(ImpressionsManager.Mode.DEBUG)
Expand All @@ -200,15 +219,15 @@ public void testFactoryConsumerInstantiationRetryReadiness() throws Exception {
splitFactoryImpl.set(splitFactory, userStorageWrapper);
assertNotNull(splitFactory.client());
assertNotNull(splitFactory.manager());
Thread.sleep(2000);
Thread.sleep(3000);
Mockito.verify(userStorageWrapper, Mockito.times(2)).connect();
}

@Test
public void testFactoryConsumerDestroy() throws NoSuchFieldException, URISyntaxException, IllegalAccessException {
CustomStorageWrapper customStorageWrapper = Mockito.mock(CustomStorageWrapper.class);
UserStorageWrapper userStorageWrapper = Mockito.mock(UserStorageWrapper.class);
Mockito.when(userStorageWrapper.connect()).thenReturn(false).thenReturn(true);
when(userStorageWrapper.connect()).thenReturn(false).thenReturn(true);
SplitClientConfig splitClientConfig = SplitClientConfig.builder()
.enableDebug()
.impressionsMode(ImpressionsManager.Mode.DEBUG)
Expand Down Expand Up @@ -352,25 +371,47 @@ public void testLocalhosJsonInputStreamNullAndFileTypeNull() throws URISyntaxExc
}

@Test
public void testFactoryKerberosInstance() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
SplitFactoryImpl splitFactory = null;
public void testFactoryKerberosInstance() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, URISyntaxException, IOException {
PowerMockito.mockStatic(SplitFactoryImpl.class);

ArgumentCaptor<Proxy> proxyCaptor = ArgumentCaptor.forClass(Proxy.class);
ArgumentCaptor<SplitClientConfig> configCaptor = ArgumentCaptor.forClass(SplitClientConfig.class);
ArgumentCaptor< HttpLoggingInterceptor> logCaptor = ArgumentCaptor.forClass( HttpLoggingInterceptor.class);
ArgumentCaptor<Authenticator> authCaptor = ArgumentCaptor.forClass(Authenticator.class);

SplitClientConfig splitClientConfig = SplitClientConfig.builder()
.setBlockUntilReadyTimeout(10000)
.authScheme(HttpAuthScheme.KERBEROS)
.kerberosPrincipalName("bilal@bilal")
.kerberosPrincipalName("bilal@localhost")
.proxyPort(6060)
.proxyHost(ENDPOINT)
.build();
try {
splitFactory = new SplitFactoryImpl("asdf", splitClientConfig);
} catch(Exception e) {

}

Method method = SplitFactoryImpl.class.getDeclaredMethod("buildSplitHttpClient", String.class,
SplitClientConfig.class, SDKMetadata.class, RequestDecorator.class);
method.setAccessible(true);
Object SplitHttpClient = method.invoke(splitFactory, "asdf", splitClientConfig, new SDKMetadata(splitSdkVersion, "", ""), new RequestDecorator(null));
Assert.assertTrue(SplitHttpClient instanceof SplitHttpClientKerberosImpl);
Map<String, String> kerberosOptions = new HashMap<String, String>();
kerberosOptions.put("com.sun.security.auth.module.Krb5LoginModule", "required");
kerberosOptions.put("refreshKrb5Config", "false");
kerberosOptions.put("doNotPrompt", "false");
kerberosOptions.put("useTicketCache", "true");
BDDMockito.given(SplitFactoryImpl.getProxyAuthenticator(splitClientConfig, kerberosOptions))
.willReturn(null);

RequestDecorator requestDecorator = new RequestDecorator(null);
SDKMetadata sdkmeta = new SDKMetadata("java-1.2.3", "1.2.3.4", "someIP");
PowerMockito.when(SplitFactoryImpl.buildSplitHttpClient("qwer",
splitClientConfig,
sdkmeta,
requestDecorator)).thenCallRealMethod();

SplitHttpClient splitHttpClient = SplitFactoryImpl.buildSplitHttpClient("qwer",
splitClientConfig,
sdkmeta,
requestDecorator);

PowerMockito.verifyStatic();
SplitFactoryImpl.buildOkHttpClient(proxyCaptor.capture(), configCaptor.capture(),logCaptor.capture(), authCaptor.capture());

Assert.assertTrue(splitHttpClient instanceof SplitHttpClientKerberosImpl);
Assert.assertEquals(proxyCaptor.getValue().toString(), "HTTP @ https://sdk.split-stage.io:6060");
Assert.assertTrue(logCaptor.getValue() instanceof okhttp3.logging.HttpLoggingInterceptor);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
powermock.global-ignore=jdk.internal.reflect.*,javax.net.ssl.*

0 comments on commit fe52d1c

Please sign in to comment.