Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/generators/java-microprofile.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|generateBuilders|Whether to generate builders for models| |false|
|generateClientAsBean|For resttemplate, restclient and webclient, configure whether to create `ApiClient.java` and Apis clients as bean (with `@Component` annotation).| |false|
|generateConstructorWithAllArgs|whether to generate a constructor for all arguments| |false|
|generateInsecureTlsHook|Generate the ApiClient.disableCertificateValidation hook, which trusts all TLS certificates (default to true). Set to false to omit it, e.g. when static analysis flags the trust-all TrustManager it contains. Available on `jersey2`, `jersey3` libraries.| |false|

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This option is documented for java-microprofile but is a no-op there. java-microprofile (JavaMicroprofileServerCodegen) extends JavaClientCodegen, so the unconditionally-registered CliOption at JavaClientCodegen.java:287 propagates here and to every other Java generator, yet only the jersey2/jersey3 ApiClient mustache templates consult generateInsecureTlsHook. Users of this generator see an option that does nothing, contradicting the PR's stated jersey2/jersey3 scope. Add the CliOption (and its additionalProperties defaulting) only for the jersey2/jersey3 libraries, or otherwise filter it from generators whose templates never read it.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/generators/java-microprofile.md, line 59:

<comment>This option is documented for java-microprofile but is a no-op there. java-microprofile (JavaMicroprofileServerCodegen) extends JavaClientCodegen, so the unconditionally-registered CliOption at JavaClientCodegen.java:287 propagates here and to every other Java generator, yet only the jersey2/jersey3 ApiClient mustache templates consult generateInsecureTlsHook. Users of this generator see an option that does nothing, contradicting the PR's stated jersey2/jersey3 scope. Add the CliOption (and its additionalProperties defaulting) only for the jersey2/jersey3 libraries, or otherwise filter it from generators whose templates never read it.</comment>

<file context>
@@ -56,6 +56,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
 |generateBuilders|Whether to generate builders for models| |false|
 |generateClientAsBean|For resttemplate, restclient and webclient, configure whether to create `ApiClient.java` and Apis clients as bean (with `@Component` annotation).| |false|
 |generateConstructorWithAllArgs|whether to generate a constructor for all arguments| |false|
+|generateInsecureTlsHook|Generate the ApiClient.disableCertificateValidation hook, which trusts all TLS certificates (default to true). Set to false to omit it, e.g. when static analysis flags the trust-all TrustManager it contains. Available on `jersey2`, `jersey3` libraries.| |false|
 |gradleProperties|Append additional Gradle properties to the gradle.properties file| |null|
 |groupId|groupId in generated pom.xml| |org.openapitools|
</file context>

|gradleProperties|Append additional Gradle properties to the gradle.properties file| |null|
|groupId|groupId in generated pom.xml| |org.openapitools|
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |false|
Expand Down
1 change: 1 addition & 0 deletions docs/generators/java.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|generateBuilders|Whether to generate builders for models| |false|
|generateClientAsBean|For resttemplate, restclient and webclient, configure whether to create `ApiClient.java` and Apis clients as bean (with `@Component` annotation).| |false|
|generateConstructorWithAllArgs|whether to generate a constructor for all arguments| |false|
|generateInsecureTlsHook|Generate the ApiClient.disableCertificateValidation hook, which trusts all TLS certificates (default to true). Set to false to omit it, e.g. when static analysis flags the trust-all TrustManager it contains. Available on `jersey2`, `jersey3` libraries.| |false|
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
Outdated
|gradleProperties|Append additional Gradle properties to the gradle.properties file| |null|
|groupId|groupId in generated pom.xml| |org.openapitools|
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |false|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ public class JavaClientCodegen extends AbstractJavaCodegen
public static final String DYNAMIC_OPERATIONS = "dynamicOperations";
public static final String SUPPORT_STREAMING = "supportStreaming";
public static final String SUPPORT_URL_QUERY = "supportUrlQuery";
public static final String GENERATE_INSECURE_TLS_HOOK = "generateInsecureTlsHook";
public static final String GRADLE_PROPERTIES = "gradleProperties";
public static final String ERROR_OBJECT_TYPE = "errorObjectType";

