From f53e8c655ec14ac9f64124b18f172d8ea4421a23 Mon Sep 17 00:00:00 2001 From: Greg Thomas Date: Sun, 23 Jun 2024 17:54:41 +0100 Subject: [PATCH] Add support for a bearer token supplier to OAuth based RestTemplate clients. Fixes #19000 --- .../libraries/resttemplate/ApiClient.mustache | 11 +++++- .../resttemplate/auth/OAuth.mustache | 36 +++++++++++++++---- .../codegen/java/JavaClientCodegenTest.java | 34 ++++++++++++++++++ .../src/test/resources/3_0/java/oauth.yaml | 28 +++++++++++++++ .../org/openapitools/client/ApiClient.java | 11 +++++- .../org/openapitools/client/auth/OAuth.java | 36 +++++++++++++++---- .../org/openapitools/client/ApiClient.java | 11 +++++- .../org/openapitools/client/auth/OAuth.java | 36 +++++++++++++++---- .../org/openapitools/client/ApiClient.java | 11 +++++- .../org/openapitools/client/auth/OAuth.java | 36 +++++++++++++++---- .../org/openapitools/client/ApiClient.java | 11 +++++- .../org/openapitools/client/auth/OAuth.java | 36 +++++++++++++++---- .../org/openapitools/client/ApiClient.java | 11 +++++- .../org/openapitools/client/auth/OAuth.java | 36 +++++++++++++++---- 14 files changed, 302 insertions(+), 42 deletions(-) create mode 100644 modules/openapi-generator/src/test/resources/3_0/java/oauth.yaml diff --git a/modules/openapi-generator/src/main/resources/Java/libraries/resttemplate/ApiClient.mustache b/modules/openapi-generator/src/main/resources/Java/libraries/resttemplate/ApiClient.mustache index fe355ec358fb..7953c007459e 100644 --- a/modules/openapi-generator/src/main/resources/Java/libraries/resttemplate/ApiClient.mustache +++ b/modules/openapi-generator/src/main/resources/Java/libraries/resttemplate/ApiClient.mustache @@ -331,9 +331,18 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} { * @param accessToken Access token */ public void setAccessToken(String accessToken) { + setAccessToken(() -> accessToken); + } + + /** + * Helper method to set the supplier of access tokens for OAuth2 authentication. + * + * @param tokenSupplier The supplier of bearer tokens + */ + public void setAccessToken(Supplier tokenSupplier) { for (Authentication auth : authentications.values()) { if (auth instanceof OAuth) { - ((OAuth) auth).setAccessToken(accessToken); + ((OAuth) auth).setAccessToken(tokenSupplier); return; } } diff --git a/modules/openapi-generator/src/main/resources/Java/libraries/resttemplate/auth/OAuth.mustache b/modules/openapi-generator/src/main/resources/Java/libraries/resttemplate/auth/OAuth.mustache index 7889f1582dea..3c1d84f8acc1 100644 --- a/modules/openapi-generator/src/main/resources/Java/libraries/resttemplate/auth/OAuth.mustache +++ b/modules/openapi-generator/src/main/resources/Java/libraries/resttemplate/auth/OAuth.mustache @@ -1,24 +1,48 @@ package {{invokerPackage}}.auth; +import java.util.Optional; +import java.util.function.Supplier; import org.springframework.http.HttpHeaders; import org.springframework.util.MultiValueMap; +/** + * Provides support for RFC 6750 - Bearer Token usage for OAUTH 2.0 Authorization. + */ {{>generatedAnnotation}} public class OAuth implements Authentication { - private String accessToken; + private Supplier tokenSupplier; + /** + * Returns the bearer token used for Authorization. + * + * @return The bearer token + */ public String getAccessToken() { - return accessToken; + return tokenSupplier.get(); } + /** + * Sets the bearer access token used for Authorization. + * + * @param bearerToken The bearer token to send in the Authorization header + */ public void setAccessToken(String accessToken) { - this.accessToken = accessToken; + setAccessToken(() -> accessToken); + } + + /** + * Sets the supplier of bearer tokens used for Authorization. + * + * @param tokenSupplier The supplier of bearer tokens to send in the Authorization header + */ + public void setAccessToken(Supplier tokenSupplier) { + this.tokenSupplier = tokenSupplier; } @Override public void applyToParams(MultiValueMap queryParams, HttpHeaders headerParams, MultiValueMap cookieParams) { - if (accessToken != null) { - headerParams.add(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken); - } + Optional.ofNullable(tokenSupplier).map(Supplier::get).ifPresent(accessToken -> + headerParams.add(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken) + ); } } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java index 5bce92793776..27e156ca9d72 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java @@ -2889,4 +2889,38 @@ void shouldGenerateCorrectJaxbAnnotations(Library library) { .containsWithNameAndAttributes("XmlElement", Map.of("name", "\"item\"")) .containsWithNameAndAttributes("XmlElementWrapper", Map.of("name", "\"activities-array\"")); } + + + @Test + public void shouldGenerateOAuthTokenSuppliers() { + + final Map files = generateFromContract( + "src/test/resources/3_0/java/oauth.yaml", + JavaClientCodegen.RESTTEMPLATE + ); + + final JavaFileAssert apiClient = JavaFileAssert.assertThat(files.get("ApiClient.java")) + .printFileContent(); + apiClient + .assertMethod("setAccessToken", "String") + .bodyContainsLines("setAccessToken(() -> accessToken);"); + apiClient + .assertMethod("setAccessToken", "Supplier") + .bodyContainsLines("((OAuth) auth).setAccessToken(tokenSupplier);"); + + final JavaFileAssert oAuth = JavaFileAssert.assertThat(files.get("OAuth.java")) + .printFileContent(); + oAuth + .assertMethod("setAccessToken", "String") + .bodyContainsLines("setAccessToken(() -> accessToken);"); + oAuth + .assertMethod("setAccessToken", "Supplier") + .bodyContainsLines("this.tokenSupplier = tokenSupplier;"); + oAuth + .assertMethod("applyToParams") + .bodyContainsLines("Optional.ofNullable(tokenSupplier).map(Supplier::get).ifPresent(accessToken ->") + .bodyContainsLines("headerParams.add(HttpHeaders.AUTHORIZATION, \"Bearer \" + accessToken)"); + + } + } diff --git a/modules/openapi-generator/src/test/resources/3_0/java/oauth.yaml b/modules/openapi-generator/src/test/resources/3_0/java/oauth.yaml new file mode 100644 index 000000000000..af7e5c6e2d31 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/java/oauth.yaml @@ -0,0 +1,28 @@ +openapi: 3.0.3 + +info: + title: Test OAuth code generation + description: Tests OAuth code generation + version: 1.0.0 + +servers: + - url: http://localhost:8080 + +paths: + /api/something: + get: + responses: + 204: + description: Success! + +components: + securitySchemes: + oAuth: + type: oauth2 + flows: + implicit: + authorizationUrl: '' + scopes: {} + +security: + - oAuth: [] \ No newline at end of file diff --git a/samples/client/petstore/java/resttemplate-jakarta/src/main/java/org/openapitools/client/ApiClient.java b/samples/client/petstore/java/resttemplate-jakarta/src/main/java/org/openapitools/client/ApiClient.java index 9eec96b6455a..c477bdf31159 100644 --- a/samples/client/petstore/java/resttemplate-jakarta/src/main/java/org/openapitools/client/ApiClient.java +++ b/samples/client/petstore/java/resttemplate-jakarta/src/main/java/org/openapitools/client/ApiClient.java @@ -240,9 +240,18 @@ public void setApiKeyPrefix(String apiKeyPrefix) { * @param accessToken Access token */ public void setAccessToken(String accessToken) { + setAccessToken(() -> accessToken); + } + + /** + * Helper method to set the supplier of access tokens for OAuth2 authentication. + * + * @param tokenSupplier The supplier of bearer tokens + */ + public void setAccessToken(Supplier tokenSupplier) { for (Authentication auth : authentications.values()) { if (auth instanceof OAuth) { - ((OAuth) auth).setAccessToken(accessToken); + ((OAuth) auth).setAccessToken(tokenSupplier); return; } } diff --git a/samples/client/petstore/java/resttemplate-jakarta/src/main/java/org/openapitools/client/auth/OAuth.java b/samples/client/petstore/java/resttemplate-jakarta/src/main/java/org/openapitools/client/auth/OAuth.java index 4543e95105fc..179eebb6d4c9 100644 --- a/samples/client/petstore/java/resttemplate-jakarta/src/main/java/org/openapitools/client/auth/OAuth.java +++ b/samples/client/petstore/java/resttemplate-jakarta/src/main/java/org/openapitools/client/auth/OAuth.java @@ -1,24 +1,48 @@ package org.openapitools.client.auth; +import java.util.Optional; +import java.util.function.Supplier; import org.springframework.http.HttpHeaders; import org.springframework.util.MultiValueMap; +/** + * Provides support for RFC 6750 - Bearer Token usage for OAUTH 2.0 Authorization. + */ @jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.7.0-SNAPSHOT") public class OAuth implements Authentication { - private String accessToken; + private Supplier tokenSupplier; + /** + * Returns the bearer token used for Authorization. + * + * @return The bearer token + */ public String getAccessToken() { - return accessToken; + return tokenSupplier.get(); } + /** + * Sets the bearer access token used for Authorization. + * + * @param bearerToken The bearer token to send in the Authorization header + */ public void setAccessToken(String accessToken) { - this.accessToken = accessToken; + setAccessToken(() -> accessToken); + } + + /** + * Sets the supplier of bearer tokens used for Authorization. + * + * @param tokenSupplier The supplier of bearer tokens to send in the Authorization header + */ + public void setAccessToken(Supplier tokenSupplier) { + this.tokenSupplier = tokenSupplier; } @Override public void applyToParams(MultiValueMap queryParams, HttpHeaders headerParams, MultiValueMap cookieParams) { - if (accessToken != null) { - headerParams.add(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken); - } + Optional.ofNullable(tokenSupplier).map(Supplier::get).ifPresent(accessToken -> + headerParams.add(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken) + ); } } diff --git a/samples/client/petstore/java/resttemplate-swagger1/src/main/java/org/openapitools/client/ApiClient.java b/samples/client/petstore/java/resttemplate-swagger1/src/main/java/org/openapitools/client/ApiClient.java index fe39dffef0fc..d2b090cda529 100644 --- a/samples/client/petstore/java/resttemplate-swagger1/src/main/java/org/openapitools/client/ApiClient.java +++ b/samples/client/petstore/java/resttemplate-swagger1/src/main/java/org/openapitools/client/ApiClient.java @@ -240,9 +240,18 @@ public void setApiKeyPrefix(String apiKeyPrefix) { * @param accessToken Access token */ public void setAccessToken(String accessToken) { + setAccessToken(() -> accessToken); + } + + /** + * Helper method to set the supplier of access tokens for OAuth2 authentication. + * + * @param tokenSupplier The supplier of bearer tokens + */ + public void setAccessToken(Supplier tokenSupplier) { for (Authentication auth : authentications.values()) { if (auth instanceof OAuth) { - ((OAuth) auth).setAccessToken(accessToken); + ((OAuth) auth).setAccessToken(tokenSupplier); return; } } diff --git a/samples/client/petstore/java/resttemplate-swagger1/src/main/java/org/openapitools/client/auth/OAuth.java b/samples/client/petstore/java/resttemplate-swagger1/src/main/java/org/openapitools/client/auth/OAuth.java index 070bbec5bcab..b75429c83d68 100644 --- a/samples/client/petstore/java/resttemplate-swagger1/src/main/java/org/openapitools/client/auth/OAuth.java +++ b/samples/client/petstore/java/resttemplate-swagger1/src/main/java/org/openapitools/client/auth/OAuth.java @@ -1,24 +1,48 @@ package org.openapitools.client.auth; +import java.util.Optional; +import java.util.function.Supplier; import org.springframework.http.HttpHeaders; import org.springframework.util.MultiValueMap; +/** + * Provides support for RFC 6750 - Bearer Token usage for OAUTH 2.0 Authorization. + */ @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.7.0-SNAPSHOT") public class OAuth implements Authentication { - private String accessToken; + private Supplier tokenSupplier; + /** + * Returns the bearer token used for Authorization. + * + * @return The bearer token + */ public String getAccessToken() { - return accessToken; + return tokenSupplier.get(); } + /** + * Sets the bearer access token used for Authorization. + * + * @param bearerToken The bearer token to send in the Authorization header + */ public void setAccessToken(String accessToken) { - this.accessToken = accessToken; + setAccessToken(() -> accessToken); + } + + /** + * Sets the supplier of bearer tokens used for Authorization. + * + * @param tokenSupplier The supplier of bearer tokens to send in the Authorization header + */ + public void setAccessToken(Supplier tokenSupplier) { + this.tokenSupplier = tokenSupplier; } @Override public void applyToParams(MultiValueMap queryParams, HttpHeaders headerParams, MultiValueMap cookieParams) { - if (accessToken != null) { - headerParams.add(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken); - } + Optional.ofNullable(tokenSupplier).map(Supplier::get).ifPresent(accessToken -> + headerParams.add(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken) + ); } } diff --git a/samples/client/petstore/java/resttemplate-swagger2/src/main/java/org/openapitools/client/ApiClient.java b/samples/client/petstore/java/resttemplate-swagger2/src/main/java/org/openapitools/client/ApiClient.java index fe39dffef0fc..d2b090cda529 100644 --- a/samples/client/petstore/java/resttemplate-swagger2/src/main/java/org/openapitools/client/ApiClient.java +++ b/samples/client/petstore/java/resttemplate-swagger2/src/main/java/org/openapitools/client/ApiClient.java @@ -240,9 +240,18 @@ public void setApiKeyPrefix(String apiKeyPrefix) { * @param accessToken Access token */ public void setAccessToken(String accessToken) { + setAccessToken(() -> accessToken); + } + + /** + * Helper method to set the supplier of access tokens for OAuth2 authentication. + * + * @param tokenSupplier The supplier of bearer tokens + */ + public void setAccessToken(Supplier tokenSupplier) { for (Authentication auth : authentications.values()) { if (auth instanceof OAuth) { - ((OAuth) auth).setAccessToken(accessToken); + ((OAuth) auth).setAccessToken(tokenSupplier); return; } } diff --git a/samples/client/petstore/java/resttemplate-swagger2/src/main/java/org/openapitools/client/auth/OAuth.java b/samples/client/petstore/java/resttemplate-swagger2/src/main/java/org/openapitools/client/auth/OAuth.java index 070bbec5bcab..b75429c83d68 100644 --- a/samples/client/petstore/java/resttemplate-swagger2/src/main/java/org/openapitools/client/auth/OAuth.java +++ b/samples/client/petstore/java/resttemplate-swagger2/src/main/java/org/openapitools/client/auth/OAuth.java @@ -1,24 +1,48 @@ package org.openapitools.client.auth; +import java.util.Optional; +import java.util.function.Supplier; import org.springframework.http.HttpHeaders; import org.springframework.util.MultiValueMap; +/** + * Provides support for RFC 6750 - Bearer Token usage for OAUTH 2.0 Authorization. + */ @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.7.0-SNAPSHOT") public class OAuth implements Authentication { - private String accessToken; + private Supplier tokenSupplier; + /** + * Returns the bearer token used for Authorization. + * + * @return The bearer token + */ public String getAccessToken() { - return accessToken; + return tokenSupplier.get(); } + /** + * Sets the bearer access token used for Authorization. + * + * @param bearerToken The bearer token to send in the Authorization header + */ public void setAccessToken(String accessToken) { - this.accessToken = accessToken; + setAccessToken(() -> accessToken); + } + + /** + * Sets the supplier of bearer tokens used for Authorization. + * + * @param tokenSupplier The supplier of bearer tokens to send in the Authorization header + */ + public void setAccessToken(Supplier tokenSupplier) { + this.tokenSupplier = tokenSupplier; } @Override public void applyToParams(MultiValueMap queryParams, HttpHeaders headerParams, MultiValueMap cookieParams) { - if (accessToken != null) { - headerParams.add(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken); - } + Optional.ofNullable(tokenSupplier).map(Supplier::get).ifPresent(accessToken -> + headerParams.add(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken) + ); } } diff --git a/samples/client/petstore/java/resttemplate-withXml/src/main/java/org/openapitools/client/ApiClient.java b/samples/client/petstore/java/resttemplate-withXml/src/main/java/org/openapitools/client/ApiClient.java index ec6fdaa118bf..558506668a52 100644 --- a/samples/client/petstore/java/resttemplate-withXml/src/main/java/org/openapitools/client/ApiClient.java +++ b/samples/client/petstore/java/resttemplate-withXml/src/main/java/org/openapitools/client/ApiClient.java @@ -303,9 +303,18 @@ public void setApiKeyPrefix(String apiKeyPrefix) { * @param accessToken Access token */ public void setAccessToken(String accessToken) { + setAccessToken(() -> accessToken); + } + + /** + * Helper method to set the supplier of access tokens for OAuth2 authentication. + * + * @param tokenSupplier The supplier of bearer tokens + */ + public void setAccessToken(Supplier tokenSupplier) { for (Authentication auth : authentications.values()) { if (auth instanceof OAuth) { - ((OAuth) auth).setAccessToken(accessToken); + ((OAuth) auth).setAccessToken(tokenSupplier); return; } } diff --git a/samples/client/petstore/java/resttemplate-withXml/src/main/java/org/openapitools/client/auth/OAuth.java b/samples/client/petstore/java/resttemplate-withXml/src/main/java/org/openapitools/client/auth/OAuth.java index 070bbec5bcab..b75429c83d68 100644 --- a/samples/client/petstore/java/resttemplate-withXml/src/main/java/org/openapitools/client/auth/OAuth.java +++ b/samples/client/petstore/java/resttemplate-withXml/src/main/java/org/openapitools/client/auth/OAuth.java @@ -1,24 +1,48 @@ package org.openapitools.client.auth; +import java.util.Optional; +import java.util.function.Supplier; import org.springframework.http.HttpHeaders; import org.springframework.util.MultiValueMap; +/** + * Provides support for RFC 6750 - Bearer Token usage for OAUTH 2.0 Authorization. + */ @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.7.0-SNAPSHOT") public class OAuth implements Authentication { - private String accessToken; + private Supplier tokenSupplier; + /** + * Returns the bearer token used for Authorization. + * + * @return The bearer token + */ public String getAccessToken() { - return accessToken; + return tokenSupplier.get(); } + /** + * Sets the bearer access token used for Authorization. + * + * @param bearerToken The bearer token to send in the Authorization header + */ public void setAccessToken(String accessToken) { - this.accessToken = accessToken; + setAccessToken(() -> accessToken); + } + + /** + * Sets the supplier of bearer tokens used for Authorization. + * + * @param tokenSupplier The supplier of bearer tokens to send in the Authorization header + */ + public void setAccessToken(Supplier tokenSupplier) { + this.tokenSupplier = tokenSupplier; } @Override public void applyToParams(MultiValueMap queryParams, HttpHeaders headerParams, MultiValueMap cookieParams) { - if (accessToken != null) { - headerParams.add(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken); - } + Optional.ofNullable(tokenSupplier).map(Supplier::get).ifPresent(accessToken -> + headerParams.add(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken) + ); } } diff --git a/samples/client/petstore/java/resttemplate/src/main/java/org/openapitools/client/ApiClient.java b/samples/client/petstore/java/resttemplate/src/main/java/org/openapitools/client/ApiClient.java index 1292dc1732c1..00c6748904be 100644 --- a/samples/client/petstore/java/resttemplate/src/main/java/org/openapitools/client/ApiClient.java +++ b/samples/client/petstore/java/resttemplate/src/main/java/org/openapitools/client/ApiClient.java @@ -298,9 +298,18 @@ public void setApiKeyPrefix(String apiKeyPrefix) { * @param accessToken Access token */ public void setAccessToken(String accessToken) { + setAccessToken(() -> accessToken); + } + + /** + * Helper method to set the supplier of access tokens for OAuth2 authentication. + * + * @param tokenSupplier The supplier of bearer tokens + */ + public void setAccessToken(Supplier tokenSupplier) { for (Authentication auth : authentications.values()) { if (auth instanceof OAuth) { - ((OAuth) auth).setAccessToken(accessToken); + ((OAuth) auth).setAccessToken(tokenSupplier); return; } } diff --git a/samples/client/petstore/java/resttemplate/src/main/java/org/openapitools/client/auth/OAuth.java b/samples/client/petstore/java/resttemplate/src/main/java/org/openapitools/client/auth/OAuth.java index 070bbec5bcab..b75429c83d68 100644 --- a/samples/client/petstore/java/resttemplate/src/main/java/org/openapitools/client/auth/OAuth.java +++ b/samples/client/petstore/java/resttemplate/src/main/java/org/openapitools/client/auth/OAuth.java @@ -1,24 +1,48 @@ package org.openapitools.client.auth; +import java.util.Optional; +import java.util.function.Supplier; import org.springframework.http.HttpHeaders; import org.springframework.util.MultiValueMap; +/** + * Provides support for RFC 6750 - Bearer Token usage for OAUTH 2.0 Authorization. + */ @javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.7.0-SNAPSHOT") public class OAuth implements Authentication { - private String accessToken; + private Supplier tokenSupplier; + /** + * Returns the bearer token used for Authorization. + * + * @return The bearer token + */ public String getAccessToken() { - return accessToken; + return tokenSupplier.get(); } + /** + * Sets the bearer access token used for Authorization. + * + * @param bearerToken The bearer token to send in the Authorization header + */ public void setAccessToken(String accessToken) { - this.accessToken = accessToken; + setAccessToken(() -> accessToken); + } + + /** + * Sets the supplier of bearer tokens used for Authorization. + * + * @param tokenSupplier The supplier of bearer tokens to send in the Authorization header + */ + public void setAccessToken(Supplier tokenSupplier) { + this.tokenSupplier = tokenSupplier; } @Override public void applyToParams(MultiValueMap queryParams, HttpHeaders headerParams, MultiValueMap cookieParams) { - if (accessToken != null) { - headerParams.add(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken); - } + Optional.ofNullable(tokenSupplier).map(Supplier::get).ifPresent(accessToken -> + headerParams.add(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken) + ); } }