Skip to content

Commit

Permalink
feat(experimentalIdentityAndAuth): add experimentalIdentityAndAuth
Browse files Browse the repository at this point in the history
…flag (#5065)

As part of feature development of `experimentalIdentityAndAuth`, add
control branches for existing behavior in existing integrations,
particularly `@aws.auth#sigv4` and `@httpBearerTokenAuth`:

- `AddAwsAuthPlugin`
- `AddAwsRuntimeConfig`
- `AddBuiltinPlugins`
- `AddEventBridgePlugin`
- `AddS3Config`
- `AddS3ControlDependency`
- `AddTokenAuthPlugin`
- `AddEventStreamHandlingDependency`

Also, add a section in `CONTRIBUTING.md` about experimental features in `smithy-typescript`
used in `aws-sdk-js-v3`.
  • Loading branch information
Steven Yuan authored Aug 9, 2023
1 parent edf49b3 commit 07a70fb
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 4 deletions.
11 changes: 11 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,17 @@ smithy=/Volumes/workplace/smithy
smithy-typescript=/Volumes/workplace/smithy-typescript
```

## Experimental Features

`aws-sdk-js-v3 ` uses `smithy-typescript` to generate code. `smithy-typescript` is under heavy development and has
experimental features that can affect `aws-sdk-js-v3`. These features are enabled via opt-in settings in `sdk-codegen`.
Note that any contributions related to these features MUST be reviewed carefully for opt-in behavior via feature flags
as to not break any existing customers. Here are the experimental features that are currently under development:

| Experimental Feature | Flag | Description |
| -------------------- | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 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. |

## Build caching

Build caching is optionally available via Turborepo. See `turbo.json`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ public void addConfigInterfaceFields(
SymbolProvider symbolProvider,
TypeScriptWriter writer
) {
if (settings.getExperimentalIdentityAndAuth()) {
return;
}
// feat(experimentalIdentityAndAuth): control branch for @aws.auth#sigv4
ServiceShape service = settings.getService(model);
if (!isSigV4Service(service) && isAwsService(service)) {
ServiceTrait serviceTrait = service.getTrait(ServiceTrait.class).get();
Expand Down Expand Up @@ -120,12 +124,14 @@ public List<RuntimeClientPlugin> getClientPlugins() {
&& isAwsService(s)
&& !testServiceId(s, "STS")
&& !areAllOptionalAuthOperations(m, s))
.settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth())
.build(),
RuntimeClientPlugin.builder()
.withConventions(AwsDependency.MIDDLEWARE_SIGNING.dependency, "SigV4Auth", HAS_CONFIG)
.servicePredicate((m, s) -> isSigV4Service(s)
&& !isAwsService(s)
&& !areAllOptionalAuthOperations(m, s))
.settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth())
.build(),
RuntimeClientPlugin.builder()
.withConventions(AwsDependency.STS_MIDDLEWARE.dependency,
Expand All @@ -134,33 +140,38 @@ && isAwsService(s)
put("stsClientCtor", Symbol.builder().name("STSClient").build());
}})
.servicePredicate((m, s) -> testServiceId(s, "STS"))
.settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth())
.build(),
RuntimeClientPlugin.builder()
.withConventions(AwsDependency.MIDDLEWARE_SIGNING.dependency, "AwsAuth", HAS_MIDDLEWARE)
// See operationUsesAwsAuth() below for AwsAuth Middleware customizations.
.servicePredicate((m, s) -> isSigV4Service(s)
&& isAwsService(s)
&& !testServiceId(s, "STS")
&& !hasOptionalAuthOperation(m, s)
).build(),
&& !hasOptionalAuthOperation(m, s))
.settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth())
.build(),
RuntimeClientPlugin.builder()
.withConventions(AwsDependency.MIDDLEWARE_SIGNING.dependency, "SigV4Auth", HAS_MIDDLEWARE)
// See operationUsesAwsAuth() below for AwsAuth Middleware customizations.
.servicePredicate((m, s) -> isSigV4Service(s)
&& !isAwsService(s)
&& !hasOptionalAuthOperation(m, s)
).build(),
&& !hasOptionalAuthOperation(m, s))
.settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth())
.build(),
RuntimeClientPlugin.builder()
.withConventions(AwsDependency.MIDDLEWARE_SIGNING.dependency, "AwsAuth", HAS_MIDDLEWARE)
.operationPredicate((m, s, o) -> isSigV4Service(s)
&& isAwsService(s)
&& operationUsesAwsAuth(m, s, o))
.settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth())
.build(),
RuntimeClientPlugin.builder()
.withConventions(AwsDependency.MIDDLEWARE_SIGNING.dependency, "SigV4Auth", HAS_MIDDLEWARE)
.operationPredicate((m, s, o) -> isSigV4Service(s)
&& !isAwsService(s)
&& operationUsesAwsAuth(m, s, o))
.settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth())
.build()

);
Expand All @@ -173,6 +184,10 @@ public Map<String, Consumer<TypeScriptWriter>> getRuntimeConfigWriters(
SymbolProvider symbolProvider,
LanguageTarget target
) {
if (settings.getExperimentalIdentityAndAuth()) {
return Collections.emptyMap();
}
// feat(experimentalIdentityAndAuth): control branch for @aws.auth#sigv4
ServiceShape service = settings.getService(model);
if (!isSigV4Service(service) || areAllOptionalAuthOperations(model, service)) {
return Collections.emptyMap();
Expand Down Expand Up @@ -219,6 +234,10 @@ public Map<String, Consumer<TypeScriptWriter>> getRuntimeConfigWriters(

@Override
public void customize(TypeScriptCodegenContext codegenContext) {
if (codegenContext.settings().getExperimentalIdentityAndAuth()) {
return;
}
// feat(experimentalIdentityAndAuth): control branch for @aws.auth#sigv4
TypeScriptSettings settings = codegenContext.settings();
Model model = codegenContext.model();
BiConsumer<String, Consumer<TypeScriptWriter>> writerFactory = codegenContext.writerDelegator()::useFileWriter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ public void addConfigInterfaceFields(
writer.writeDocs("Enables FIPS compatible endpoints.")
.write("useFipsEndpoint?: boolean | __Provider<boolean>;\n");
}
if (settings.getExperimentalIdentityAndAuth()) {
return;
}
// feat(experimentalIdentityAndAuth): control branch for AWS config interface fields
if (isSigV4Service(settings, model)) {
writer.writeDocs(isAwsService(settings, model)
? "The AWS region to which this client will send requests"
Expand Down Expand Up @@ -134,6 +138,10 @@ private Map<String, Consumer<TypeScriptWriter>> getDefaultConfig(
if (!isSigV4Service(settings, model)) {
return Collections.emptyMap();
}
if (settings.getExperimentalIdentityAndAuth()) {
return Collections.emptyMap();
}
// feat(experimentalIdentityAndAuth): control branch for AWS runtime config
switch (target) {
case BROWSER:
return MapUtils.of("region", writer -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public List<RuntimeClientPlugin> getClientPlugins() {
RuntimeClientPlugin.builder()
.withConventions(TypeScriptDependency.CONFIG_RESOLVER.dependency, "Region", HAS_CONFIG)
.servicePredicate((m, s) -> isAwsService(s) || isSigV4Service(s))
.settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth())
.build(),
// Only one of Endpoints or CustomEndpoints should be used
RuntimeClientPlugin.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ public Map<String, Consumer<TypeScriptWriter>> getRuntimeConfigWriters(TypeScrip
if (!testServiceId(settings.getService(model))) {
return Collections.emptyMap();
}
if (settings.getExperimentalIdentityAndAuth()) {
return Collections.emptyMap();
}
// feat(experimentalIdentityAndAuth): control branch for EventBridge runtime config
switch (target) {
case SHARED:
return MapUtils.of("signerConstructor", writer -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,13 @@ public List<RuntimeClientPlugin> getClientPlugins() {
.withConventions(AwsDependency.MIDDLEWARE_EVENTSTREAM.dependency,
"EventStream", HAS_CONFIG)
.servicePredicate(AddEventStreamHandlingDependency::hasEventStreamInput)
.settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth())
.build(),
RuntimeClientPlugin.builder()
.withConventions(AwsDependency.MIDDLEWARE_EVENTSTREAM.dependency,
"EventStream", HAS_MIDDLEWARE)
.operationPredicate(AddEventStreamHandlingDependency::hasEventStreamInput)
.settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth())
.build()
);
}
Expand All @@ -68,6 +70,10 @@ public void addConfigInterfaceFields(
SymbolProvider symbolProvider,
TypeScriptWriter writer
) {
if (settings.getExperimentalIdentityAndAuth()) {
return;
}
// feat(experimentalIdentityAndAuth): control branch for event stream handler interface fields
if (hasEventStreamInput(model, settings.getService(model))) {
writer.addImport("EventStreamPayloadHandlerProvider", "__EventStreamPayloadHandlerProvider",
TypeScriptDependency.AWS_SDK_TYPES);
Expand All @@ -89,6 +95,10 @@ public Map<String, Consumer<TypeScriptWriter>> getRuntimeConfigWriters(
return Collections.emptyMap();
}

if (settings.getExperimentalIdentityAndAuth()) {
return Collections.emptyMap();
}
// feat(experimentalIdentityAndAuth): control branch for event stream handler runtime config
switch (target) {
case NODE:
return MapUtils.of("eventStreamPayloadHandlerProvider", writer -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ public void addConfigInterfaceFields(
if (!isS3(service)) {
return;
}
if (settings.getExperimentalIdentityAndAuth()) {
return;
}
// feat(experimentalIdentityAndAuth): control branch for S3 Config interface fields
writer.writeDocs("Whether to escape request path when signing the request.")
.write("signingEscapePath?: boolean;\n");
writer.writeDocs(
Expand All @@ -134,6 +138,10 @@ public Map<String, Consumer<TypeScriptWriter>> getRuntimeConfigWriters(
if (!isS3(settings.getService(model))) {
return Collections.emptyMap();
}
if (settings.getExperimentalIdentityAndAuth()) {
return Collections.emptyMap();
}
// feat(experimentalIdentityAndAuth): control branch for S3 Config runtime config
switch (target) {
case SHARED:
return MapUtils.of("signingEscapePath", writer -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ public Map<String, Consumer<TypeScriptWriter>> getRuntimeConfigWriters(
if (!isS3Control(settings.getService(model))) {
return Collections.emptyMap();
}
if (settings.getExperimentalIdentityAndAuth()) {
return Collections.emptyMap();
}
// feat(experimentalIdentityAndAuth): control branch for S3 Control signingEscapePath
switch (target) {
case SHARED:
return MapUtils.of("signingEscapePath", writer -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@ public List<RuntimeClientPlugin> getClientPlugins() {
RuntimeClientPlugin.builder()
.withConventions(AwsDependency.MIDDLEWARE_TOKEN.dependency, "Token", HAS_CONFIG)
.servicePredicate((m, s) -> isHttpBearerAuthService(s))
.settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth())
.build(),
RuntimeClientPlugin.builder()
.withConventions(AwsDependency.MIDDLEWARE_TOKEN.dependency, "Token", HAS_MIDDLEWARE)
.servicePredicate((m, s) -> isHttpBearerAuthService(s))
.settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth())
.build()
);
}
Expand Down

0 comments on commit 07a70fb

Please sign in to comment.