[CORE] Add support for HTTP signature (#4993)

* Add support for HTTP signature

* Add http-signature security scheme

* add http_signature_test to security scheme

* Add separate OAS file with support for HTTP signature

* change URL of apache license to use https

* add log warning to indicate the 'http signature' security scheme is still a draft
This commit is contained in:
Sebastien Rosset 2020-01-26 08:48:22 -08:00 committed by Jim Schubert
parent d8c9f25b10
commit 20afa870a9
5 changed files with 1818 additions and 4 deletions

View File

@ -29,8 +29,11 @@ public class CodegenSecurity {
public String type;
public String scheme;
public Boolean hasMore, isBasic, isOAuth, isApiKey;
// is Basic is true for all http authentication type. Those are to differentiate basic and bearer authentication
public Boolean isBasicBasic, isBasicBearer;
// is Basic is true for all http authentication type.
// Those are to differentiate basic and bearer authentication
// isHttpSignature is to support HTTP signature authorization scheme.
// https://datatracker.ietf.org/doc/draft-cavage-http-signatures/
public Boolean isBasicBasic, isBasicBearer, isHttpSignature;
public String bearerFormat;
public Map<String, Object> vendorExtensions = new HashMap<String, Object>();
// ApiKey specific
@ -50,6 +53,7 @@ public class CodegenSecurity {
filteredSecurity.hasMore = false;
filteredSecurity.isBasic = isBasic;
filteredSecurity.isBasicBasic = isBasicBasic;
filteredSecurity.isHttpSignature = isHttpSignature;
filteredSecurity.isBasicBearer = isBasicBearer;
filteredSecurity.isApiKey = isApiKey;
filteredSecurity.isOAuth = isOAuth;
@ -97,6 +101,7 @@ public class CodegenSecurity {
Objects.equals(isOAuth, that.isOAuth) &&
Objects.equals(isApiKey, that.isApiKey) &&
Objects.equals(isBasicBasic, that.isBasicBasic) &&
Objects.equals(isHttpSignature, that.isHttpSignature) &&
Objects.equals(isBasicBearer, that.isBasicBearer) &&
Objects.equals(bearerFormat, that.bearerFormat) &&
Objects.equals(vendorExtensions, that.vendorExtensions) &&
@ -117,8 +122,9 @@ public class CodegenSecurity {
@Override
public int hashCode() {
return Objects.hash(name, type, scheme, hasMore, isBasic, isOAuth, isApiKey, isBasicBasic, isBasicBearer,
bearerFormat, vendorExtensions, keyParamName, isKeyInQuery, isKeyInHeader, isKeyInCookie, flow,
return Objects.hash(name, type, scheme, hasMore, isBasic, isOAuth, isApiKey,
isBasicBasic, isHttpSignature, isBasicBearer, bearerFormat, vendorExtensions,
keyParamName, isKeyInQuery, isKeyInHeader, isKeyInCookie, flow,
authorizationUrl, tokenUrl, scopes, isCode, isPassword, isApplication, isImplicit);
}
@ -133,6 +139,7 @@ public class CodegenSecurity {
sb.append(", isOAuth=").append(isOAuth);
sb.append(", isApiKey=").append(isApiKey);
sb.append(", isBasicBasic=").append(isBasicBasic);
sb.append(", isHttpSignature=").append(isHttpSignature);
sb.append(", isBasicBearer=").append(isBasicBearer);
sb.append(", bearerFormat='").append(bearerFormat).append('\'');
sb.append(", vendorExtensions=").append(vendorExtensions);

View File

@ -3617,6 +3617,7 @@ public class DefaultCodegen implements CodegenConfig {
cs.name = key;
cs.type = securityScheme.getType().toString();
cs.isCode = cs.isPassword = cs.isApplication = cs.isImplicit = false;
cs.isHttpSignature = false;
cs.isBasicBasic = cs.isBasicBearer = false;
cs.scheme = securityScheme.getScheme();
if (securityScheme.getExtensions() != null) {
@ -3638,6 +3639,14 @@ public class DefaultCodegen implements CodegenConfig {
} else if ("bearer".equals(securityScheme.getScheme())) {
cs.isBasicBearer = true;
cs.bearerFormat = securityScheme.getBearerFormat();
} else if ("signature".equals(securityScheme.getScheme())) {
// HTTP signature as defined in https://datatracker.ietf.org/doc/draft-cavage-http-signatures/
// The registry of security schemes is maintained by IANA.
// https://www.iana.org/assignments/http-authschemes/http-authschemes.xhtml
// As of January 2020, the "signature" scheme has not been registered with IANA yet.
// This scheme may have to be changed when it is officially registered with IANA.
cs.isHttpSignature = true;
LOGGER.warn("Security scheme 'HTTP signature' is a draft IETF RFC and subject to change.");
}
} else if (SecurityScheme.Type.OAUTH2.equals(securityScheme.getType())) {
cs.isKeyInHeader = cs.isKeyInQuery = cs.isKeyInCookie = cs.isApiKey = cs.isBasic = false;

View File

@ -42,6 +42,7 @@ import org.openapitools.codegen.serializer.SerializerUtils;
import org.openapitools.codegen.templating.MustacheEngineAdapter;
import org.openapitools.codegen.utils.ImplementationVersion;
import org.openapitools.codegen.utils.ModelUtils;
import org.openapitools.codegen.utils.ProcessUtils;
import org.openapitools.codegen.utils.URLPathUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -851,6 +852,9 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
if (hasBearerMethods(authMethods)) {
bundle.put("hasBearerMethods", true);
}
if (ProcessUtils.hasHttpSignatureMethods(authMethods)) {
bundle.put("hasHttpSignatureMethods", true);
}
}
List<CodegenServer> servers = config.fromServers(openAPI.getServers());

View File

@ -94,4 +94,22 @@ public class ProcessUtils {
return false;
}
/**
* Returns true if the specified OAS model has at least one operation with the HTTP signature
* security scheme.
* The HTTP signature scheme is defined in https://datatracker.ietf.org/doc/draft-cavage-http-signatures/
*
* @param authMethods List of auth methods.
* @return True if at least one operation has HTTP signature security schema defined
*/
public static boolean hasHttpSignatureMethods(List<CodegenSecurity> authMethods) {
if (authMethods != null && !authMethods.isEmpty()) {
for (CodegenSecurity cs : authMethods) {
if (Boolean.TRUE.equals(cs.isHttpSignature)) {
return true;
}
}
}
return false;
}
}