Skip to content

Commit

Permalink
Make conversion of multi-auth opt-in (#5011)
Browse files Browse the repository at this point in the history
Currently, `metadata.auth` and `operation.auth` are read although full
support for multi-auth is not implemented yet.

This change allows reading these `auth` values to be opt-in, especially
for `useSraAuth` tests.

Also, allows conversions of select smithy auth trait shape IDs into
`AuthType`s:

- `smithy.api#httpBearerAuth => BEARER`
- `smithy.api#noAuth => NONE`
- `aws.auth#sigv4 => V4`
  • Loading branch information
syall authored Mar 14, 2024
1 parent eca1665 commit 895e0fd
Show file tree
Hide file tree
Showing 10 changed files with 173 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package software.amazon.awssdk.codegen;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import software.amazon.awssdk.codegen.internal.Constant;
Expand Down Expand Up @@ -78,11 +79,7 @@ public static Metadata constructMetadata(ServiceModel serviceModel,
.withSupportsH2(supportsH2(serviceMetadata))
.withJsonVersion(getJsonVersion(metadata, serviceMetadata))
.withAwsQueryCompatible(serviceMetadata.getAwsQueryCompatible())
.withAuth(Optional.ofNullable(serviceMetadata.getAuth())
.orElseGet(() -> Collections.singletonList(serviceMetadata.getSignatureVersion()))
.stream()
.map(AuthType::fromValue)
.collect(Collectors.toList()));
.withAuth(getAuthFromServiceMetadata(serviceMetadata, customizationConfig.useMultiAuth()));

return metadata;
}
Expand Down Expand Up @@ -135,4 +132,20 @@ private static String getJsonVersion(Metadata metadata, ServiceMetadata serviceM
return serviceMetadata.getJsonVersion();
}
}

