Skip to content

feat(experimentalIdentityAndAuth): add codegen for HttpAuthExtensionConfiguration #910

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,22 @@
@SmithyUnstableApi
public final record ConfigField(
String name,
Type type,
Consumer<TypeScriptWriter> source,
Consumer<TypeScriptWriter> docs
) {}
) {
/**
* Defines the type of the config field.
*/
@SmithyUnstableApi
public enum Type {
/**
* Specifies the property is important, e.g. {@code apiKey} for {@code @httpApiKeyAuth}
*/
MAIN,
/**
* Specifies the property is auxiliary, e.g. {@code region} for {@code @aws.auth#sigv4}
*/
AUXILIARY
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

package software.amazon.smithy.typescript.codegen;

import java.nio.file.Paths;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
Expand All @@ -32,7 +31,6 @@
import software.amazon.smithy.model.shapes.ShapeId;
import software.amazon.smithy.typescript.codegen.auth.AuthUtils;
import software.amazon.smithy.typescript.codegen.auth.http.HttpAuthScheme;
import software.amazon.smithy.typescript.codegen.auth.http.HttpAuthSchemeProviderGenerator;
import software.amazon.smithy.typescript.codegen.auth.http.SupportedHttpAuthSchemesIndex;
import software.amazon.smithy.typescript.codegen.integration.TypeScriptIntegration;
import software.amazon.smithy.utils.MapUtils;
Expand Down Expand Up @@ -212,9 +210,7 @@ private void generateHttpAuthSchemeConfig(
if (target.equals(LanguageTarget.SHARED)) {
configs.put("httpAuthSchemeProvider", w -> {
String providerName = "default" + service.toShapeId().getName() + "HttpAuthSchemeProvider";
w.addRelativeImport(providerName, null, Paths.get(".", CodegenUtils.SOURCE_FOLDER,
HttpAuthSchemeProviderGenerator.HTTP_AUTH_FOLDER,
HttpAuthSchemeProviderGenerator.HTTP_AUTH_SCHEME_RESOLVER_MODULE));
w.addImport(providerName, null, AuthUtils.AUTH_HTTP_PROVIDER_DEPENDENCY);
w.write(providerName);
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import software.amazon.smithy.model.shapes.OperationShape;
import software.amazon.smithy.model.shapes.ServiceShape;
import software.amazon.smithy.rulesengine.traits.EndpointRuleSetTrait;
import software.amazon.smithy.typescript.codegen.auth.http.HttpAuthSchemeProviderGenerator;
import software.amazon.smithy.typescript.codegen.auth.AuthUtils;
import software.amazon.smithy.typescript.codegen.auth.http.integration.HttpAuthTypeScriptIntegration;
import software.amazon.smithy.typescript.codegen.integration.RuntimeClientPlugin;
import software.amazon.smithy.typescript.codegen.integration.TypeScriptIntegration;
Expand Down Expand Up @@ -313,10 +313,7 @@ private void generateClientDefaults() {
writer.write("httpAuthSchemes?: HttpAuthScheme[];\n");

String httpAuthSchemeProviderName = service.toShapeId().getName() + "HttpAuthSchemeProvider";
writer.addRelativeImport(httpAuthSchemeProviderName, null, Paths.get(".",
CodegenUtils.SOURCE_FOLDER,
HttpAuthSchemeProviderGenerator.HTTP_AUTH_FOLDER,
HttpAuthSchemeProviderGenerator.HTTP_AUTH_SCHEME_RESOLVER_MODULE));
writer.addImport(httpAuthSchemeProviderName, null, AuthUtils.AUTH_HTTP_PROVIDER_DEPENDENCY);
writer.writeDocs("""
experimentalIdentityAndAuth: Configuration of an HttpAuthSchemeProvider for a client which \
resolves which HttpAuthScheme to use.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@

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

import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import software.amazon.smithy.codegen.core.SymbolDependency;
import software.amazon.smithy.model.knowledge.ServiceIndex;
import software.amazon.smithy.model.knowledge.ServiceIndex.AuthSchemeMode;
import software.amazon.smithy.model.shapes.ServiceShape;
import software.amazon.smithy.model.shapes.ShapeId;
import software.amazon.smithy.typescript.codegen.CodegenUtils;
import software.amazon.smithy.typescript.codegen.Dependency;
import software.amazon.smithy.typescript.codegen.auth.http.HttpAuthScheme;
import software.amazon.smithy.typescript.codegen.auth.http.SupportedHttpAuthSchemesIndex;
import software.amazon.smithy.utils.SmithyInternalApi;
Expand All @@ -20,6 +26,54 @@
*/
@SmithyInternalApi
public final class AuthUtils {
public static final String HTTP_AUTH_FOLDER = "auth";

public static final String HTTP_AUTH_SCHEME_PROVIDER_MODULE = "httpAuthSchemeProvider";

public static final String HTTP_AUTH_SCHEME_PROVIDER_FILE =
HTTP_AUTH_SCHEME_PROVIDER_MODULE + ".ts";

public static final String HTTP_AUTH_SCHEME_PROVIDER_PATH =
Paths.get(".", CodegenUtils.SOURCE_FOLDER, HTTP_AUTH_FOLDER, HTTP_AUTH_SCHEME_PROVIDER_FILE).toString();

public static final Dependency AUTH_HTTP_PROVIDER_DEPENDENCY = new Dependency() {
@Override
public String getPackageName() {
return Paths.get(
".", CodegenUtils.SOURCE_FOLDER,
HTTP_AUTH_FOLDER, HTTP_AUTH_SCHEME_PROVIDER_MODULE
).toString();
}

@Override
public List<SymbolDependency> getDependencies() {
return Collections.emptyList();
}
};

public static final String HTTP_AUTH_SCHEME_EXTENSION_MODULE = "httpAuthExtensionConfiguration";

public static final String HTTP_AUTH_SCHEME_EXTENSION_FILE =
HTTP_AUTH_SCHEME_EXTENSION_MODULE + ".ts";

public static final String HTTP_AUTH_SCHEME_EXTENSION_PATH =
Paths.get(".", CodegenUtils.SOURCE_FOLDER, HTTP_AUTH_FOLDER, HTTP_AUTH_SCHEME_EXTENSION_FILE).toString();

public static final Dependency AUTH_HTTP_EXTENSION_DEPENDENCY = new Dependency() {
@Override
public String getPackageName() {
return Paths.get(
".", CodegenUtils.SOURCE_FOLDER,
HTTP_AUTH_FOLDER, HTTP_AUTH_SCHEME_EXTENSION_MODULE
).toString();
}

@Override
public List<SymbolDependency> getDependencies() {
return Collections.emptyList();
}
};

private AuthUtils() {}

public static Map<ShapeId, HttpAuthScheme> getAllEffectiveNoAuthAwareAuthSchemes(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,6 @@
*/
@SmithyInternalApi
public class HttpAuthSchemeProviderGenerator implements Runnable {
/**
* Directory segment for {@code auth/}.
*/
public static final String HTTP_AUTH_FOLDER = "auth";
/**
* File name segment for {@code httpAuthSchemeProvder}.
*/
public static final String HTTP_AUTH_SCHEME_RESOLVER_MODULE = "httpAuthSchemeProvider";

private static final String HTTP_AUTH_SCHEME_RESOLVER_FILE =
HTTP_AUTH_SCHEME_RESOLVER_MODULE + ".ts";
private static final String HTTP_AUTH_SCHEME_RESOLVER_PATH =
Paths.get(CodegenUtils.SOURCE_FOLDER, HTTP_AUTH_FOLDER, HTTP_AUTH_SCHEME_RESOLVER_FILE).toString();

private final TypeScriptDelegator delegator;
private final Model model;

Expand Down Expand Up @@ -104,7 +90,7 @@ export interface WeatherHttpAuthSchemeParameters {
}
*/
private void generateHttpAuthSchemeParametersInterface() {
delegator.useFileWriter(HTTP_AUTH_SCHEME_RESOLVER_PATH.toString(), w -> {
delegator.useFileWriter(AuthUtils.HTTP_AUTH_SCHEME_PROVIDER_PATH, w -> {
w.openBlock("""
/**
* @internal
Expand Down Expand Up @@ -138,7 +124,7 @@ export async function defaultWeatherHttpAuthSchemeParametersProvider(
};
*/
private void generateDefaultHttpAuthSchemeParametersProviderFunction() {
delegator.useFileWriter(HTTP_AUTH_SCHEME_RESOLVER_PATH.toString(), w -> {
delegator.useFileWriter(AuthUtils.HTTP_AUTH_SCHEME_PROVIDER_PATH, w -> {
w.addRelativeImport(serviceSymbol.getName() + "ResolvedConfig", null,
Paths.get(".", serviceSymbol.getNamespace()));
w.addImport("HandlerExecutionContext", null, TypeScriptDependency.SMITHY_TYPES);
Expand Down Expand Up @@ -190,7 +176,7 @@ function createSmithyApiHttpApiKeyAuthHttpAuthOption(authParameters: WeatherHttp
};
*/
private void generateHttpAuthOptionFunction(ShapeId shapeId, HttpAuthScheme authScheme) {
delegator.useFileWriter(HTTP_AUTH_SCHEME_RESOLVER_PATH.toString(), w -> {
delegator.useFileWriter(AuthUtils.HTTP_AUTH_SCHEME_PROVIDER_PATH, w -> {
String normalizedAuthSchemeName = normalizeAuthSchemeName(shapeId);
w.addDependency(TypeScriptDependency.EXPERIMENTAL_IDENTITY_AND_AUTH);
w.addImport("HttpAuthOption", null, TypeScriptDependency.EXPERIMENTAL_IDENTITY_AND_AUTH);
Expand Down Expand Up @@ -242,7 +228,7 @@ export interface WeatherHttpAuthSchemeProvider {
}
*/
private void generateHttpAuthSchemeProviderInterface() {
delegator.useFileWriter(HTTP_AUTH_SCHEME_RESOLVER_PATH.toString(), w -> {
delegator.useFileWriter(AuthUtils.HTTP_AUTH_SCHEME_PROVIDER_PATH, w -> {
w.write("""
/**
* @internal
Expand All @@ -267,7 +253,7 @@ export function defaultWeatherHttpAuthSchemeProvider(authParameters: WeatherHttp
};
*/
private void generateHttpAuthSchemeProviderDefaultFunction() {
delegator.useFileWriter(HTTP_AUTH_SCHEME_RESOLVER_PATH.toString(), w -> {
delegator.useFileWriter(AuthUtils.HTTP_AUTH_SCHEME_PROVIDER_PATH, w -> {
w.openBlock("""
/**
* @internal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import software.amazon.smithy.typescript.codegen.TypeScriptSettings;
import software.amazon.smithy.typescript.codegen.TypeScriptWriter;
import software.amazon.smithy.typescript.codegen.auth.http.HttpAuthOptionProperty;
import software.amazon.smithy.typescript.codegen.auth.http.HttpAuthOptionProperty.Type;
import software.amazon.smithy.typescript.codegen.auth.http.HttpAuthScheme;
import software.amazon.smithy.utils.SmithyInternalApi;

Expand Down Expand Up @@ -47,20 +46,20 @@ public Optional<HttpAuthScheme> getHttpAuthScheme() {
return Optional.of(HttpAuthScheme.builder()
.schemeId(HttpApiKeyAuthTrait.ID)
.applicationProtocol(ApplicationProtocol.createDefaultHttpApplicationProtocol())
.addConfigField(new ConfigField("apiKey", w -> {
.addConfigField(new ConfigField("apiKey", ConfigField.Type.MAIN, w -> {
w.addImport("ApiKeyIdentity", null,
TypeScriptDependency.EXPERIMENTAL_IDENTITY_AND_AUTH);
w.addImport("ApiKeyIdentityProvider", null,
TypeScriptDependency.EXPERIMENTAL_IDENTITY_AND_AUTH);
w.write("ApiKeyIdentity | ApiKeyIdentityProvider");
}, w -> w.write("The API key to use when making requests.")))
.addHttpAuthOptionProperty(new HttpAuthOptionProperty(
"name", Type.SIGNING, t -> w -> {
"name", HttpAuthOptionProperty.Type.SIGNING, t -> w -> {
HttpApiKeyAuthTrait httpApiKeyAuthTrait = (HttpApiKeyAuthTrait) t;
w.write("$S", httpApiKeyAuthTrait.getName());
}))
.addHttpAuthOptionProperty(new HttpAuthOptionProperty(
"in", Type.SIGNING, t -> w -> {
"in", HttpAuthOptionProperty.Type.SIGNING, t -> w -> {
w.addImport("HttpApiKeyAuthLocation", null,
TypeScriptDependency.EXPERIMENTAL_IDENTITY_AND_AUTH);
HttpApiKeyAuthTrait httpApiKeyAuthTrait = (HttpApiKeyAuthTrait) t;
Expand All @@ -74,7 +73,7 @@ public Optional<HttpAuthScheme> getHttpAuthScheme() {
}
}))
.addHttpAuthOptionProperty(new HttpAuthOptionProperty(
"scheme", Type.SIGNING, t -> w -> {
"scheme", HttpAuthOptionProperty.Type.SIGNING, t -> w -> {
HttpApiKeyAuthTrait httpApiKeyAuthTrait = (HttpApiKeyAuthTrait) t;
httpApiKeyAuthTrait.getScheme().ifPresentOrElse(
s -> w.write(s),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import software.amazon.smithy.model.traits.HttpBearerAuthTrait;
import software.amazon.smithy.typescript.codegen.ApplicationProtocol;
import software.amazon.smithy.typescript.codegen.ConfigField;
import software.amazon.smithy.typescript.codegen.ConfigField.Type;
import software.amazon.smithy.typescript.codegen.LanguageTarget;
import software.amazon.smithy.typescript.codegen.TypeScriptDependency;
import software.amazon.smithy.typescript.codegen.TypeScriptSettings;
Expand Down Expand Up @@ -43,7 +44,7 @@ public Optional<HttpAuthScheme> getHttpAuthScheme() {
return Optional.of(HttpAuthScheme.builder()
.schemeId(HttpBearerAuthTrait.ID)
.applicationProtocol(ApplicationProtocol.createDefaultHttpApplicationProtocol())
.addConfigField(new ConfigField("token", w -> {
.addConfigField(new ConfigField("token", Type.MAIN, w -> {
w.addDependency(TypeScriptDependency.EXPERIMENTAL_IDENTITY_AND_AUTH);
w.addImport("TokenIdentity", null,
TypeScriptDependency.EXPERIMENTAL_IDENTITY_AND_AUTH);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import software.amazon.smithy.typescript.codegen.TypeScriptSettings;
import software.amazon.smithy.typescript.codegen.TypeScriptWriter;
import software.amazon.smithy.typescript.codegen.auth.http.HttpAuthOptionProperty;
import software.amazon.smithy.typescript.codegen.auth.http.HttpAuthOptionProperty.Type;
import software.amazon.smithy.typescript.codegen.auth.http.HttpAuthScheme;
import software.amazon.smithy.typescript.codegen.auth.http.HttpAuthSchemeParameter;
import software.amazon.smithy.utils.SmithyInternalApi;
Expand Down Expand Up @@ -47,12 +46,12 @@ public Optional<HttpAuthScheme> getHttpAuthScheme() {
.schemeId(ShapeId.from("aws.auth#sigv4"))
.applicationProtocol(ApplicationProtocol.createDefaultHttpApplicationProtocol())
.putDefaultSigner(LanguageTarget.SHARED, AWS_SIGV4_AUTH_SIGNER)
.addConfigField(new ConfigField("region", w -> {
.addConfigField(new ConfigField("region", ConfigField.Type.AUXILIARY, w -> {
w.addDependency(TypeScriptDependency.SMITHY_TYPES);
w.addImport("Provider", "__Provider", TypeScriptDependency.SMITHY_TYPES);
w.write("string | __Provider<string>");
}, w -> w.write("The AWS region to which this client will send requests.")))
.addConfigField(new ConfigField("credentials", w -> {
.addConfigField(new ConfigField("credentials", ConfigField.Type.MAIN, w -> {
w.addDependency(TypeScriptDependency.SMITHY_TYPES);
w.addImport("AwsCredentialIdentity", null, TypeScriptDependency.SMITHY_TYPES);
w.addImport("AwsCredentialIdentityProvider", null, TypeScriptDependency.SMITHY_TYPES);
Expand All @@ -67,11 +66,11 @@ public Optional<HttpAuthScheme> getHttpAuthScheme() {
});
}))
.addHttpAuthOptionProperty(new HttpAuthOptionProperty(
"name", Type.SIGNING, t -> w -> {
"name", HttpAuthOptionProperty.Type.SIGNING, t -> w -> {
w.write("$S", t.toNode().expectObjectNode().getMember("name"));
}))
.addHttpAuthOptionProperty(new HttpAuthOptionProperty(
"region", Type.SIGNING, t -> w -> {
"region", HttpAuthOptionProperty.Type.SIGNING, t -> w -> {
w.write("authParameters.region");
}))
.build());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

package software.amazon.smithy.typescript.codegen.auth.http.integration;

import software.amazon.smithy.typescript.codegen.Dependency;
import software.amazon.smithy.typescript.codegen.auth.AuthUtils;
import software.amazon.smithy.typescript.codegen.extensions.ExtensionConfigurationInterface;
import software.amazon.smithy.utils.Pair;
import software.amazon.smithy.utils.SmithyInternalApi;

/**
* Adds the corresponding interface and functions for {@code HttpAuthExtensionConfiguration}.
*
* This is experimental for `experimentalIdentityAndAuth`.
*/
@SmithyInternalApi
public class HttpAuthExtensionConfigurationInterface implements ExtensionConfigurationInterface {
@Override
public Pair<String, Dependency> name() {
return Pair.of("HttpAuthExtensionConfiguration", AuthUtils.AUTH_HTTP_EXTENSION_DEPENDENCY);
}

@Override
public Pair<String, Dependency> getExtensionConfigurationFn() {
return Pair.of("getHttpAuthExtensionConfiguration", AuthUtils.AUTH_HTTP_EXTENSION_DEPENDENCY);
}

@Override
public Pair<String, Dependency> resolveRuntimeConfigFn() {
return Pair.of("resolveHttpAuthRuntimeConfig", AuthUtils.AUTH_HTTP_EXTENSION_DEPENDENCY);
}
}
Loading