Expand Down Expand Up @@ -283,6 +284,7 @@ public JavaClientCodegen() {
cliOptions.add(CliOption.newBoolean(WEBCLIENT_BLOCKING_OPERATIONS, "Making all WebClient operations blocking(sync). Note that if on operation 'x-webclient-blocking: false' then such operation won't be sync", this.webclientBlockingOperations));
cliOptions.add(CliOption.newBoolean(GENERATE_CLIENT_AS_BEAN, "For resttemplate, restclient and webclient, configure whether to create `ApiClient.java` and Apis clients as bean (with `@Component` annotation).", this.generateClientAsBean));
cliOptions.add(CliOption.newBoolean(SUPPORT_URL_QUERY, "Generate toUrlQueryString in POJO (default to true). Available on `native`, `apache-httpclient` libraries."));
cliOptions.add(CliOption.newBoolean(GENERATE_INSECURE_TLS_HOOK, "Generate the ApiClient.disableCertificateValidation hook, which trusts all TLS certificates (default to true). Set to false to omit it, e.g. when static analysis flags the trust-all TrustManager it contains. Available on `jersey2`, `jersey3` libraries."));
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
Outdated
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
Outdated
cliOptions.add(CliOption.newBoolean(USE_ENUM_CASE_INSENSITIVE, "Use `equalsIgnoreCase` when String for enum comparison", useEnumCaseInsensitive));
cliOptions.add(CliOption.newBoolean(FAIL_ON_UNKNOWN_PROPERTIES, "Fail Jackson de-serialization on unknown properties", this.failOnUnknownProperties));
cliOptions.add(CliOption.newBoolean(USE_JACKSON_3, "Use Jackson 3 instead of Jackson 2. Supported for 'native', 'apache-httpclient', and 'jersey3' libraries (requires Java 17+) and for Spring 'resttemplate', 'webclient', and 'restclient' libraries (require useSpringBoot4=true).", this.useJackson3));
Expand Down Expand Up @@ -527,6 +529,15 @@ public void processOpts() {
additionalProperties.put(SUPPORT_URL_QUERY, Boolean.parseBoolean(additionalProperties.get(SUPPORT_URL_QUERY).toString()));
}

// the disableCertificateValidation hook is emitted by default, to keep
// existing subclasses that call it compiling
if (!additionalProperties.containsKey(GENERATE_INSECURE_TLS_HOOK)) {
additionalProperties.put(GENERATE_INSECURE_TLS_HOOK, true);
} else {
additionalProperties.put(GENERATE_INSECURE_TLS_HOOK,
Boolean.parseBoolean(additionalProperties.get(GENERATE_INSECURE_TLS_HOOK).toString()));
}

convertPropertyToBooleanAndWriteBack(GENERATE_CLIENT_AS_BEAN, this::setGenerateClientAsBean);
convertPropertyToBooleanAndWriteBack(USE_ENUM_CASE_INSENSITIVE, this::setUseEnumCaseInsensitive);
convertPropertyToTypeAndWriteBack(CodegenConstants.MAX_ATTEMPTS_FOR_RETRY, Integer::parseInt, this::setMaxAttemptsForRetry);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@ import java.io.IOException;
import java.io.InputStream;

import java.net.URI;
{{#generateInsecureTlsHook}}
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
{{/generateInsecureTlsHook}}
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
Expand Down Expand Up @@ -1437,14 +1439,17 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
* server endpoints from web targets created by the client instance that is using this SSL context.
* 4. Set the client-side trust store.
*
{{#generateInsecureTlsHook}}
* To completely disable certificate validation (at your own risk), you can
* override this method and invoke disableCertificateValidation(clientBuilder).
*
{{/generateInsecureTlsHook}}
* @param clientBuilder a {@link {{javaxPackage}}.ws.rs.client.ClientBuilder} object.
*/
protected void customizeClientBuilder(ClientBuilder clientBuilder) {
// No-op extension point
}
{{#generateInsecureTlsHook}}

/**
* Disable X.509 certificate validation in TLS connections.
Expand Down Expand Up @@ -1475,6 +1480,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
sslContext.init(null, trustAllCerts, new SecureRandom());
clientBuilder.sslContext(sslContext);
}
{{/generateInsecureTlsHook}}

/**
* <p>Build the response headers.</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@ import java.io.IOException;
import java.io.InputStream;

import java.net.URI;
{{#generateInsecureTlsHook}}
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
{{/generateInsecureTlsHook}}
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
Expand Down Expand Up @@ -1477,14 +1479,17 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
* server endpoints from web targets created by the client instance that is using this SSL context.
* 4. Set the client-side trust store.
*
{{#generateInsecureTlsHook}}
* To completely disable certificate validation (at your own risk), you can
* override this method and invoke disableCertificateValidation(clientBuilder).
*
{{/generateInsecureTlsHook}}
* @param clientBuilder a {@link {{javaxPackage}}.ws.rs.client.ClientBuilder} object.
*/
protected void customizeClientBuilder(ClientBuilder clientBuilder) {
// No-op extension point
}
{{#generateInsecureTlsHook}}

/**
* Disable X.509 certificate validation in TLS connections.
Expand Down Expand Up @@ -1515,6 +1520,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
sslContext.init(null, trustAllCerts, new SecureRandom());
clientBuilder.sslContext(sslContext);
}
{{/generateInsecureTlsHook}}

/**
* <p>Build the response headers.</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5003,4 +5003,47 @@ private static JavaClientCodegen newRetrofit2Codegen(Map<String, Object> propert
codegen.additionalProperties().putAll(properties);
return codegen;
}

@DataProvider(name = "jerseyLibraries")
public static Object[][] jerseyLibraries() {
return new Object[][]{{JavaClientCodegen.JERSEY2}, {JavaClientCodegen.JERSEY3}};
}

@Test(dataProvider = "jerseyLibraries")
public void testInsecureTlsHookGeneratedByDefault(String library) {
Path output = generateJerseyClient(library, null);

JavaFileAssert.assertThat(output.resolve("src/main/java/xyz/abcdef/invoker/ApiClient.java").toFile())
.assertMethod("disableCertificateValidation");
}

@Test(dataProvider = "jerseyLibraries")
public void testInsecureTlsHookOmittedWhenDisabled(String library) {
Path output = generateJerseyClient(library, false);

assertThat(output.resolve("src/main/java/xyz/abcdef/invoker/ApiClient.java")).content()
.doesNotContain("disableCertificateValidation")
.doesNotContain("X509TrustManager")
.doesNotContain("import javax.net.ssl.SSLContext;")
.doesNotContain("import java.security.SecureRandom;")
.doesNotContain("import java.security.KeyManagementException;")
.doesNotContain("import java.security.NoSuchAlgorithmException;")
.doesNotContain("import java.security.cert.X509Certificate;");
}

private static Path generateJerseyClient(String library, Boolean generateInsecureTlsHook) {
Path output = newTempFolder();
CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName(JAVA_GENERATOR)
.setLibrary(library)
.addAdditionalProperty(CodegenConstants.INVOKER_PACKAGE, "xyz.abcdef.invoker")
.setInputSpec("src/test/resources/3_0/petstore.yaml")
.setOutputDir(output.toString().replace("\\", "/"));
if (generateInsecureTlsHook != null) {
configurator.addAdditionalProperty(GENERATE_INSECURE_TLS_HOOK, generateInsecureTlsHook);
}

new DefaultGenerator().opts(configurator.toClientOptInput()).generate();
return output;
}
}