Skip to content
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

fix: correctly redact sensitive data in lists/maps #1122

Merged
merged 1 commit into from
Jul 15, 2024
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
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
Loading