Skip to content

Commit

Permalink
fix: correctly redact sensitive data in lists/maps (#1122)
Browse files Browse the repository at this point in the history
  • Loading branch information
ianbotsf committed Jul 15, 2024
1 parent 34acdc7 commit 2652698
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changes/30110eeb-0708-45b6-973f-960dc6062ce6.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"id": "30110eeb-0708-45b6-973f-960dc6062ce6",
"type": "bugfix",
"description": "Correctly redact sensitive data in lists and maps"
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ import software.amazon.smithy.kotlin.codegen.core.*
import software.amazon.smithy.kotlin.codegen.lang.KotlinTypes
import software.amazon.smithy.kotlin.codegen.model.*
import software.amazon.smithy.kotlin.codegen.rendering.serde.ClientErrorCorrection
import software.amazon.smithy.model.Model
import software.amazon.smithy.model.shapes.*
import software.amazon.smithy.model.traits.*

private const val REDACTED_VALUE = "*** Sensitive Data Redacted ***"

/**
* Renders Smithy structure shapes
*/
Expand Down Expand Up @@ -105,18 +108,15 @@ class StructureGenerator(
write("append(\"#T(\")", symbol)

when {
shape.hasTrait<SensitiveTrait>() -> write("append(#S)", "*** Sensitive Data Redacted ***")
shape.isSensitive(model) -> write("append(#S)", REDACTED_VALUE)
else -> {
sortedMembers.forEachIndexed { index, memberShape ->
val (memberName, _) = memberNameSymbolIndex[memberShape]!!
val isSensitive = memberShape.isSensitive(model)
val value = if (isSensitive) REDACTED_VALUE else "\$$memberName"
val separator = if (index < sortedMembers.size - 1) "," else ""

val targetShape = model.expectShape(memberShape.target)
if (targetShape.hasTrait<SensitiveTrait>()) {
write("append(\"#1L=*** Sensitive Data Redacted ***$separator\")", memberName)
} else {
write("append(\"#1L=\$#2L$separator\")", memberShape.defaultName(), memberName)
}
write("append(\"#L=#L#L\")", memberShape.defaultName(), value, separator)
}
}
}
Expand Down Expand Up @@ -385,3 +385,11 @@ class StructureGenerator(
if (hasConflictWithBaseClass) throw CodegenException("`sdkErrorMetadata` conflicts with property of same name inherited from SdkBaseException. Apply a rename customization/projection to fix.")
}
}

private fun Shape.isSensitive(model: Model): Boolean = when {
this is MemberShape -> model.expectShape(target).isSensitive(model)
hasTrait<SensitiveTrait>() -> true
this is ListShape -> member.isSensitive(model)
this is MapShape -> key.isSensitive(model) || value.isSensitive(model)
else -> false
}
Original file line number Diff line number Diff line change
Expand Up @@ -285,11 +285,38 @@ class StructureGeneratorTest {
@sensitive
string Baz
list BazList {
member: Baz
}
map BazToStringMap {
key: Baz
value: String
}
map StringToBazMap {
key: String
value: Baz
}
map StringToBazList {
key: String
value: BazList
}
list StringToBazListList {
member: StringToBazList
}
structure Foo {
bar: Baz,
@documentation("Member documentation")
baz: Baz,
qux: String
qux: String,
quux: BazList,
corge: BazToStringMap,
grault: StringToBazMap,
garply: StringToBazList,
waldo: StringToBazListList,
}
""".prependNamespaceAndService().toSmithyModel()
Expand All @@ -306,7 +333,12 @@ class StructureGeneratorTest {
append("Foo(")
append("bar=*** Sensitive Data Redacted ***,")
append("baz=*** Sensitive Data Redacted ***,")
append("qux=${'$'}qux")
append("corge=*** Sensitive Data Redacted ***,")
append("garply=*** Sensitive Data Redacted ***,")
append("grault=*** Sensitive Data Redacted ***,")
append("quux=*** Sensitive Data Redacted ***,")
append("qux=${'$'}qux,")
append("waldo=*** Sensitive Data Redacted ***")
append(")")
}
""".formatForTest()
Expand Down

0 comments on commit 2652698

Please sign in to comment.