Skip to content

Commit

Permalink
chore(codegen): make sigv4a detection programmatic
Browse files Browse the repository at this point in the history
  • Loading branch information
kuhe committed Aug 1, 2024
1 parent 03f1a90 commit 98740af
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 139 deletions.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -237,16 +237,14 @@ public Map<String, Consumer<TypeScriptWriter>> getRuntimeConfigWriters(
}
switch (target) {
case SHARED:
return MapUtils.of("signingEscapePath", writer -> {
writer.write("false");
}, "useArnRegion", writer -> {
writer.write("false");
}, "signerConstructor", writer -> {
writer.addDependency(AwsDependency.SIGNATURE_V4_MULTIREGION)
.addImport("SignatureV4MultiRegion", "SignatureV4MultiRegion",
AwsDependency.SIGNATURE_V4_MULTIREGION)
.write("SignatureV4MultiRegion");
});
return MapUtils.of(
"signingEscapePath", writer -> {
writer.write("false");
},
"useArnRegion", writer -> {
writer.write("false");
}
);
case NODE:
return MapUtils.of(
"useArnRegion", writer -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@
import java.util.Collections;
import java.util.Map;
import java.util.function.Consumer;
import software.amazon.smithy.aws.traits.auth.SigV4ATrait;
import software.amazon.smithy.codegen.core.SymbolProvider;
import software.amazon.smithy.model.Model;
import software.amazon.smithy.model.knowledge.ServiceIndex;
import software.amazon.smithy.typescript.codegen.LanguageTarget;
import software.amazon.smithy.typescript.codegen.TypeScriptSettings;
import software.amazon.smithy.typescript.codegen.TypeScriptWriter;
Expand All @@ -30,15 +28,14 @@ public boolean matchesSettings(TypeScriptSettings settings) {
return settings.useLegacyAuth();
}

@Override
public Map<String, Consumer<TypeScriptWriter>> getRuntimeConfigWriters(
TypeScriptSettings settings,
Model model,
SymbolProvider symbolProvider,
LanguageTarget target
) {
final boolean addSigv4aSignerToConfig = ServiceIndex.of(model)
.getEffectiveAuthSchemes(settings.getService(), ServiceIndex.AuthSchemeMode.NO_AUTH_AWARE)
.containsKey(SigV4ATrait.ID);
final boolean addSigv4aSignerToConfig = AwsTraitsUtils.isSigV4AsymmetricService(model, settings);

// the sigv4a trait also appears on operations, but we will not check
// them individually because it must appear on the service as well in that case.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@

package software.amazon.smithy.aws.typescript.codegen;

import java.util.Set;
import software.amazon.smithy.aws.traits.ServiceTrait;
import software.amazon.smithy.aws.traits.auth.SigV4ATrait;
import software.amazon.smithy.aws.traits.auth.SigV4Trait;
import software.amazon.smithy.model.Model;
import software.amazon.smithy.model.knowledge.ServiceIndex;
import software.amazon.smithy.model.shapes.ServiceShape;
import software.amazon.smithy.model.shapes.ShapeId;
import software.amazon.smithy.model.traits.HttpBearerAuthTrait;
import software.amazon.smithy.rulesengine.traits.EndpointRuleSetTrait;
import software.amazon.smithy.typescript.codegen.TypeScriptSettings;
Expand All @@ -29,6 +33,13 @@
*/
@SmithyInternalApi
public final class AwsTraitsUtils {
// SigV4a is not declared as a trait in existing services, so we need to hard code the following:
// This should not be copied or made public outside of this class.
private static final Set<ShapeId> ENDPOINT_RULESET_HTTP_AUTH_SCHEME_SERVICES = Set.of(
ShapeId.from("com.amazonaws.s3#AmazonS3"),
ShapeId.from("com.amazonaws.eventbridge#AWSEvents"),
ShapeId.from("com.amazonaws.cloudfrontkeyvaluestore#CloudFrontKeyValueStore")
);

private AwsTraitsUtils() {}

Expand All @@ -48,6 +59,16 @@ public static boolean isSigV4Service(ServiceShape serviceShape) {
return serviceShape.hasTrait(SigV4Trait.class);
}

public static boolean isSigV4AsymmetricService(Model model, TypeScriptSettings settings) {
if (ENDPOINT_RULESET_HTTP_AUTH_SCHEME_SERVICES.contains(settings.getService())) {
return true;
}

return ServiceIndex.of(model)
.getEffectiveAuthSchemes(settings.getService(), ServiceIndex.AuthSchemeMode.NO_AUTH_AWARE)
.containsKey(SigV4ATrait.ID);
}

static boolean isEndpointsV2Service(ServiceShape serviceShape) {
return serviceShape.hasTrait(EndpointRuleSetTrait.class);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@
package software.amazon.smithy.aws.typescript.codegen.auth.http.integration;

import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Objects;
import java.util.function.Consumer;
import software.amazon.smithy.aws.typescript.codegen.AwsDependency;
import software.amazon.smithy.aws.typescript.codegen.AwsTraitsUtils;
import software.amazon.smithy.codegen.core.Symbol;
import software.amazon.smithy.codegen.core.SymbolProvider;
import software.amazon.smithy.model.Model;
import software.amazon.smithy.model.knowledge.ServiceIndex;
import software.amazon.smithy.model.knowledge.ServiceIndex.AuthSchemeMode;
Expand All @@ -20,6 +24,7 @@
import software.amazon.smithy.model.shapes.ShapeId;
import software.amazon.smithy.model.traits.DynamicTrait;
import software.amazon.smithy.typescript.codegen.CodegenUtils;
import software.amazon.smithy.typescript.codegen.LanguageTarget;
import software.amazon.smithy.typescript.codegen.TypeScriptCodegenContext;
import software.amazon.smithy.typescript.codegen.TypeScriptDependency;
import software.amazon.smithy.typescript.codegen.TypeScriptSettings;
Expand All @@ -38,6 +43,7 @@
import software.amazon.smithy.typescript.codegen.endpointsV2.EndpointsV2Generator;
import software.amazon.smithy.utils.CodeInterceptor;
import software.amazon.smithy.utils.CodeSection;
import software.amazon.smithy.utils.MapUtils;
import software.amazon.smithy.utils.SmithyInternalApi;

/**
Expand All @@ -48,39 +54,62 @@
*/
@SmithyInternalApi
public final class AwsSdkCustomizeEndpointRuleSetHttpAuthSchemeProvider implements HttpAuthTypeScriptIntegration {
public static final Set<ShapeId> ENDPOINT_RULESET_HTTP_AUTH_SCHEME_SERVICES = Set.of(
ShapeId.from("com.amazonaws.s3#AmazonS3"),
ShapeId.from("com.amazonaws.eventbridge#AWSEvents"),
ShapeId.from("com.amazonaws.cloudfrontkeyvaluestore#CloudFrontKeyValueStore"));
private static final ShapeId SIGV4A_ID = ShapeId.from("aws.auth#sigv4a");

/**
* Integration should be skipped if the `useLegacyAuth` flag is true.
*/
@Override
public boolean matchesSettings(TypeScriptSettings settings) {
return !settings.useLegacyAuth()
&& ENDPOINT_RULESET_HTTP_AUTH_SCHEME_SERVICES.contains(settings.getService());
return !settings.useLegacyAuth();
}

@Override
public List<String> runBefore() {
return List.of(
AddHttpAuthSchemePlugin.class.getCanonicalName());
AddHttpAuthSchemePlugin.class.getCanonicalName()
);
}

@Override
public List<String> runAfter() {
return List.of(
SupportSigV4Auth.class.getCanonicalName(),
AwsSdkCustomizeSigV4Auth.class.getCanonicalName());
AwsSdkCustomizeSigV4Auth.class.getCanonicalName()
);
}

@Override
public Map<String, Consumer<TypeScriptWriter>> getRuntimeConfigWriters(
TypeScriptSettings settings,
Model model,
SymbolProvider symbolProvider,
LanguageTarget target
) {
if (!AwsTraitsUtils.isSigV4AsymmetricService(model, settings)) {
return Collections.emptyMap();
}

if (Objects.requireNonNull(target) == LanguageTarget.SHARED) {
return MapUtils.of("signerConstructor", writer -> {
writer
.addDependency(AwsDependency.SIGNATURE_V4_MULTIREGION)
.addImport("SignatureV4MultiRegion", null, AwsDependency.SIGNATURE_V4_MULTIREGION)
.write("SignatureV4MultiRegion");
});
}
return Collections.emptyMap();
}

@Override
public void customizeSupportedHttpAuthSchemes(
SupportedHttpAuthSchemesIndex supportedHttpAuthSchemesIndex,
Model model,
TypeScriptSettings settings) {
if (!AwsTraitsUtils.isSigV4AsymmetricService(model, settings)) {
return;
}

// TODO(experimentalIdentityAndAuth): should be removed when @aws.auth#sigv4a is supported
if (supportedHttpAuthSchemesIndex.getHttpAuthScheme(SIGV4A_ID) == null) {
ShapeId sigv4 = ShapeId.from("aws.auth#sigv4");
Expand All @@ -96,6 +125,9 @@ public void customizeSupportedHttpAuthSchemes(
public List<? extends CodeInterceptor<? extends CodeSection, TypeScriptWriter>> interceptors(
TypeScriptCodegenContext codegenContext
) {
if (!AwsTraitsUtils.isSigV4AsymmetricService(codegenContext.model(), codegenContext.settings())) {
return Collections.emptyList();
}
return List.of(
new CodeInterceptor<HttpAuthSchemeParametersInterfaceCodeSection, TypeScriptWriter>() {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@
package software.amazon.smithy.aws.typescript.codegen.auth.http.integration;

import static software.amazon.smithy.aws.typescript.codegen.AwsTraitsUtils.isAwsService;
import static software.amazon.smithy.aws.typescript.codegen.AwsTraitsUtils.isSigV4AsymmetricService;
import static software.amazon.smithy.aws.typescript.codegen.AwsTraitsUtils.isSigV4Service;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import software.amazon.smithy.aws.traits.auth.SigV4ATrait;
import software.amazon.smithy.aws.traits.auth.SigV4Trait;
import software.amazon.smithy.aws.typescript.codegen.AwsCredentialProviderUtils;
Expand All @@ -25,7 +24,6 @@
import software.amazon.smithy.model.knowledge.TopDownIndex;
import software.amazon.smithy.model.shapes.OperationShape;
import software.amazon.smithy.model.shapes.ServiceShape;
import software.amazon.smithy.model.shapes.ShapeId;
import software.amazon.smithy.model.traits.OptionalAuthTrait;
import software.amazon.smithy.typescript.codegen.LanguageTarget;
import software.amazon.smithy.typescript.codegen.TypeScriptDependency;
Expand Down Expand Up @@ -177,8 +175,7 @@ public void customizeSupportedHttpAuthSchemes(
.build();
supportedHttpAuthSchemesIndex.putHttpAuthScheme(authScheme.getSchemeId(), authScheme);

if (AwsSdkCustomizeEndpointRuleSetHttpAuthSchemeProvider.ENDPOINT_RULESET_HTTP_AUTH_SCHEME_SERVICES
.contains(service.getId())) {
if (isSigV4AsymmetricService(model, settings)) {
HttpAuthScheme authSchemeSigV4a = supportedHttpAuthSchemesIndex.getHttpAuthScheme(SigV4Trait.ID).toBuilder()
.schemeId(SigV4ATrait.ID)
.putDefaultSigner(LanguageTarget.SHARED, w -> w
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@ software.amazon.smithy.aws.typescript.codegen.AddCrossRegionCopyingPlugin
software.amazon.smithy.aws.typescript.codegen.AddDocumentClientPlugin
software.amazon.smithy.aws.typescript.codegen.AddEndpointDiscoveryPlugin
software.amazon.smithy.aws.typescript.codegen.AddHttpChecksumDependency
software.amazon.smithy.aws.typescript.codegen.AddEventBridgePlugin
software.amazon.smithy.aws.typescript.codegen.AddSigv4aPlugin
software.amazon.smithy.aws.typescript.codegen.AddCloudFrontKeyValueStorePlugin
software.amazon.smithy.aws.typescript.codegen.auth.http.integration.AwsSdkCustomizeHttpBearerTokenAuth
software.amazon.smithy.aws.typescript.codegen.auth.http.integration.SupportSigV4Auth
software.amazon.smithy.aws.typescript.codegen.auth.http.integration.AwsSdkCustomizeSigV4Auth
Expand Down

0 comments on commit 98740af

Please sign in to comment.