Skip to content

Commit f9c466c

Browse files
committed
Properly redact oauth tokens with toString()
1 parent e857be9 commit f9c466c

File tree

3 files changed

+85
-1
lines changed

3 files changed

+85
-1
lines changed

plugins/core/core/src/software/aws/toolkits/core/utils/SensitiveField.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package software.aws.toolkits.core.utils
55

66
import kotlin.reflect.full.hasAnnotation
77
import kotlin.reflect.full.memberProperties
8+
import kotlin.reflect.full.superclasses
89

910
@Target(AnnotationTarget.PROPERTY)
1011
annotation class SensitiveField
@@ -23,7 +24,13 @@ fun redactedString(o: Any): String {
2324
properties.forEachIndexed { i, prop ->
2425
append(prop.name)
2526
append("=")
26-
if (prop.hasAnnotation<SensitiveField>()) {
27+
28+
// @Inherited does not work in Kotlin
29+
// https://youtrack.jetbrains.com/issue/KT-22265/Support-for-inherited-annotations
30+
if (
31+
prop.hasAnnotation<SensitiveField>() ||
32+
clazz.superclasses.flatMap { superClazz -> superClazz.members.filter { it.name == prop.name }}.any { it.hasAnnotation<SensitiveField>() }
33+
) {
2734
if (prop.getter.call(o) == null) {
2835
append("null")
2936
} else {
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package software.aws.toolkits.jetbrains.core.credentials.sso
5+
6+
import org.assertj.core.api.Assertions.assertThat
7+
import org.junit.jupiter.api.Test
8+
import java.time.Instant
9+
10+
class AccessTokenTest {
11+
@Test
12+
fun `DeviceAuthorizationGrantToken#toString has redacted values`() {
13+
val sut = DeviceAuthorizationGrantToken(
14+
startUrl = "clearText",
15+
region = "clearText",
16+
accessToken = "hiddenText",
17+
refreshToken = "hiddenText",
18+
expiresAt = Instant.EPOCH,
19+
createdAt = Instant.EPOCH,
20+
)
21+
22+
assertThat(sut.toString()).doesNotContain("hiddenText")
23+
}
24+
25+
@Test
26+
fun `PKCEAuthorizationGrantToken#toString has redacted values`() {
27+
val sut = PKCEAuthorizationGrantToken(
28+
issuerUrl = "clearText",
29+
region = "clearText",
30+
accessToken = "hiddenText",
31+
refreshToken = "hiddenText",
32+
expiresAt = Instant.EPOCH,
33+
createdAt = Instant.EPOCH,
34+
)
35+
36+
assertThat(sut.toString()).doesNotContain("hiddenText")
37+
}
38+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package software.aws.toolkits.jetbrains.core.credentials.sso
5+
6+
import org.assertj.core.api.Assertions.assertThat
7+
import org.junit.jupiter.api.Test
8+
import java.time.Instant
9+
10+
class ClientRegistrationTest {
11+
@Test
12+
fun `DeviceAuthorizationClientRegistration#toString has redacted values`() {
13+
val sut = DeviceAuthorizationClientRegistration(
14+
clientId = "clearText",
15+
clientSecret = "hiddenText",
16+
expiresAt = Instant.EPOCH,
17+
scopes = listOf("clearText"),
18+
)
19+
20+
assertThat(sut.toString()).doesNotContain("hiddenText")
21+
}
22+
23+
@Test
24+
fun `PKCEClientRegistration#toString has redacted values`() {
25+
val sut = PKCEClientRegistration(
26+
clientId = "clearText",
27+
clientSecret = "hiddenText",
28+
expiresAt = Instant.EPOCH,
29+
scopes = listOf("clearText"),
30+
issuerUrl = "clearText",
31+
region = "clearText",
32+
clientType = "clearText",
33+
grantTypes = listOf("clearText"),
34+
redirectUris = listOf("clearText")
35+
)
36+
37+
assertThat(sut.toString()).doesNotContain("hiddenText")
38+
}
39+
}

0 commit comments

Comments
 (0)