Skip to content

Add experimentalIdentityAndAuth flag #857

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
Aug 9, 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
12 changes: 12 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@ In order to utilise this feature, create a file `local.properties` in the projec
smithy=/Volumes/workplace/smithy
```

## Experimental Features

The `smithy-typescript` repository is under heavy development, and has experimental features that can affect consumers
of code generation packages and TypeScript packages. These features are enabled via opt-in settings in
`smithy-build.json`. 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.

## Reporting Bugs/Feature Requests

We welcome you to use the GitHub issue tracker to report bugs or suggest features.
Expand Down
15 changes: 15 additions & 0 deletions smithy-typescript-codegen-test/smithy-build.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,21 @@
"disableDefaultValidation": true
}
}
},
"client-experimental-identity-and-auth": {
"plugins": {
"typescript-codegen": {
"service": "example.weather#Weather",
"targetNamespace": "Weather",
"package": "weather",
"packageVersion": "0.0.1",
"packageJson": {
"license": "Apache-2.0",
"private": true
},
"experimentalIdentityAndAuth": true
}
}
}
},
"plugins": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public final class TypeScriptSettings {
private static final String PRIVATE = "private";
private static final String PACKAGE_MANAGER = "packageManager";
private static final String CREATE_DEFAULT_README = "createDefaultReadme";
private static final String EXPERIMENTAL_IDENTITY_AND_AUTH = "experimentalIdentityAndAuth";

private String packageName;
private String packageDescription = "";
Expand All @@ -74,6 +75,7 @@ public final class TypeScriptSettings {
RequiredMemberMode.NULLABLE;
private PackageManager packageManager = PackageManager.YARN;
private boolean createDefaultReadme = false;
private boolean experimentalIdentityAndAuth = false;

@Deprecated
public static TypeScriptSettings from(Model model, ObjectNode config) {
Expand Down Expand Up @@ -107,6 +109,8 @@ public static TypeScriptSettings from(Model model, ObjectNode config, ArtifactTy
settings.setPrivate(config.getBooleanMember(PRIVATE).map(BooleanNode::getValue).orElse(false));
settings.setCreateDefaultReadme(
config.getBooleanMember(CREATE_DEFAULT_README).map(BooleanNode::getValue).orElse(false));
settings.setExperimentalIdentityAndAuth(
config.getBooleanMemberOrDefault(EXPERIMENTAL_IDENTITY_AND_AUTH, false));
settings.setPackageManager(
config.getStringMember(PACKAGE_MANAGER)
.map(s -> PackageManager.fromString(s.getValue()))
Expand Down Expand Up @@ -352,6 +356,31 @@ public void setPackageManager(PackageManager packageManager) {
this.packageManager = packageManager;
}

/**
* Returns whether to use experimental identity and auth.
*
* @return if experimental identity and auth should used. Default: false
*/
public boolean getExperimentalIdentityAndAuth() {
return experimentalIdentityAndAuth;
}

/**
* Sets whether experimental identity and auth should be used.
*
* @param experimentalIdentityAndAuth whether experimental identity and auth should be used.
*/
public void setExperimentalIdentityAndAuth(boolean experimentalIdentityAndAuth) {
if (experimentalIdentityAndAuth) {
LOGGER.warning("""
Experimental identity and auth is in development, and is subject to \
breaking changes. Behavior may NOT have the same feature parity as \
non-experimental behavior. This setting is also subject to removal \
when the feature is completed.""");
}
this.experimentalIdentityAndAuth = experimentalIdentityAndAuth;
}

/**
* Gets the corresponding {@link ServiceShape} from a model.
*
Expand Down Expand Up @@ -440,7 +469,7 @@ public enum ArtifactType {
CLIENT(SymbolVisitor::new,
Arrays.asList(PACKAGE, PACKAGE_DESCRIPTION, PACKAGE_JSON, PACKAGE_VERSION, PACKAGE_MANAGER,
SERVICE, PROTOCOL, TARGET_NAMESPACE, PRIVATE, REQUIRED_MEMBER_MODE,
CREATE_DEFAULT_README)),
CREATE_DEFAULT_README, EXPERIMENTAL_IDENTITY_AND_AUTH)),
SSDK((m, s) -> new ServerSymbolVisitor(m, new SymbolVisitor(m, s)),
Arrays.asList(PACKAGE, PACKAGE_DESCRIPTION, PACKAGE_JSON, PACKAGE_VERSION, PACKAGE_MANAGER,
SERVICE, PROTOCOL, TARGET_NAMESPACE, PRIVATE, REQUIRED_MEMBER_MODE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public List<RuntimeClientPlugin> getClientPlugins() {
.name("resolveHttpApiKeyAuthConfig")
.build())
.servicePredicate((m, s) -> hasEffectiveHttpApiKeyAuthTrait(m, s))
.settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth())
.build(),

// Add the middleware to operations that use HTTP API key authorization.
Expand All @@ -96,12 +97,17 @@ public List<RuntimeClientPlugin> getClientPlugins() {
.keySet()
.contains(HttpApiKeyAuthTrait.ID)
&& !o.hasTrait(OptionalAuthTrait.class))
.settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth())
.build()
);
}

@Override
public void customize(TypeScriptCodegenContext codegenContext) {
if (codegenContext.settings().getExperimentalIdentityAndAuth()) {
return;
}
// feat(experimentalIdentityAndAuth): control branch for @httpApiKeyAuth
TypeScriptSettings settings = codegenContext.settings();
Model model = codegenContext.model();
BiConsumer<String, Consumer<TypeScriptWriter>> writerFactory = codegenContext.writerDelegator()::useFileWriter;
Expand Down