/**
* Converts service metadata into a list of AuthTypes. If useMultiAuth is enabled, then
* {@code metadata.auth} will be used in the conversion if present. Otherwise, use
* {@code metadata.signatureVersion}.
*/
private static List<AuthType> getAuthFromServiceMetadata(ServiceMetadata serviceMetadata,
boolean useMultiAuth) {
if (useMultiAuth) {
List<String> serviceAuth = serviceMetadata.getAuth();
if (serviceAuth != null) {
return serviceAuth.stream().map(AuthType::fromValue).collect(Collectors.toList());
}
}
return Collections.singletonList(AuthType.fromValue(serviceMetadata.getSignatureVersion()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,14 @@ final class AddOperations {
private final NamingStrategy namingStrategy;
private final Map<String, PaginatorDefinition> paginators;
private final List<String> deprecatedShapes;
private final boolean useMultiAuth;

AddOperations(IntermediateModelBuilder builder) {
this.serviceModel = builder.getService();
this.namingStrategy = builder.getNamingStrategy();
this.paginators = builder.getPaginators().getPagination();
this.deprecatedShapes = builder.getCustomConfig().getDeprecatedShapes();
this.useMultiAuth = builder.getCustomConfig().useMultiAuth();
}

private static boolean isAuthenticated(Operation op) {
Expand Down Expand Up @@ -234,13 +236,16 @@ public Map<String, OperationModel> constructOperations() {
}

/**
* Returns the list of authTypes defined for an operation. If the new auth member is defined we use it, otherwise we retrofit
* the list with the value of the authType member if present or return an empty list if not.
* Returns the list of authTypes defined for an operation. If useMultiAuth is enabled, then
* {@code operation.auth} will be used in the conversion if present. Otherwise, use
* {@code operation.authtype} if present.
*/
private List<AuthType> getAuthFromOperation(Operation op) {
List<String> opAuth = op.getAuth();
if (opAuth != null) {
return opAuth.stream().map(AuthType::fromValue).collect(Collectors.toList());
if (useMultiAuth) {
List<String> opAuth = op.getAuth();
if (opAuth != null) {
return opAuth.stream().map(AuthType::fromValue).collect(Collectors.toList());
}
}
AuthType legacyAuthType = op.getAuthtype();
if (legacyAuthType != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,13 @@ public class CustomizationConfig {
*/
private String rootPackageName;

/**
* Set to true to read from c2j multi-auth values. Currently defaults to false.
*
* TODO(multi-auth): full multi-auth support is not implemented
*/
private boolean useMultiAuth;

private CustomizationConfig() {
}

Expand Down Expand Up @@ -828,4 +835,12 @@ public CustomizationConfig withRootPackageName(String packageName) {
this.rootPackageName = packageName;
return this;
}

public void setUseMultiAuth(boolean useMultiAuth) {
this.useMultiAuth = useMultiAuth;
}

public boolean useMultiAuth() {
return useMultiAuth;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,21 @@ public String value() {
}

public static AuthType fromValue(String value) {
String normalizedValue = StringUtils.lowerCase(value);
return Arrays.stream(values())
.filter(authType -> authType.value.equals(normalizedValue))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException(String.format("Unknown AuthType '%s'", normalizedValue)));
switch (value) {
// TODO(multi-auth): review conversion of smithy auth trait shape IDs
case "smithy.api#httpBearerAuth":
return BEARER;
case "smithy.api#noAuth":
return NONE;
case "aws.auth#sigv4":
return V4;
default:
String normalizedValue = StringUtils.lowerCase(value);
return Arrays.stream(values())
.filter(authType -> authType.value.equals(normalizedValue))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException(
String.format("Unknown AuthType '%s'", normalizedValue)));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package software.amazon.awssdk.codegen.model.service;

import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;

import org.junit.Test;

public class AuthTypeTest {
@Test
public void authTypeConvertBearer() {
String smithyAuthTypeInput = "smithy.api#httpBearerAuth";
String c2jAuthTypeInput = "bearer";

AuthType smithyAuthType = AuthType.fromValue(smithyAuthTypeInput);
AuthType c2jAuthType = AuthType.fromValue(c2jAuthTypeInput);
assertThat(smithyAuthType, equalTo(AuthType.BEARER));
assertThat(c2jAuthType, equalTo(AuthType.BEARER));
assertThat(smithyAuthType, equalTo(c2jAuthType));
}

@Test
public void authTypeConvertNone() {
String smithyAuthTypeInput = "smithy.api#noAuth";
String c2jAuthTypeInput = "none";

AuthType smithyAuthType = AuthType.fromValue(smithyAuthTypeInput);
AuthType c2jAuthType = AuthType.fromValue(c2jAuthTypeInput);
assertThat(smithyAuthType, equalTo(AuthType.NONE));
assertThat(c2jAuthType, equalTo(AuthType.NONE));
assertThat(smithyAuthType, equalTo(c2jAuthType));
}

@Test
public void authTypeConvertV4() {
String smithyAuthTypeInput = "aws.auth#sigv4";
String c2jAuthTypeInput = "v4";

AuthType smithyAuthType = AuthType.fromValue(smithyAuthTypeInput);
AuthType c2jAuthType = AuthType.fromValue(c2jAuthTypeInput);
assertThat(smithyAuthType, equalTo(AuthType.V4));
assertThat(c2jAuthType, equalTo(AuthType.V4));
assertThat(smithyAuthType, equalTo(c2jAuthType));
}

@Test
public void authTypeConvertCustom() {
String c2jAuthTypeInput = "custom";

AuthType c2jAuthType = AuthType.fromValue(c2jAuthTypeInput);
assertThat(c2jAuthType, equalTo(AuthType.CUSTOM));
}

@Test
public void authTypeConvertIam() {
String c2jAuthTypeInput = "iam";

AuthType c2jAuthType = AuthType.fromValue(c2jAuthTypeInput);
assertThat(c2jAuthType, equalTo(AuthType.IAM));
}

@Test
public void authTypeConvertV4UnsignedBody() {
String c2jAuthTypeInput = "v4-unsigned-body";

AuthType c2jAuthType = AuthType.fromValue(c2jAuthTypeInput);
assertThat(c2jAuthType, equalTo(AuthType.V4_UNSIGNED_BODY));
}

@Test
public void authTypeConvertS3() {
String c2jAuthTypeInput = "s3";

AuthType c2jAuthType = AuthType.fromValue(c2jAuthTypeInput);
assertThat(c2jAuthType, equalTo(AuthType.S3));
}

@Test
public void authTypeConvertS3v4() {
String c2jAuthTypeInput = "s3v4";

AuthType c2jAuthType = AuthType.fromValue(c2jAuthTypeInput);
assertThat(c2jAuthType, equalTo(AuthType.S3V4));
}

@Test
public void authTypeConvertUnknownAuthType() {
String c2jAuthTypeInput = "unknown";

assertThatThrownBy(() -> AuthType.fromValue(c2jAuthTypeInput))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Unknown AuthType 'unknown'");
}
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
{
"useMultiAuth": true
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
{
"useMultiAuth": true
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
{
"useMultiAuth": true
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
{
"useMultiAuth": true
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
{
"useMultiAuth": true
}

0 comments on commit 895e0fd

Please sign in to comment.