Skip to content
This repository was archived by the owner on Mar 11, 2022. It is now read-only.

Commit 6b9b7be

Browse files
committed
Indicate custom SSL limitations
Document the limitations of OkHttp and Java 8_252 or newer being unable to use disableSSLAuthentication and customSSLSocketFactory options. Ignore test combinations that intersect that. Make the CloudFoundryServiceTest not use OkHttp.
1 parent ae59cd1 commit 6b9b7be

File tree

7 files changed

+65
-9
lines changed

7 files changed

+65
-9
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ The main use case that is supported by this optional dependency is configuration
6868
([see the javadoc](http://www.javadoc.io/doc/com.cloudant/cloudant-client/) for ClientBuilder.maxConnections). If the OkHttp dependency is
6969
available at runtime it will be used automatically. Not using OkHttp will result in a smaller application size.
7070

71+
**Note:** The configuration options `ClientBuilder.customSSLSocketFactory` and
72+
`ClientBuilder.disableSSLAuthentication` are not usable with the combination of the optional OkHttp
73+
dependency and Java versions of 8u252 or newer.
74+
7175
## Getting Started
7276

7377
This section contains a simple example of creating a `com.cloudant.client.api.CloudantClient` instance and interacting with Cloudant.

cloudant-client/src/main/java/com/cloudant/client/api/ClientBuilder.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright © 2015, 2019 IBM Corp. All rights reserved.
2+
* Copyright © 2015, 2020 IBM Corp. All rights reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
55
* except in compliance with the License. You may obtain a copy of the License at
@@ -514,6 +514,9 @@ public ClientBuilder proxyPassword(String proxyPassword) {
514514
* The SSL authentication is enabled by default meaning that hostname verification
515515
* and certificate chain validation is done using the JVM default settings.
516516
* </P>
517+
* <P>
518+
* <B>Not supported with Java 8u252 or newer and the optional OkHttp dependency.</B>
519+
* </P>
517520
*
518521
* @return this ClientBuilder object for setting additional options
519522
* @throws IllegalStateException if {@link #customSSLSocketFactory(SSLSocketFactory)}
@@ -534,6 +537,9 @@ public ClientBuilder disableSSLAuthentication() {
534537
/**
535538
* Specifies the custom SSLSocketFactory to use when connecting to Cloudant over a
536539
* <code>https</code> URL, when SSL authentication is enabled.
540+
* <P>
541+
* <B>Not supported with Java 8u252 or newer and the optional OkHttp dependency.</B>
542+
* </P>
537543
*
538544
* @param factory An SSLSocketFactory, or <code>null</code> for the
539545
* default SSLSocketFactory of the JRE.

cloudant-client/src/test/java/com/cloudant/tests/CloudFoundryServiceTest.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright © 2016, 2019 IBM Corp. All rights reserved.
2+
* Copyright © 2016, 2020 IBM Corp. All rights reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
55
* except in compliance with the License. You may obtain a copy of the License at
@@ -24,6 +24,7 @@
2424
import com.cloudant.client.api.ClientBuilder;
2525
import com.cloudant.client.api.CloudantClient;
2626
import com.cloudant.tests.extensions.MockWebServerExtension;
27+
import com.cloudant.tests.util.HttpFactoryParameterizedTest;
2728
import com.cloudant.tests.util.MockWebServerResources;
2829
import com.google.gson.GsonBuilder;
2930

@@ -63,6 +64,11 @@ public class CloudFoundryServiceTest {
6364

6465
@BeforeEach
6566
public void beforeEach() {
67+
// Default test running uses OkHttp because it is in the classpath
68+
// These tests need to use disableSSLAuthentication because the mock server https does not
69+
// have a trusted certificate. That option is not valid with OkHttp and Java 8_252 or newer
70+
// but we want to run these tests, so use the OkHelperMock to disable OkHttp.
71+
new HttpFactoryParameterizedTest.OkHelperMock();
6672
server = mockWebServerExt.get();
6773
server.useHttps(MockWebServerResources.getSSLSocketFactory(), false);
6874
mockServerHostPort = String.format("%s:%s/", server.getHostName(), server.getPort());

cloudant-client/src/test/java/com/cloudant/tests/HttpProxyTest.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright © 2015, 2018 IBM Corp. All rights reserved.
2+
* Copyright © 2015, 2020 IBM Corp. All rights reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
55
* except in compliance with the License. You may obtain a copy of the License at
@@ -23,6 +23,7 @@
2323
import com.cloudant.tests.extensions.MockWebServerExtension;
2424
import com.cloudant.tests.util.HttpFactoryParameterizedTest;
2525
import com.cloudant.tests.util.MockWebServerResources;
26+
import com.cloudant.tests.util.Utils;
2627

2728
import org.junit.jupiter.api.AfterEach;
2829
import org.junit.jupiter.api.BeforeEach;
@@ -300,6 +301,10 @@ public void proxiedRequest(final boolean okUsable,
300301
final boolean useHttpsServer,
301302
final boolean useProxyAuth) throws Exception {
302303

304+
// Test uses disableSSLAuthentication because the mock server doesn't have a trusted cert
305+
// - need to disable the test for OkHttp and Java 8_252 or newer
306+
Utils.assumeCustomSslAuthUsable(okUsable);
307+
303308
//mock a 200 OK
304309
server.setDispatcher(new Dispatcher() {
305310
@Override

cloudant-client/src/test/java/com/cloudant/tests/SslAuthenticationTest.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright © 2015, 2019 IBM Corp. All rights reserved.
2+
* Copyright © 2015, 2020 IBM Corp. All rights reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
55
* except in compliance with the License. You may obtain a copy of the License at
@@ -24,6 +24,7 @@
2424
import com.cloudant.tests.extensions.MockWebServerExtension;
2525
import com.cloudant.tests.util.HttpFactoryParameterizedTest;
2626
import com.cloudant.tests.util.MockWebServerResources;
27+
import com.cloudant.tests.util.Utils;
2728

2829
import org.junit.jupiter.api.BeforeEach;
2930
import org.junit.jupiter.api.TestTemplate;
@@ -136,7 +137,8 @@ private static void validateClientAuthenticationException(CouchDbException e) {
136137
*/
137138
@TestTemplate
138139
public void localSslAuthenticationDisabled() throws Exception {
139-
140+
// disableSSLAuthentication not usable with OkHttp and 8_252 or newer
141+
Utils.assumeCustomSslAuthUsable(isOkUsable);
140142
// Build a client that connects to the mock server with SSL authentication disabled
141143
CloudantClient dbClient = CloudantClientHelper.newMockWebServerClientBuilder(server)
142144
.disableSSLAuthentication()
@@ -251,7 +253,8 @@ public void execute() throws Throwable {
251253
*/
252254
@TestTemplate
253255
public void localSSLAuthenticationDisabledWithCookieAuth() throws Exception {
254-
256+
// disableSSLAuthentication not usable with OkHttp and 8_252 or newer
257+
Utils.assumeCustomSslAuthUsable(isOkUsable);
255258
// Mock up an OK cookie response then an OK response for the getAllDbs()
256259
server.enqueue(MockWebServerResources.OK_COOKIE);
257260
server.enqueue(new MockResponse()); //OK 200

cloudant-client/src/test/java/com/cloudant/tests/util/HttpFactoryParameterizedTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright © 2016, 2018 IBM Corp. All rights reserved.
2+
* Copyright © 2016, 2020 IBM Corp. All rights reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
55
* except in compliance with the License. You may obtain a copy of the License at
@@ -37,7 +37,7 @@ public abstract class HttpFactoryParameterizedTest extends TestWithDbPerClass {
3737
* A mock OkHelper that always returns false to force use of the JVM HttpURLConnection
3838
* via the {@link DefaultHttpUrlConnectionFactory}
3939
*/
40-
static class OkHelperMock extends MockUp<OkHelper> {
40+
public static class OkHelperMock extends MockUp<OkHelper> {
4141
@Mock
4242
public static boolean isOkUsable() {
4343
return false;

cloudant-client/src/test/java/com/cloudant/tests/util/Utils.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright © 2015, 2018 IBM Corp. All rights reserved.
2+
* Copyright © 2015, 2020 IBM Corp. All rights reserved.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
55
* except in compliance with the License. You may obtain a copy of the License at
@@ -35,6 +35,8 @@
3535
import com.cloudant.http.HttpConnectionInterceptorContext;
3636
import com.cloudant.http.HttpConnectionResponseInterceptor;
3737

38+
import org.junit.jupiter.api.Assumptions;
39+
3840
import java.io.File;
3941
import java.io.FileNotFoundException;
4042
import java.net.URI;
@@ -225,4 +227,34 @@ public static void assertOKResponse(Response r) throws Exception {
225227
assertTrue(r.getStatusCode()
226228
/ 100 == 2, "The response code should be 2XX was " + r.getStatusCode());
227229
}
230+
231+
/**
232+
* Utility to ignore tests when running with optional OkHttp dependency and Java 8_252 or newer.
233+
* This should be applied to any test that uses the customSSLSocketFactory or
234+
* disableSSLAuthentication options.
235+
*
236+
* These options cannot be used with OkHttp and Java 8_252 or newer
237+
* (see https://github.com/square/okhttp/issues/5970.
238+
* OkHttp treats 8_252 and newer as equivalent to 9+ because of the availability of ALPN
239+
* support. In 9+ reflection cannot be used to infer the TrustManager from the SslSocketFactory
240+
* so setting the SslSocketFactory without a TrustManager is prevented. This blocks the route we
241+
* currently use to supply custom SslSocketFactory via the deprecated OkHttp OkUrlFactory path
242+
* via javax.net.ssl.HttpsURLConnection#setSSLSocketFactory(javax.net.ssl.SSLSocketFactory).
243+
*
244+
*/
245+
public static void assumeCustomSslAuthUsable(boolean isOkUsable) {
246+
String version = System.getProperty("java.version");
247+
boolean java8_252OrHigher = false;
248+
// Java 1.8 or lower, 9+ are 9, 10 etc
249+
if (version.startsWith("1.")) {
250+
if (version.startsWith("1.8.")) {
251+
int update = Integer.parseInt(version.split("_")[1]);
252+
if (update >= 252) java8_252OrHigher = true;
253+
}
254+
} else {
255+
java8_252OrHigher = true;
256+
}
257+
Assumptions.assumeFalse(isOkUsable && java8_252OrHigher, "Test uses custom " +
258+
"SslSocketFactory, incompatible with OkHttp and Java 8_252 or newer.");
259+
}
228260
}

0 commit comments

Comments
 (0)