diff --git a/aws/smithy-aws-apigateway-openapi/src/main/java/software/amazon/smithy/aws/apigateway/openapi/AddAuthorizers.java b/aws/smithy-aws-apigateway-openapi/src/main/java/software/amazon/smithy/aws/apigateway/openapi/AddAuthorizers.java index d4e9c15af54..1e38ca684b0 100644 --- a/aws/smithy-aws-apigateway-openapi/src/main/java/software/amazon/smithy/aws/apigateway/openapi/AddAuthorizers.java +++ b/aws/smithy-aws-apigateway-openapi/src/main/java/software/amazon/smithy/aws/apigateway/openapi/AddAuthorizers.java @@ -97,8 +97,7 @@ private OpenApi addComputedAuthorizers(Context context, OpenApi openApi, Authori if (converter.getAuthSchemeName().equals(scheme)) { SecurityScheme createdScheme = converter.createSecurityScheme(context); SecurityScheme.Builder schemeBuilder = createdScheme.toBuilder(); - schemeBuilder.putExtension( - CLIENT_EXTENSION_NAME, determineApiGatewayClientName(authorizer.getScheme())); + schemeBuilder.putExtension(CLIENT_EXTENSION_NAME, authorizer.getAuthType()); ObjectNode authorizerNode = Node.objectNodeBuilder() .withOptionalMember("type", authorizer.getType().map(Node::from)) @@ -124,13 +123,4 @@ private OpenApi addComputedAuthorizers(Context context, OpenApi openApi, Authori builder.components(components.build()); return builder.build(); } - - // TODO: should this also allow overrides via configuration properties? - private static String determineApiGatewayClientName(String value) { - if (value.equals("aws.v4")) { - return "awsSigv4"; - } else { - return "custom"; - } - } } diff --git a/aws/smithy-aws-apigateway-openapi/src/test/java/software/amazon/smithy/aws/apigateway/openapi/AddAuthorizersTest.java b/aws/smithy-aws-apigateway-openapi/src/test/java/software/amazon/smithy/aws/apigateway/openapi/AddAuthorizersTest.java index 410181435c4..fe695a8c8d0 100644 --- a/aws/smithy-aws-apigateway-openapi/src/test/java/software/amazon/smithy/aws/apigateway/openapi/AddAuthorizersTest.java +++ b/aws/smithy-aws-apigateway-openapi/src/test/java/software/amazon/smithy/aws/apigateway/openapi/AddAuthorizersTest.java @@ -75,4 +75,24 @@ public void addsOnlyAuthType() { assertThat(sigV4.getExtension("x-amazon-apigateway-authtype").get(), equalTo(Node.from("awsSigv4"))); assertFalse(sigV4.getExtension("x-amazon-apigateway-authorizer").isPresent()); } + + @Test + public void addsCustomAuthType() { + Model model = Model.assembler() + .discoverModels(getClass().getClassLoader()) + .addImport(getClass().getResource("custom-auth-type-authorizer.json")) + .assemble() + .unwrap(); + OpenApi result = OpenApiConverter.create() + .classLoader(getClass().getClassLoader()) + .convert(model, ShapeId.from("ns.foo#SomeService")); + SecurityScheme sigV4 = result.getComponents().getSecuritySchemes().get("sigv4"); + + assertThat(result.getComponents().getSecuritySchemes().get("aws.v4"), nullValue()); + assertThat(sigV4.getType(), equalTo("apiKey")); + assertThat(sigV4.getName().get(), equalTo("Authorization")); + assertThat(sigV4.getIn().get(), equalTo("header")); + assertThat(sigV4.getExtension("x-amazon-apigateway-authtype").get(), equalTo(Node.from("myCustomType"))); + assertFalse(sigV4.getExtension("x-amazon-apigateway-authorizer").isPresent()); + } } diff --git a/aws/smithy-aws-apigateway-openapi/src/test/resources/software/amazon/smithy/aws/apigateway/openapi/custom-auth-type-authorizer.json b/aws/smithy-aws-apigateway-openapi/src/test/resources/software/amazon/smithy/aws/apigateway/openapi/custom-auth-type-authorizer.json new file mode 100644 index 00000000000..20c9a4c2ff3 --- /dev/null +++ b/aws/smithy-aws-apigateway-openapi/src/test/resources/software/amazon/smithy/aws/apigateway/openapi/custom-auth-type-authorizer.json @@ -0,0 +1,19 @@ +{ + "smithy": "0.4.0", + "ns.foo": { + "shapes": { + "SomeService": { + "type": "service", + "version": "2018-03-17", + "protocols": [{"name": "aws.rest-json", "auth": ["aws.v4"]}], + "aws.apigateway#authorizer": "sigv4", + "aws.apigateway#authorizers": { + "sigv4": { + "scheme": "aws.v4", + "customAuthType": "myCustomType" + } + } + } + } + } +} diff --git a/aws/smithy-aws-traits/src/main/java/software/amazon/smithy/aws/traits/apigateway/AuthorizerDefinition.java b/aws/smithy-aws-traits/src/main/java/software/amazon/smithy/aws/traits/apigateway/AuthorizerDefinition.java index ff8bfd53934..3d9578b1826 100644 --- a/aws/smithy-aws-traits/src/main/java/software/amazon/smithy/aws/traits/apigateway/AuthorizerDefinition.java +++ b/aws/smithy-aws-traits/src/main/java/software/amazon/smithy/aws/traits/apigateway/AuthorizerDefinition.java @@ -33,19 +33,23 @@ * @see AuthorizersTrait */ public final class AuthorizerDefinition implements ToNode, ToSmithyBuilder { + private static final String SIGV4_AUTH_TYPE = "awsSigv4"; + private static final String DEFAULT_AUTH_TYPE = "custom"; private static final String SCHEME_KEY = "scheme"; private static final String TYPE_KEY = "type"; + private static final String AUTH_TYPE_KEY = "customAuthType"; private static final String URI_KEY = "uri"; private static final String CREDENTIALS_KEY = "credentials"; private static final String IDENTITY_SOURCE_KEY = "identitySource"; private static final String IDENTITY_VALIDATION_EXPRESSION_KEY = "identityValidationExpression"; private static final String RESULT_TTL_IN_SECONDS = "resultTtlInSeconds"; private static final List PROPERTIES = ListUtils.of( - SCHEME_KEY, TYPE_KEY, URI_KEY, CREDENTIALS_KEY, IDENTITY_SOURCE_KEY, + SCHEME_KEY, TYPE_KEY, AUTH_TYPE_KEY, URI_KEY, CREDENTIALS_KEY, IDENTITY_SOURCE_KEY, IDENTITY_VALIDATION_EXPRESSION_KEY, RESULT_TTL_IN_SECONDS); private final String scheme; private final String type; + private final String authType; private final String uri; private final String credentials; private final String identitySource; @@ -56,6 +60,7 @@ private AuthorizerDefinition(Builder builder) { scheme = SmithyBuilder.requiredState(SCHEME_KEY, builder.scheme); type = builder.type; uri = builder.uri; + authType = builder.authType; credentials = builder.credentials; identitySource = builder.identitySource; identityValidationExpression = builder.identityValidationExpression; @@ -105,6 +110,25 @@ public Optional getUri() { return Optional.ofNullable(uri); } + /** + * Gets the authType of the authorizer. + * + *

This value is not used directly by APIGateway but will be used for + * OpenAPI exports. This will default to "awsSigV4" if your scheme is + * "aws.v4", or "custom" otherwise.

+ * + * @return Returns the authType. + */ + public String getAuthType() { + if (authType != null) { + return authType; + } else if (scheme.equals("aws.v4")) { + return SIGV4_AUTH_TYPE; + } else { + return DEFAULT_AUTH_TYPE; + } + } + /** * Gets the Credentials required for invoking the authorizer, if any, in * the form of an ARN of an IAM execution role. @@ -156,6 +180,7 @@ public Builder toBuilder() { .scheme(scheme) .type(type) .uri(uri) + .authType(authType) .credentials(credentials) .identitySource(identitySource) .identityValidationExpression(identityValidationExpression) @@ -167,6 +192,7 @@ public Node toNode() { return Node.objectNodeBuilder() .withMember(SCHEME_KEY, Node.from(getScheme())) .withOptionalMember(TYPE_KEY, getType().map(Node::from)) + .withOptionalMember(AUTH_TYPE_KEY, Optional.ofNullable(authType).map(Node::from)) .withOptionalMember(URI_KEY, getUri().map(Node::from)) .withOptionalMember(CREDENTIALS_KEY, getCredentials().map(Node::from)) .withOptionalMember(IDENTITY_SOURCE_KEY, getIdentitySource().map(Node::from)) @@ -188,6 +214,7 @@ public boolean equals(Object o) { return scheme.equals(that.scheme) && Objects.equals(type, that.type) && Objects.equals(uri, that.uri) + && Objects.equals(authType, that.authType) && Objects.equals(credentials, that.credentials) && Objects.equals(identitySource, that.identitySource) && Objects.equals(identityValidationExpression, that.identityValidationExpression) @@ -206,6 +233,9 @@ static AuthorizerDefinition fromNode(ObjectNode node) { node.getStringMember(TYPE_KEY) .map(StringNode::getValue) .ifPresent(builder::type); + node.getStringMember(AUTH_TYPE_KEY) + .map(StringNode::getValue) + .ifPresent(builder::authType); node.getStringMember(URI_KEY) .map(StringNode::getValue) .ifPresent(builder::uri); @@ -231,6 +261,7 @@ static AuthorizerDefinition fromNode(ObjectNode node) { public static final class Builder implements SmithyBuilder { private String scheme; private String type; + private String authType; private String uri; private String credentials; private String identitySource; @@ -270,6 +301,21 @@ public Builder type(String type) { return this; } + /** + * Sets the authType of the authorizer. + * + *

This value is not used directly by APIGateway but will be used + * for OpenAPI exports. This will default to "awsSigV4" if your scheme + * is "aws.v4", or "custom" otherwise.

+ * + * @param authType the auth type (e.g. awsSigV4) + * @return Returns the builder. + */ + public Builder authType(String authType) { + this.authType = authType; + return this; + } + /** * Sets the Uniform Resource Identifier (URI) of the authorizer * Lambda function. diff --git a/aws/smithy-aws-traits/src/main/resources/META-INF/smithy/aws.apigateway.json b/aws/smithy-aws-traits/src/main/resources/META-INF/smithy/aws.apigateway.json index baeb7049818..4e31298b3b1 100644 --- a/aws/smithy-aws-traits/src/main/resources/META-INF/smithy/aws.apigateway.json +++ b/aws/smithy-aws-traits/src/main/resources/META-INF/smithy/aws.apigateway.json @@ -31,6 +31,10 @@ "target": "smithy.api#String", "documentation": "The type of the authorizer. If specifying information beyond the scheme, this value is required. The value must be \"token\", for an authorizer with the caller identity embedded in an authorization token, or \"request\", for an authorizer with the caller identity contained in request parameters." }, + "customAuthType": { + "target": "smithy.api#String", + "documentation": "This value is not used directly by APIGateway but will be used for OpenAPI exports. This will default to \"awsSigV4\" if your scheme is \"aws.v4\", or \"custom\" otherwise." + }, "uri": { "target": "smithy.api#String", "documentation": "The Uniform Resource Identifier (URI) of the authorizer Lambda function" diff --git a/docs/source/spec/amazon-apigateway.rst b/docs/source/spec/amazon-apigateway.rst index a6599c8d77c..5e8419747b2 100644 --- a/docs/source/spec/amazon-apigateway.rst +++ b/docs/source/spec/amazon-apigateway.rst @@ -119,6 +119,11 @@ An *authorizer* definition is an object that supports the following properties: authorizer with the caller identity embedded in an authorization token, or "request", for an authorizer with the caller identity contained in request parameters. + * - customAuthType + - ``string`` + - The ``authType`` of the authorizer. This value is used in APIGateway + exports as ``x-amazon-apigateway-authtype``. This value is set to + ``custom`` by default, or ``awsSigv4`` if your scheme is ``aws.v4``. * - uri - ``string`` - Specifies the authorizer's Uniform Resource Identifier