Add helper methods to determine if the spec has certain authentication defined (#6347)

* better import, add security methods

* add helper method to determine auth type when adding supporting files

* better docstrings

* fix boolean return

* update tests

* Revert "update tests"

This reverts commit 29cfc8ad663234ee20c73ac7be9c4dd2235ac34f.

* add test in shippable

* rename variables

* check if auth files are needed

* update tests

* revert check

* set java8 to true

* fix auth check

* better npe handling

* reoder methods

* undo changes to shippable.yml
This commit is contained in:
William Cheng 2020-05-22 12:57:44 +08:00 committed by GitHub
parent 69177517ef
commit f10de73ed5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 191 additions and 113 deletions

View File

@ -926,13 +926,13 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
bundle.put("authMethods", authMethods);
bundle.put("hasAuthMethods", true);
if (hasOAuthMethods(authMethods)) {
if (ProcessUtils.hasOAuthMethods(authMethods)) {
bundle.put("hasOAuthMethods", true);
bundle.put("oauthMethods", getOAuthMethods(authMethods));
bundle.put("oauthMethods", ProcessUtils.getOAuthMethods(authMethods));
}
if (hasBearerMethods(authMethods)) {
bundle.put("hasBearerMethods", true);
if (ProcessUtils.hasHttpBearerMethods(authMethods)) {
bundle.put("hasHttpBearerMethods", true);
}
if (ProcessUtils.hasHttpSignatureMethods(authMethods)) {
bundle.put("hasHttpSignatureMethods", true);
@ -1445,37 +1445,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
return result;
}
private boolean hasOAuthMethods(List<CodegenSecurity> authMethods) {
for (CodegenSecurity cs : authMethods) {
if (Boolean.TRUE.equals(cs.isOAuth)) {
return true;
}
}
return false;
}
private boolean hasBearerMethods(List<CodegenSecurity> authMethods) {
for (CodegenSecurity cs : authMethods) {
if (Boolean.TRUE.equals(cs.isBasicBearer)) {
return true;
}
}
return false;
}
private List<CodegenSecurity> getOAuthMethods(List<CodegenSecurity> authMethods) {
List<CodegenSecurity> oauthMethods = new ArrayList<>();
for (CodegenSecurity cs : authMethods) {
if (Boolean.TRUE.equals(cs.isOAuth)) {
oauthMethods.add(cs);
}
}
return oauthMethods;
}
protected File writeInputStreamToFile(String filename, InputStream in, String templateFile) throws IOException {
if (in != null) {

View File

@ -106,9 +106,6 @@ public class JavaClientCodegen extends AbstractJavaCodegen
protected String authFolder;
protected String serializationLibrary = null;
protected boolean addOAuthSupportingFiles = false;
protected boolean addOAuthRetrySupportingFiles = false;
public JavaClientCodegen() {
super();
@ -320,10 +317,8 @@ public class JavaClientCodegen extends AbstractJavaCodegen
supportingFiles.add(new SupportingFile("auth/HttpBasicAuth.mustache", authFolder, "HttpBasicAuth.java"));
supportingFiles.add(new SupportingFile("auth/HttpBearerAuth.mustache", authFolder, "HttpBearerAuth.java"));
supportingFiles.add(new SupportingFile("auth/ApiKeyAuth.mustache", authFolder, "ApiKeyAuth.java"));
// NOTE: below moved to postProcessOperationsWithModels
//supportingFiles.add(new SupportingFile("auth/OAuth.mustache", authFolder, "OAuth.java"));
//supportingFiles.add(new SupportingFile("auth/OAuthFlow.mustache", authFolder, "OAuthFlow.java"));
}
supportingFiles.add(new SupportingFile("gradlew.mustache", "", "gradlew"));
supportingFiles.add(new SupportingFile("gradlew.bat.mustache", "", "gradlew.bat"));
supportingFiles.add(new SupportingFile("gradle-wrapper.properties.mustache",
@ -516,6 +511,22 @@ public class JavaClientCodegen extends AbstractJavaCodegen
additionalProperties.remove(SERIALIZATION_LIBRARY_GSON);
}
// authentication related files
// has OAuth defined
if (ProcessUtils.hasOAuthMethods(openAPI)) {
// for okhttp-gson (default), check to see if OAuth is defined and included OAuth-related files accordingly
if ((OKHTTP_GSON.equals(getLibrary()) || StringUtils.isEmpty(getLibrary()))) {
supportingFiles.add(new SupportingFile("auth/OAuthOkHttpClient.mustache", authFolder, "OAuthOkHttpClient.java"));
supportingFiles.add(new SupportingFile("auth/RetryingOAuth.mustache", authFolder, "RetryingOAuth.java"));
}
// google-api-client doesn't use the OpenAPI auth, because it uses Google Credential directly (HttpRequestInitializer)
if (!(GOOGLE_API_CLIENT.equals(getLibrary()) || REST_ASSURED.equals(getLibrary()) || usePlayWS
|| NATIVE.equals(getLibrary()) || MICROPROFILE.equals(getLibrary()))) {
supportingFiles.add(new SupportingFile("auth/OAuth.mustache", authFolder, "OAuth.java"));
supportingFiles.add(new SupportingFile("auth/OAuthFlow.mustache", authFolder, "OAuthFlow.java"));
}
}
}
private boolean usesAnyRetrofitLibrary() {
@ -591,24 +602,6 @@ public class JavaClientCodegen extends AbstractJavaCodegen
}
}
// has OAuth defined
if (ProcessUtils.hasOAuthMethods(objs)) {
// for okhttp-gson (default), check to see if OAuth is defined and included OAuth-related files accordingly
if ((OKHTTP_GSON.equals(getLibrary()) || StringUtils.isEmpty(getLibrary())) && !addOAuthRetrySupportingFiles) {
supportingFiles.add(new SupportingFile("auth/OAuthOkHttpClient.mustache", authFolder, "OAuthOkHttpClient.java"));
supportingFiles.add(new SupportingFile("auth/RetryingOAuth.mustache", authFolder, "RetryingOAuth.java"));
addOAuthRetrySupportingFiles = true; // add only once
}
// google-api-client doesn't use the OpenAPI auth, because it uses Google Credential directly (HttpRequestInitializer)
if (!(GOOGLE_API_CLIENT.equals(getLibrary()) || REST_ASSURED.equals(getLibrary()) || usePlayWS
|| NATIVE.equals(getLibrary()) || MICROPROFILE.equals(getLibrary())) && !addOAuthSupportingFiles) {
supportingFiles.add(new SupportingFile("auth/OAuth.mustache", authFolder, "OAuth.java"));
supportingFiles.add(new SupportingFile("auth/OAuthFlow.mustache", authFolder, "OAuthFlow.java"));
addOAuthSupportingFiles = true; // add only once
}
}
if (MICROPROFILE.equals(getLibrary())) {
objs = AbstractJavaJAXRSServerCodegen.jaxrsPostProcessOperations(objs);
}

View File

@ -1,17 +1,16 @@
package org.openapitools.codegen.utils;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.openapitools.codegen.CodegenModel;
import org.openapitools.codegen.CodegenOperation;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.CodegenSecurity;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class ProcessUtils {
private static Boolean hasOAuthMethods;
/**
* Add x-index extension to the model's properties
*
@ -34,9 +33,7 @@ public class ProcessUtils {
var.vendorExtensions.put("x-index", j);
j++;
}
}
}
/**
@ -48,53 +45,6 @@ public class ProcessUtils {
addIndexToProperties(models, 0);
}
/**
* Returns true if at least one operation has OAuth security schema defined
*
* @param objs Map of operations
* @return True if at least one operation has OAuth security schema defined
*/
public static boolean hasOAuthMethods(Map<String, Object> objs) {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
if (operations != null) {
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation operation : ops) {
if (operation.authMethods != null && !operation.authMethods.isEmpty()) {
for (CodegenSecurity cs : operation.authMethods) {
if (Boolean.TRUE.equals(cs.isOAuth)) {
return true;
}
}
}
}
}
return false;
}
/**
* Returns true if at least one operation has Bearer security schema defined
*
* @param objs Map of operations
* @return True if at least one operation has Bearer security schema defined
*/
public static boolean hasBearerMethods(Map<String, Object> objs) {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
if (operations != null) {
List<CodegenOperation> ops = (List<CodegenOperation>) operations.get("operation");
for (CodegenOperation operation : ops) {
if (operation.authMethods != null && !operation.authMethods.isEmpty()) {
for (CodegenSecurity cs : operation.authMethods) {
if (Boolean.TRUE.equals(cs.isBasicBearer)) {
return true;
}
}
}
}
}
return false;
}
/**
* Returns true if the specified OAS model has at least one operation with the HTTP basic
* security scheme.
@ -148,4 +98,159 @@ public class ProcessUtils {
}
return false;
}
/**
* Returns true if the specified OAS model has at least one operation with HTTP bearer.
*
* @param authMethods List of auth methods.
* @return True if at least one operation has HTTP bearer security scheme defined
*/
public static boolean hasHttpBearerMethods(List<CodegenSecurity> authMethods) {
if (authMethods != null && !authMethods.isEmpty()) {
for (CodegenSecurity cs : authMethods) {
if (Boolean.TRUE.equals(cs.isBasicBasic)) {
return true;
}
}
}
return false;
}
/**
* Returns true if the specified OAS model has at least one operation with OAuth.
*
* @param authMethods List of auth methods.
* @return True if at least one operation has OAuth security scheme defined
*/
public static boolean hasOAuthMethods(List<CodegenSecurity> authMethods) {
for (CodegenSecurity cs : authMethods) {
if (Boolean.TRUE.equals(cs.isOAuth)) {
return true;
}
}
return false;
}
/**
* Returns a list of OAuth Codegen security objects
*
* @param authMethods List of auth methods.
* @return A list of OAuth Codegen security objects
*/
public static List<CodegenSecurity> getOAuthMethods(List<CodegenSecurity> authMethods) {
List<CodegenSecurity> oauthMethods = new ArrayList<>();
for (CodegenSecurity cs : authMethods) {
if (Boolean.TRUE.equals(cs.isOAuth)) {
oauthMethods.add(cs);
}
}
return oauthMethods;
}
/**
* Returns true if the specified OAS model has at least one operation with OAuth authentication.
*
* @param openAPI An instance of OpenAPI
* @return True if at least one operation has OAuth security scheme defined
*/
public static boolean hasOAuthMethods(OpenAPI openAPI) {
final Map<String, SecurityScheme> securitySchemes = getSecuritySchemes(openAPI);
if (securitySchemes != null) {
for (Map.Entry<String, SecurityScheme> scheme : securitySchemes.entrySet()) {
if (SecurityScheme.Type.OAUTH2.equals(scheme.getValue().getType())) {
return true;
}
}
}
return false;
}
/**
* Returns true if the specified OAS model has at least one operation with HTTP bearer authentication.
*
* @param openAPI An instance of OpenAPI
* @return True if at least one operation has HTTP bearer security scheme defined
*/
public static boolean hasHttpBearerMethods(OpenAPI openAPI) {
final Map<String, SecurityScheme> securitySchemes = getSecuritySchemes(openAPI);
if (securitySchemes != null) {
for (Map.Entry<String, SecurityScheme> scheme : securitySchemes.entrySet()) {
if (SecurityScheme.Type.HTTP.equals(scheme.getValue().getType()) && "bearer".equals(scheme.getValue().getScheme())) {
return true;
}
}
}
return false;
}
/**
* Returns true if the specified OAS model has at least one operation with HTTP basic authentication.
*
* @param openAPI An instance of OpenAPI
* @return True if at least one operation has HTTP basic security scheme defined
*/
public static boolean hasHttpBasicMethods(OpenAPI openAPI) {
final Map<String, SecurityScheme> securitySchemes = getSecuritySchemes(openAPI);
if (securitySchemes != null) {
for (Map.Entry<String, SecurityScheme> scheme : securitySchemes.entrySet()) {
if (SecurityScheme.Type.HTTP.equals(scheme.getValue().getType()) && "basic".equals(scheme.getValue().getScheme())) {
return true;
}
}
}
return false;
}
/**
* Returns true if the specified OAS model has at least one operation with HTTP signature authentication.
*
* @param openAPI An instance of OpenAPI
* @return True if at least one operation has HTTP signature security scheme defined
*/
public static boolean hasHttpSignatureMethods(OpenAPI openAPI) {
final Map<String, SecurityScheme> securitySchemes = getSecuritySchemes(openAPI);
if (securitySchemes != null) {
for (Map.Entry<String, SecurityScheme> scheme : securitySchemes.entrySet()) {
if (SecurityScheme.Type.HTTP.equals(scheme.getValue().getType()) && "signature".equals(scheme.getValue().getScheme())) {
return true;
}
}
}
return false;
}
/**
* Returns true if the specified OAS model has at least one operation with API key authentication.
*
* @param openAPI An instance of OpenAPI
* @return True if at least one operation has API key security scheme defined
*/
public static boolean hasApiKeyMethods(OpenAPI openAPI) {
final Map<String, SecurityScheme> securitySchemes = getSecuritySchemes(openAPI);
if (securitySchemes != null) {
for (Map.Entry<String, SecurityScheme> scheme : securitySchemes.entrySet()) {
if (SecurityScheme.Type.APIKEY.equals(scheme.getValue().getType())) {
return true;
}
}
}
return false;
}
public static Map<String, SecurityScheme> getSecuritySchemes(OpenAPI openAPI) {
if (openAPI == null) {
return null;
} else {
return openAPI.getComponents() != null ? openAPI.getComponents().getSecuritySchemes() : null;
}
}
}

View File

@ -137,7 +137,9 @@ ext {
{{#hasOAuthMethods}}
scribejava_apis_version = "6.9.0"
{{/hasOAuthMethods}}
{{#hasHttpBasicMethods}}
tomitribe_http_signatures_version = "1.3"
{{/hasHttpBasicMethods}}
}
dependencies {
@ -159,7 +161,9 @@ dependencies {
{{#hasOAuthMethods}}
compile "com.github.scribejava:scribejava-apis:$scribejava_apis_version"
{{/hasOAuthMethods}}
{{#hasHttpBasicMethods}}
compile "org.tomitribe:tomitribe-http-signatures:$tomitribe_http_signatures_version"
{{/hasHttpBasicMethods}}
{{#supportJava6}}
compile "commons-io:commons-io:$commons_io_version"
compile "org.apache.commons:commons-lang3:$commons_lang3_version"

View File

@ -28,7 +28,9 @@ lazy val root = (project in file(".")).
{{#hasOAuthMethods}}
"com.github.scribejava" % "scribejava-apis" % "6.9.0" % "compile",
{{/hasOAuthMethods}}
{{#hasHttpBasicMethods}}
"org.tomitribe" % "tomitribe-http-signatures" % "1.3" % "compile",
{{/hasHttpBasicMethods}}
{{^java8}}
"com.brsanthu" % "migbase64" % "2.2",
{{/java8}}

View File

@ -338,11 +338,13 @@
<version>${commons-io-version}</version>
</dependency>
{{/supportJava6}}
{{#hasHttpBasicMethods}}
<dependency>
<groupId>org.tomitribe</groupId>
<artifactId>tomitribe-http-signatures</artifactId>
<version>${http-signature-version}</version>
</dependency>
{{/hasHttpBasicMethods}}
{{#hasOAuthMethods}}
<dependency>
<groupId>com.github.scribejava</groupId>
@ -385,7 +387,9 @@
<threetenbp-version>2.9.10</threetenbp-version>
{{/threetenbp}}
<junit-version>4.13</junit-version>
{{#hasHttpBasicMethods}}
<http-signature-version>1.4</http-signature-version>
{{/hasHttpBasicMethods}}
{{#hasOAuthMethods}}
<scribejava-apis-version>6.9.0</scribejava-apis-version>
{{/hasOAuthMethods}}

View File

@ -293,8 +293,8 @@ public class JavaClientCodegenTest {
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/ApiResponse.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/ServerConfiguration.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/ServerVariable.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/auth/ApiKeyAuth.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/auth/Authentication.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/auth/ApiKeyAuth.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/auth/HttpBasicAuth.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/auth/HttpBearerAuth.java");
//TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/xyz/abcdef/auth/OAuth.java");
@ -370,8 +370,8 @@ public class JavaClientCodegenTest {
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/ApiResponse.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/ServerConfiguration.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/ServerVariable.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/auth/ApiKeyAuth.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/auth/Authentication.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/auth/ApiKeyAuth.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/auth/HttpBasicAuth.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/auth/HttpBearerAuth.java");
TestUtils.ensureContainsFile(generatedFiles, output, "src/main/java/zz/yyyy/invoker/xxxx/Configuration.java");