Skip to content

Commit 87decd3

Browse files
author
Steven Yuan
committed
feat(experimentalIdentityAndAuth): enable identity and auth by default
`experimentalIdentityAndAuth` behavior is now the default auth behavior. The `experimentalIdentityAndAuth` flag is now oppositely replaced with `useLegacyAuth`, which enables legacy auth behavior for backward compatibility concerns.
1 parent 4ad5f3a commit 87decd3

28 files changed

+205
-96
lines changed

.changeset/four-cougars-collect.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---
2+
---

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ under development:
3030

3131
Experimental Feature | Flag | Description
3232
---------------------|-------------------------------|------------
33-
Identity & Auth | `experimentalIdentityAndAuth` | Standardize identity and auth integrations to match the Smithy specification (see [Authentication Traits](https://smithy.io/2.0/spec/authentication-traits.html)). Newer capabilities include support for multiple auth schemes, `@optionalAuth`, and standardized identity interfaces for authentication schemes both in code generation and TypeScript packages. In `smithy-typescript`, `@httpApiKeyAuth` will be updated to use the new standardized interfaces. In `aws-sdk-js-v3` (`smithy-typescript`'s largest customer), this will affect `@aws.auth#sigv4` and `@httpBearerAuth` implementations, but is planned to be completely backwards-compatible.
33+
N/A | N/A | N/A
3434

3535
## Reporting Bugs/Feature Requests
3636

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ By default, the Smithy TypeScript code generators provide the code generation fr
197197
|`private`|No|Whether the package is `private` in `package.json`. The default value is `false`.|
198198
|`requiredMemberMode`|No|**NOT RECOMMENDED DUE TO BACKWARD COMPATIBILITY CONCERNS.** Sets whether members marked with the `@required` trait are allowed to be `undefined`. See more details on the risks in `TypeScriptSettings.RequiredMemberMode`. The default value is `nullable`.|
199199
|`createDefaultReadme`|No|Whether to generate a default `README.md` for the package. The default value is `false`.|
200-
|`experimentalIdentityAndAuth`|No|Experimental feature that standardizes identity and auth integrations to match the Smithy specification (see [Authentication Traits](https://smithy.io/2.0/spec/authentication-traits.html)). See [the experimental features section for more details](CONTRIBUTING.md#experimental-features).|
200+
|`useLegacyAuth`|No|**NOT RECOMMENDED, AVAILABLE ONLY FOR BACKWARD COMPATIBILITY CONCERNS.** Flag that enables using legacy auth. When in doubt, use the default identity and auth behavior (not configuring `useLegacyAuth`) as the golden path.|
201201

202202
#### `typescript-client-codegen` plugin artifacts
203203

packages/experimental-identity-and-auth/src/integration/httpApiKeyAuth.integ.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
import { requireRequestsFrom } from "@smithy/util-test";
88

99
describe("@httpApiKeyAuth integration tests", () => {
10-
// TODO(experimentalIdentityAndAuth): should match `HttpApiKeyAuthService` `@httpApiKeyAuth` trait
10+
// Match `HttpApiKeyAuthService` `@httpApiKeyAuth` trait
1111
const MOCK_API_KEY_NAME = "Authorization";
1212
const MOCK_API_KEY_SCHEME = "ApiKey";
1313
const MOCK_API_KEY = "APIKEY_123";

scripts/build-generated-test-packages.js

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ const releasedClientDir = path.join(
3737
"typescript-codegen"
3838
);
3939

40-
// TODO(experimentalIdentityAndAuth): build generic client for integration tests
41-
const weatherExperimentalIdentityAndAuthClientDir = path.join(
40+
// Build generic legacy auth client for integration tests
41+
const weatherLegacyAuthClientDir = path.join(
4242
codegenTestDir,
43-
"client-experimental-identity-and-auth",
43+
"client-legacy-auth",
4444
"typescript-client-codegen"
4545
);
4646

@@ -50,14 +50,14 @@ const weatherSsdkDir = path.join(
5050
"typescript-server-codegen"
5151
)
5252

53-
// TODO(experimentalIdentityAndAuth): add `@httpApiKeyAuth` client for integration tests
53+
// Build `@httpApiKeyAuth` client for integration tests
5454
const httpApiKeyAuthClientDir = path.join(
5555
codegenTestDir,
5656
"identity-and-auth-http-api-key-auth",
5757
"typescript-client-codegen"
5858
);
5959

60-
// TODO(experimentalIdentityAndAuth): add `@httpBearerAuth` client for integration tests
60+
// Build `@httpBearerAuth` client for integration tests
6161
const httpBearerAuthClientDir = path.join(
6262
codegenTestDir,
6363
"identity-and-auth-http-bearer-auth",
@@ -94,11 +94,8 @@ const buildAndCopyToNodeModules = async (packageName, codegenDir, nodeModulesDir
9494
(async () => {
9595
await buildAndCopyToNodeModules("weather", weatherClientDir, nodeModulesDir);
9696
await buildAndCopyToNodeModules("weather-ssdk", weatherSsdkDir, nodeModulesDir);
97-
// TODO(experimentalIdentityAndAuth): build generic client for integration tests
98-
await buildAndCopyToNodeModules("@smithy/weather-experimental-identity-and-auth", weatherExperimentalIdentityAndAuthClientDir, nodeModulesDir);
99-
// TODO(experimentalIdentityAndAuth): add `@httpApiKeyAuth` client for integration tests
97+
await buildAndCopyToNodeModules("@smithy/weather-legacy-auth", weatherLegacyAuthClientDir, nodeModulesDir);
10098
await buildAndCopyToNodeModules("@smithy/identity-and-auth-http-api-key-auth-service", httpApiKeyAuthClientDir, nodeModulesDir);
101-
// TODO(experimentalIdentityAndAuth): add `@httpBearerAuth` client for integration tests
10299
await buildAndCopyToNodeModules("@smithy/identity-and-auth-http-bearer-auth-service", httpBearerAuthClientDir, nodeModulesDir);
103100
// TODO(released-version-test): Test released version of smithy-typescript codegenerators, but currently is not working
104101
// await buildAndCopyToNodeModules("released", releasedClientDir, undefined);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package example.weather;
7+
8+
import java.util.Optional;
9+
import java.util.function.Consumer;
10+
import software.amazon.smithy.codegen.core.Symbol;
11+
import software.amazon.smithy.codegen.core.SymbolReference;
12+
import software.amazon.smithy.model.shapes.ShapeId;
13+
import software.amazon.smithy.typescript.codegen.ApplicationProtocol;
14+
import software.amazon.smithy.typescript.codegen.LanguageTarget;
15+
import software.amazon.smithy.typescript.codegen.TypeScriptDependency;
16+
import software.amazon.smithy.typescript.codegen.TypeScriptSettings;
17+
import software.amazon.smithy.typescript.codegen.TypeScriptWriter;
18+
import software.amazon.smithy.typescript.codegen.auth.http.ConfigField;
19+
import software.amazon.smithy.typescript.codegen.auth.http.HttpAuthOptionProperty;
20+
import software.amazon.smithy.typescript.codegen.auth.http.HttpAuthScheme;
21+
import software.amazon.smithy.typescript.codegen.auth.http.HttpAuthSchemeParameter;
22+
import software.amazon.smithy.typescript.codegen.auth.http.integration.HttpAuthTypeScriptIntegration;
23+
import software.amazon.smithy.utils.SmithyInternalApi;
24+
25+
@SmithyInternalApi
26+
public final class SupportWeatherSigV4Auth implements HttpAuthTypeScriptIntegration {
27+
static final Symbol AWS_CREDENTIAL_IDENTITY = Symbol.builder()
28+
.name("AwsCredentialIdentity")
29+
.namespace(TypeScriptDependency.SMITHY_TYPES.getPackageName(), "/")
30+
.addDependency(TypeScriptDependency.SMITHY_TYPES)
31+
.build();
32+
static final Symbol AWS_CREDENTIAL_IDENTITY_PROVIDER = Symbol.builder()
33+
.name("AwsCredentialIdentityProvider")
34+
.namespace(TypeScriptDependency.SMITHY_TYPES.getPackageName(), "/")
35+
.addDependency(TypeScriptDependency.SMITHY_TYPES)
36+
.build();
37+
static final ConfigField CREDENTIALS_CONFIG_FIELD = ConfigField.builder()
38+
.name("credentials")
39+
.type(ConfigField.Type.MAIN)
40+
.docs(w -> w.write("The credentials used to sign requests."))
41+
.inputType(Symbol.builder()
42+
.name("AwsCredentialIdentity | AwsCredentialIdentityProvider")
43+
.addReference(AWS_CREDENTIAL_IDENTITY)
44+
.addReference(AWS_CREDENTIAL_IDENTITY_PROVIDER)
45+
.build())
46+
.resolvedType(Symbol.builder()
47+
.name("AwsCredentialIdentityProvider")
48+
.addReference(AWS_CREDENTIAL_IDENTITY)
49+
.addReference(AWS_CREDENTIAL_IDENTITY_PROVIDER)
50+
.build())
51+
.configFieldWriter(ConfigField::defaultMainConfigFieldWriter)
52+
.build();
53+
private static final Consumer<TypeScriptWriter> AWS_SIGV4_AUTH_SIGNER = w -> {
54+
w.addDependency(TypeScriptDependency.EXPERIMENTAL_IDENTITY_AND_AUTH);
55+
w.addImport("SigV4Signer", null, TypeScriptDependency.EXPERIMENTAL_IDENTITY_AND_AUTH);
56+
w.write("new SigV4Signer()");
57+
};
58+
private static final SymbolReference PROVIDER = SymbolReference.builder()
59+
.symbol(Symbol.builder()
60+
.name("Provider")
61+
.namespace(TypeScriptDependency.SMITHY_TYPES.getPackageName(), "/")
62+
.addDependency(TypeScriptDependency.SMITHY_TYPES)
63+
.build())
64+
.alias("__Provider")
65+
.build();
66+
67+
@Override
68+
public boolean matchesSettings(TypeScriptSettings settings) {
69+
return !settings.useLegacyAuth();
70+
}
71+
72+
@Override
73+
public Optional<HttpAuthScheme> getHttpAuthScheme() {
74+
return Optional.of(HttpAuthScheme.builder()
75+
.schemeId(ShapeId.from("aws.auth#sigv4"))
76+
.applicationProtocol(ApplicationProtocol.createDefaultHttpApplicationProtocol())
77+
.putDefaultSigner(LanguageTarget.SHARED, AWS_SIGV4_AUTH_SIGNER)
78+
.addConfigField(CREDENTIALS_CONFIG_FIELD)
79+
.addConfigField(ConfigField.builder()
80+
.name("region")
81+
.type(ConfigField.Type.AUXILIARY)
82+
.docs(w -> w.write("The AWS region to which this client will send requests."))
83+
.inputType(Symbol.builder()
84+
.name("string | __Provider<string>")
85+
.addReference(PROVIDER)
86+
.build())
87+
.resolvedType(Symbol.builder()
88+
.name("__Provider<string>")
89+
.addReference(PROVIDER)
90+
.build())
91+
.configFieldWriter(ConfigField::defaultAuxiliaryConfigFieldWriter)
92+
.build())
93+
.addHttpAuthSchemeParameter(HttpAuthSchemeParameter.builder()
94+
.name("region")
95+
.type(w -> w.write("string"))
96+
.source(w -> {
97+
w.addDependency(TypeScriptDependency.UTIL_MIDDLEWARE);
98+
w.addImport("normalizeProvider", null, TypeScriptDependency.UTIL_MIDDLEWARE);
99+
w.openBlock("await normalizeProvider(config.region)() || (() => {", "})()", () -> {
100+
w.write("throw new Error(\"expected `region` to be configured for `aws.auth#sigv4`\");");
101+
});
102+
})
103+
.build())
104+
.addHttpAuthOptionProperty(HttpAuthOptionProperty.builder()
105+
.name("name")
106+
.type(HttpAuthOptionProperty.Type.SIGNING)
107+
.source(s -> w -> {
108+
w.write("$S", s.trait().toNode().expectObjectNode().getMember("name"));
109+
})
110+
.build())
111+
.addHttpAuthOptionProperty(HttpAuthOptionProperty.builder()
112+
.name("region")
113+
.type(HttpAuthOptionProperty.Type.SIGNING)
114+
.source(t -> w -> {
115+
w.write("authParameters.region");
116+
})
117+
.build())
118+
.propertiesExtractor(s -> w -> w
119+
.write("""
120+
(config, context) => {
121+
return {
122+
/**
123+
* @internal
124+
*/
125+
signingProperties: {
126+
...config,
127+
...context,
128+
},
129+
};
130+
},"""))
131+
.build());
132+
}
133+
}
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
example.weather.ExampleWeatherCustomEndpointsRuntimeConfig
2+
example.weather.SupportWeatherSigV4Auth

smithy-typescript-codegen-test/model/weather/main.smithy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ service Weather {
3434
GetCurrentTime
3535
// util-stream.integ.spec.ts
3636
Invoke
37-
// experimentalIdentityAndAuth
37+
// Identity and Auth
3838
OnlyHttpApiKeyAuth
3939
OnlyHttpApiKeyAuthOptional
4040
OnlyHttpBearerAuth

smithy-typescript-codegen-test/smithy-build.json

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
}
3030
}
3131
},
32-
"client-experimental-identity-and-auth": {
32+
"client-identity-and-auth": {
3333
"transforms": [
3434
{
3535
"name": "includeServices",
@@ -41,17 +41,16 @@
4141
"plugins": {
4242
"typescript-client-codegen": {
4343
"service": "example.weather#Weather",
44-
"package": "@smithy/weather-experimental-identity-and-auth",
44+
"package": "weather",
4545
"packageVersion": "0.0.1",
4646
"packageJson": {
4747
"license": "Apache-2.0",
4848
"private": true
49-
},
50-
"experimentalIdentityAndAuth": true
49+
}
5150
}
5251
}
5352
},
54-
"control-experimental-identity-and-auth": {
53+
"client-legacy-auth": {
5554
"transforms": [
5655
{
5756
"name": "includeServices",
@@ -63,12 +62,13 @@
6362
"plugins": {
6463
"typescript-client-codegen": {
6564
"service": "example.weather#Weather",
66-
"package": "weather",
65+
"package": "@smithy/weather-legacy-auth",
6766
"packageVersion": "0.0.1",
6867
"packageJson": {
6968
"license": "Apache-2.0",
7069
"private": true
71-
}
70+
},
71+
"useLegacyAuth": true
7272
}
7373
}
7474
},
@@ -89,8 +89,7 @@
8989
"packageJson": {
9090
"license": "Apache-2.0",
9191
"private": true
92-
},
93-
"experimentalIdentityAndAuth": true
92+
}
9493
}
9594
}
9695
},
@@ -111,8 +110,7 @@
111110
"packageJson": {
112111
"license": "Apache-2.0",
113112
"private": true
114-
},
115-
"experimentalIdentityAndAuth": true
113+
}
116114
}
117115
}
118116
}

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/DirectedTypeScriptCodegen.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -241,9 +241,7 @@ private void generateClient(GenerateServiceDirective<TypeScriptCodegenContext, T
241241
delegator.useShapeWriter(service, writer -> new ServiceBareBonesClientGenerator(
242242
settings, model, symbolProvider, writer, integrations, runtimePlugins, applicationProtocol).run());
243243

244-
if (directive.settings().getExperimentalIdentityAndAuth()) {
245-
// feat(experimentalIdentityAndAuth): allow configuring custom HttpAuthSchemeProviderGenerator
246-
LOGGER.fine("experimentalIdentityAndAuth: Generating auth scheme resolver");
244+
if (!directive.settings().useLegacyAuth()) {
247245
new HttpAuthSchemeProviderGenerator(
248246
delegator,
249247
settings,

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/RuntimeConfigGenerator.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -195,10 +195,9 @@ void generate(LanguageTarget target) {
195195
integration.getRuntimeConfigWriters(settings, model, symbolProvider, target)
196196
);
197197
}
198-
// feat(experimentalIdentityAndAuth): add config writers for httpAuthScheme and httpAuthSchemes
199198
// Needs a separate integration point since not all the information is accessible in
200199
// {@link TypeScriptIntegration#getRuntimeConfigWriters()}
201-
if (applicationProtocol.isHttpProtocol() && settings.getExperimentalIdentityAndAuth()) {
200+
if (applicationProtocol.isHttpProtocol() && !settings.useLegacyAuth()) {
202201
generateHttpAuthSchemeConfig(configs, writer, target);
203202
}
204203
int indentation = target.equals(LanguageTarget.SHARED) ? 1 : 2;
@@ -229,7 +228,6 @@ private void generateHttpAuthSchemeConfig(
229228
) {
230229
SupportedHttpAuthSchemesIndex authIndex = new SupportedHttpAuthSchemesIndex(integrations, model, settings);
231230

232-
// feat(experimentalIdentityAndAuth): write the default imported HttpAuthSchemeProvider
233231
if (target.equals(LanguageTarget.SHARED)) {
234232
configs.put("httpAuthSchemeProvider", w -> {
235233
w.write("$T", Symbol.builder()
@@ -241,7 +239,6 @@ private void generateHttpAuthSchemeConfig(
241239
});
242240
}
243241

244-
// feat(experimentalIdentityAndAuth): gather HttpAuthSchemes to generate
245242
ServiceIndex serviceIndex = ServiceIndex.of(model);
246243
TopDownIndex topDownIndex = TopDownIndex.of(model);
247244
Map<ShapeId, HttpAuthScheme> allEffectiveHttpAuthSchemes =
@@ -268,7 +265,6 @@ private void generateHttpAuthSchemeConfig(
268265
return;
269266
}
270267

271-
// feat(experimentalIdentityAndAuth): write the default httpAuthSchemes
272268
configs.put("httpAuthSchemes", w -> {
273269
w.addDependency(TypeScriptDependency.SMITHY_TYPES);
274270
w.addImport("IdentityProviderConfig", null, TypeScriptDependency.SMITHY_TYPES);

smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/TypeScriptDependency.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ public enum TypeScriptDependency implements Dependency {
124124
// Conditionally added when @aws.auth#sigv4 is used
125125
SIGNATURE_V4("dependencies", "@smithy/signature-v4", false),
126126

127-
// feat(experimentalIdentityAndAuth): Conditionally added dependencies for `experimentalIdentityAndAuth`.
128127
// This package should never have a major version, and should only use minor and patch versions in development.
129128
// Exports are located between @smithy/types and @smithy/core
130129
@Deprecated EXPERIMENTAL_IDENTITY_AND_AUTH("dependencies", "@smithy/experimental-identity-and-auth", false),

0 commit comments

Comments
 (0)