Skip to content

Commit

Permalink
Skip code generation of data filter functions for shapes that do not …
Browse files Browse the repository at this point in the history
…contain sensitive fields (recursive) (#722)

* check for sensitive data before generating a filter function

* use forward recursive selector

* include streaming in traits for which to generate filter

* fix indentation

* sensitive data check for unions

* remove tests for non-generated unions

* skip filters for insensitive properties in structures

* pass dependency

* formatting

* move model to initialization in SensitiveDataFinder
  • Loading branch information
kuhe authored Mar 22, 2023
1 parent c662462 commit e2325f6
Show file tree
Hide file tree
Showing 7 changed files with 945 additions and 656 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,22 @@
import software.amazon.smithy.model.traits.ErrorTrait;
import software.amazon.smithy.typescript.codegen.TypeScriptSettings.RequiredMemberMode;
import software.amazon.smithy.typescript.codegen.integration.HttpProtocolGeneratorUtils;
import software.amazon.smithy.typescript.codegen.validation.SensitiveDataFinder;
import software.amazon.smithy.utils.SmithyInternalApi;

/**
* Generates normal structures and error structures.
*
* Renders structures as interfaces.
*
* <p>A namespace is created with the same name as the structure to
* <p>
* A namespace is created with the same name as the structure to
* provide helper functionality for checking if a given value is
* known to be of the same type as the structure. This will be
* even more useful if/when inheritance is added to Smithy.
*
* <p>Note that the {@code required} trait on structures is used to
* <p>
* Note that the {@code required} trait on structures is used to
* determine whether or not a generated TypeScript interface uses
* required members. This is typically not recommended in other languages
* since it's documented as backward-compatible for a model to migrate a
Expand All @@ -55,7 +58,8 @@
* deserializers will need to set previously required properties to
* undefined too.
*
* <p>The generator will explicitly state that a required property can
* <p>
* The generator will explicitly state that a required property can
* be set to {@code undefined}. This makes it clear that undefined checks
* need to be made when using {@code --strictNullChecks}, but has no
* effect otherwise.
Expand All @@ -69,28 +73,30 @@ final class StructureGenerator implements Runnable {
private final StructureShape shape;
private final boolean includeValidation;
private final RequiredMemberMode requiredMemberMode;
private final SensitiveDataFinder sensitiveDataFinder;

/**
* sets 'includeValidation' to 'false' and requiredMemberMode
* to {@link RequiredMemberMode#NULLABLE}.
*/
StructureGenerator(Model model, SymbolProvider symbolProvider, TypeScriptWriter writer, StructureShape shape) {
this(model, symbolProvider, writer, shape, false,
RequiredMemberMode.NULLABLE);
RequiredMemberMode.NULLABLE);
}

StructureGenerator(Model model,
SymbolProvider symbolProvider,
TypeScriptWriter writer,
StructureShape shape,
boolean includeValidation,
RequiredMemberMode requiredMemberMode) {
SymbolProvider symbolProvider,
TypeScriptWriter writer,
StructureShape shape,
boolean includeValidation,
RequiredMemberMode requiredMemberMode) {
this.model = model;
this.symbolProvider = symbolProvider;
this.writer = writer;
this.shape = shape;
this.includeValidation = includeValidation;
this.requiredMemberMode = requiredMemberMode;
sensitiveDataFinder = new SensitiveDataFinder(model);
}

@Override
Expand All @@ -105,20 +111,24 @@ public void run() {
/**
* Renders a normal, non-error structure.
*
* <p>For example, given the following Smithy model:
* <p>
* For example, given the following Smithy model:
*
* <pre>{@code
* <pre>
* {@code
* namespace smithy.example
*
* structure Person {
* @required
* &#64;required
* name: String,
* @range(min: 1)
* &#64;range(min: 1)
* age: Integer,
* }
* }</pre>
* }
* </pre>
*
* <p>The following TypeScript is rendered:
* <p>
* The following TypeScript is rendered:
*
* <pre>{@code
* export interface Person {
Expand All @@ -129,7 +139,8 @@ public void run() {
* export const PersonFilterSensitiveLog = (obj: Person): any => ({...obj});
* }</pre>
*
* <p>If validation is enabled, it generates the following:
* <p>
* If validation is enabled, it generates the following:
*
* <pre>{@code
* export interface Person {
Expand Down Expand Up @@ -164,7 +175,11 @@ private void renderNonErrorStructure() {
}

StructuredMemberWriter config = new StructuredMemberWriter(
model, symbolProvider, shape.getAllMembers().values(), this.requiredMemberMode);
model,
symbolProvider,
shape.getAllMembers().values(),
this.requiredMemberMode,
sensitiveDataFinder);
config.writeMembers(writer, shape);
writer.closeBlock("}");
writer.write("");
Expand All @@ -174,15 +189,17 @@ private void renderNonErrorStructure() {
private void renderStructureNamespace(StructuredMemberWriter structuredMemberWriter, boolean includeValidation) {
Symbol symbol = symbolProvider.toSymbol(shape);
String objectParam = "obj";
writer.writeDocs("@internal");
writer.openBlock("export const $LFilterSensitiveLog = ($L: $L): any => ({", "})",
symbol.getName(),
objectParam,
symbol.getName(),
() -> {
structuredMemberWriter.writeFilterSensitiveLog(writer, objectParam);
}
);

if (sensitiveDataFinder.findsSensitiveDataIn(shape)) {
writer.writeDocs("@internal");
writer.openBlock("export const $LFilterSensitiveLog = ($L: $L): any => ({", "})",
symbol.getName(),
objectParam,
symbol.getName(),
() -> {
structuredMemberWriter.writeFilterSensitiveLog(writer, objectParam);
});
}

if (!includeValidation) {
return;
Expand Down Expand Up @@ -212,19 +229,23 @@ private void renderStructureNamespace(StructuredMemberWriter structuredMemberWri
* (ServiceException in case of server SDK), and add the appropriate fault
* property.
*
* <p>Given the following Smithy structure:
* <p>
* Given the following Smithy structure:
*
* <pre>{@code
* <pre>
* {@code
* namespace smithy.example
*
* @error("client")
* &#64;error("client")
* structure NoSuchResource {
* @required
* &#64;required
* resourceType: String
* }
* }</pre>
* }
* </pre>
*
* <p>The following TypeScript is generated:
* <p>
* The following TypeScript is generated:
*
* <pre>{@code
* import { ExceptionOptionType as __ExceptionOptionType } from "@aws-sdk/smithy-client";
Expand Down Expand Up @@ -261,8 +282,9 @@ private void renderErrorStructure() {
HttpProtocolGeneratorUtils.writeRetryableTrait(writer, shape, ";");
}
StructuredMemberWriter structuredMemberWriter = new StructuredMemberWriter(model, symbolProvider,
shape.getAllMembers().values(), this.requiredMemberMode);
// since any error interface must extend from JavaScript Error interface, message member is already
shape.getAllMembers().values(), this.requiredMemberMode, sensitiveDataFinder);
// since any error interface must extend from JavaScript Error interface,
// message member is already
// required in the JavaScript Error interface
structuredMemberWriter.skipMembers.add("message");
structuredMemberWriter.writeMembers(writer, shape);
Expand Down
Loading

0 comments on commit e2325f6

Please sign in to comment.