From 2a7fb30ca768fc77967fcbcf5905bcc41e76798c Mon Sep 17 00:00:00 2001 From: Xinsong Cui Date: Tue, 8 Jul 2025 15:00:52 -0400 Subject: [PATCH 1/7] add runtime type --- .../software/amazon/smithy/kotlin/codegen/core/RuntimeTypes.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/RuntimeTypes.kt b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/RuntimeTypes.kt index 53fb49c71..09cd7e351 100644 --- a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/RuntimeTypes.kt +++ b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/RuntimeTypes.kt @@ -374,6 +374,7 @@ object RuntimeTypes { val BearerTokenAuthScheme = symbol("BearerTokenAuthScheme") val BearerTokenProviderConfig = symbol("BearerTokenProviderConfig") val BearerTokenProvider = symbol("BearerTokenProvider") + val BearerToken= symbol("BearerToken") val reprioritizeAuthOptions = symbol("reprioritizeAuthOptions") } From 3311dd911a3aa1267106dabbd58201afbe151a9e Mon Sep 17 00:00:00 2001 From: Xinsong Cui Date: Tue, 8 Jul 2025 15:05:50 -0400 Subject: [PATCH 2/7] lint --- .../software/amazon/smithy/kotlin/codegen/core/RuntimeTypes.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/RuntimeTypes.kt b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/RuntimeTypes.kt index 09cd7e351..17bed1ac9 100644 --- a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/RuntimeTypes.kt +++ b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/RuntimeTypes.kt @@ -374,7 +374,7 @@ object RuntimeTypes { val BearerTokenAuthScheme = symbol("BearerTokenAuthScheme") val BearerTokenProviderConfig = symbol("BearerTokenProviderConfig") val BearerTokenProvider = symbol("BearerTokenProvider") - val BearerToken= symbol("BearerToken") + val BearerToken = symbol("BearerToken") val reprioritizeAuthOptions = symbol("reprioritizeAuthOptions") } From ca6373dba5f216aeb67fdf52c19935ef99390d39 Mon Sep 17 00:00:00 2001 From: Xinsong Cui Date: Wed, 9 Jul 2025 14:00:56 -0400 Subject: [PATCH 3/7] pr feedback, move env bearer token provider to smithy kotlin --- .../kotlin/codegen/core/RuntimeTypes.kt | 1 + .../auth/EnvironmentBearerTokenProvider.kt | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 runtime/auth/http-auth/common/src/aws/smithy/kotlin/runtime/http/auth/EnvironmentBearerTokenProvider.kt diff --git a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/RuntimeTypes.kt b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/RuntimeTypes.kt index 17bed1ac9..1cbf3b407 100644 --- a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/RuntimeTypes.kt +++ b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/RuntimeTypes.kt @@ -375,6 +375,7 @@ object RuntimeTypes { val BearerTokenProviderConfig = symbol("BearerTokenProviderConfig") val BearerTokenProvider = symbol("BearerTokenProvider") val BearerToken = symbol("BearerToken") + val EnvironmentBearerTokenProvider = symbol("EnvironmentBearerTokenProvider") val reprioritizeAuthOptions = symbol("reprioritizeAuthOptions") } diff --git a/runtime/auth/http-auth/common/src/aws/smithy/kotlin/runtime/http/auth/EnvironmentBearerTokenProvider.kt b/runtime/auth/http-auth/common/src/aws/smithy/kotlin/runtime/http/auth/EnvironmentBearerTokenProvider.kt new file mode 100644 index 000000000..7296f4957 --- /dev/null +++ b/runtime/auth/http-auth/common/src/aws/smithy/kotlin/runtime/http/auth/EnvironmentBearerTokenProvider.kt @@ -0,0 +1,30 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package aws.smithy.kotlin.runtime.http.auth + +import aws.smithy.kotlin.runtime.collections.Attributes +import aws.smithy.kotlin.runtime.collections.emptyAttributes +import aws.smithy.kotlin.runtime.time.Instant +import aws.smithy.kotlin.runtime.util.PlatformProvider + +/** + * A [BearerTokenProvider] that extracts the bearer token from the target environment variable. + */ +public class EnvironmentBearerTokenProvider( + private val key: String, + private val platform: PlatformProvider = PlatformProvider.System, +) : BearerTokenProvider { + override suspend fun resolve(attributes: Attributes): BearerToken { + // Check environment variable on each resolve call + val bearerToken = platform.getenv(key) + ?: error("$key environment variable is not set") + + return object : BearerToken { + override val token: String = bearerToken + override val attributes: Attributes = emptyAttributes() + override val expiration: Instant? = null + } + } +} From cf1809152747d5f217dd3407c0030275a69f7944 Mon Sep 17 00:00:00 2001 From: Xinsong Cui Date: Wed, 9 Jul 2025 14:19:09 -0400 Subject: [PATCH 4/7] api --- runtime/auth/http-auth/api/http-auth.api | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/runtime/auth/http-auth/api/http-auth.api b/runtime/auth/http-auth/api/http-auth.api index 709166a39..d47a5a9c7 100644 --- a/runtime/auth/http-auth/api/http-auth.api +++ b/runtime/auth/http-auth/api/http-auth.api @@ -59,6 +59,12 @@ public final class aws/smithy/kotlin/runtime/http/auth/BearerTokenSigner : aws/s public abstract interface class aws/smithy/kotlin/runtime/http/auth/CloseableBearerTokenProvider : aws/smithy/kotlin/runtime/http/auth/BearerTokenProvider, java/io/Closeable { } +public final class aws/smithy/kotlin/runtime/http/auth/EnvironmentBearerTokenProvider : aws/smithy/kotlin/runtime/http/auth/BearerTokenProvider { + public fun (Ljava/lang/String;Laws/smithy/kotlin/runtime/util/PlatformProvider;)V + public synthetic fun (Ljava/lang/String;Laws/smithy/kotlin/runtime/util/PlatformProvider;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun resolve (Laws/smithy/kotlin/runtime/collections/Attributes;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; +} + public final class aws/smithy/kotlin/runtime/http/auth/ReprioritizeAuthOptionsKt { public static final fun reprioritizeAuthOptions (Ljava/util/List;Ljava/util/List;)Ljava/util/List; } From da6d2d7c3927a9e7993375084b685e7df23f38e5 Mon Sep 17 00:00:00 2001 From: Xinsong Cui Date: Wed, 9 Jul 2025 16:29:46 -0400 Subject: [PATCH 5/7] add tests for env bearer token provider --- .../EnvironmentBearerTokenProviderTest.kt | 60 +++++++++++++++++++ .../runtime/util/TestPlatformProvider.kt | 2 +- 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 runtime/auth/http-auth/common/test/aws/smithy/kotlin/runtime/http/auth/EnvironmentBearerTokenProviderTest.kt diff --git a/runtime/auth/http-auth/common/test/aws/smithy/kotlin/runtime/http/auth/EnvironmentBearerTokenProviderTest.kt b/runtime/auth/http-auth/common/test/aws/smithy/kotlin/runtime/http/auth/EnvironmentBearerTokenProviderTest.kt new file mode 100644 index 000000000..500d5cca3 --- /dev/null +++ b/runtime/auth/http-auth/common/test/aws/smithy/kotlin/runtime/http/auth/EnvironmentBearerTokenProviderTest.kt @@ -0,0 +1,60 @@ +package aws.smithy.kotlin.runtime.http.auth + +import aws.smithy.kotlin.runtime.collections.emptyAttributes +import aws.smithy.kotlin.runtime.util.TestPlatformProvider +import kotlinx.coroutines.test.runTest +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFailsWith + +class EnvironmentBearerTokenProviderTest { + class MutableTestPlatformProvider( + private val mutableEnv: MutableMap = mutableMapOf(), + ) : TestPlatformProvider(env = mutableEnv) { + + fun setEnv(key: String, value: String) { + mutableEnv[key] = value + } + + override fun getenv(key: String): String? = mutableEnv[key] + } + + @Test + fun testResolveWithValidToken() = runTest { + val provider = EnvironmentBearerTokenProvider( + "TEST_TOKEN", + MutableTestPlatformProvider(mutableMapOf("TEST_TOKEN" to "test-bearer-token")), + ) + + val token = provider.resolve() + + assertEquals("test-bearer-token", token.token) + } + + @Test + fun testResolveWithMissingToken() = runTest { + val provider = EnvironmentBearerTokenProvider( + "MISSING_TEST_TOKEN", + MutableTestPlatformProvider(mutableMapOf()), + ) + + val exception = assertFailsWith { + provider.resolve(emptyAttributes()) + } + assertEquals("MISSING_TEST_TOKEN environment variable is not set", exception.message) + } + + @Test + fun testResolveChecksEnvironmentOnEachCall() = runTest { + val envVars = mutableMapOf("DYNAMIC_TEST_TOKEN" to "initial-bearer-token") + val testPlatformProvider = MutableTestPlatformProvider(envVars) + val provider = EnvironmentBearerTokenProvider( + "DYNAMIC_TEST_TOKEN", + testPlatformProvider, + ) + + assertEquals("initial-bearer-token", provider.resolve().token) + testPlatformProvider.setEnv("DYNAMIC_TEST_TOKEN", "updated-bearer-token") + assertEquals("updated-bearer-token", provider.resolve().token) + } +} diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/TestPlatformProvider.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/TestPlatformProvider.kt index e284630fa..fe304ab1b 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/TestPlatformProvider.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/TestPlatformProvider.kt @@ -15,7 +15,7 @@ import aws.smithy.kotlin.runtime.InternalApi * @param os Operating system info to emulate */ @InternalApi -public class TestPlatformProvider( +public open class TestPlatformProvider( env: Map = emptyMap(), private val props: Map = emptyMap(), private val fs: Map = emptyMap(), From d21cf5f4113deae80e313414e4204c6971b2e7fe Mon Sep 17 00:00:00 2001 From: Xinsong Cui Date: Wed, 9 Jul 2025 16:37:11 -0400 Subject: [PATCH 6/7] api --- runtime/runtime-core/api/runtime-core.api | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/runtime-core/api/runtime-core.api b/runtime/runtime-core/api/runtime-core.api index fa4c1d2d2..e693470c7 100644 --- a/runtime/runtime-core/api/runtime-core.api +++ b/runtime/runtime-core/api/runtime-core.api @@ -2424,7 +2424,7 @@ public final class aws/smithy/kotlin/runtime/util/SingleFlightGroup { public final fun singleFlight (Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } -public final class aws/smithy/kotlin/runtime/util/TestPlatformProvider : aws/smithy/kotlin/runtime/util/Filesystem, aws/smithy/kotlin/runtime/util/PlatformProvider { +public class aws/smithy/kotlin/runtime/util/TestPlatformProvider : aws/smithy/kotlin/runtime/util/Filesystem, aws/smithy/kotlin/runtime/util/PlatformProvider { public static final field Companion Laws/smithy/kotlin/runtime/util/TestPlatformProvider$Companion; public fun ()V public fun (Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Laws/smithy/kotlin/runtime/util/OperatingSystem;)V From 63e65965835f39def298d0710f1f71e3f6ae9de9 Mon Sep 17 00:00:00 2001 From: Xinsong Cui Date: Fri, 11 Jul 2025 13:42:58 -0400 Subject: [PATCH 7/7] remove unnecessary test --- .../auth/EnvironmentBearerTokenProvider.kt | 1 - .../EnvironmentBearerTokenProviderTest.kt | 29 ++----------------- runtime/runtime-core/api/runtime-core.api | 2 +- .../runtime/util/TestPlatformProvider.kt | 2 +- 4 files changed, 4 insertions(+), 30 deletions(-) diff --git a/runtime/auth/http-auth/common/src/aws/smithy/kotlin/runtime/http/auth/EnvironmentBearerTokenProvider.kt b/runtime/auth/http-auth/common/src/aws/smithy/kotlin/runtime/http/auth/EnvironmentBearerTokenProvider.kt index 7296f4957..ffe37b60b 100644 --- a/runtime/auth/http-auth/common/src/aws/smithy/kotlin/runtime/http/auth/EnvironmentBearerTokenProvider.kt +++ b/runtime/auth/http-auth/common/src/aws/smithy/kotlin/runtime/http/auth/EnvironmentBearerTokenProvider.kt @@ -17,7 +17,6 @@ public class EnvironmentBearerTokenProvider( private val platform: PlatformProvider = PlatformProvider.System, ) : BearerTokenProvider { override suspend fun resolve(attributes: Attributes): BearerToken { - // Check environment variable on each resolve call val bearerToken = platform.getenv(key) ?: error("$key environment variable is not set") diff --git a/runtime/auth/http-auth/common/test/aws/smithy/kotlin/runtime/http/auth/EnvironmentBearerTokenProviderTest.kt b/runtime/auth/http-auth/common/test/aws/smithy/kotlin/runtime/http/auth/EnvironmentBearerTokenProviderTest.kt index 500d5cca3..e98e8083d 100644 --- a/runtime/auth/http-auth/common/test/aws/smithy/kotlin/runtime/http/auth/EnvironmentBearerTokenProviderTest.kt +++ b/runtime/auth/http-auth/common/test/aws/smithy/kotlin/runtime/http/auth/EnvironmentBearerTokenProviderTest.kt @@ -8,22 +8,11 @@ import kotlin.test.assertEquals import kotlin.test.assertFailsWith class EnvironmentBearerTokenProviderTest { - class MutableTestPlatformProvider( - private val mutableEnv: MutableMap = mutableMapOf(), - ) : TestPlatformProvider(env = mutableEnv) { - - fun setEnv(key: String, value: String) { - mutableEnv[key] = value - } - - override fun getenv(key: String): String? = mutableEnv[key] - } - @Test fun testResolveWithValidToken() = runTest { val provider = EnvironmentBearerTokenProvider( "TEST_TOKEN", - MutableTestPlatformProvider(mutableMapOf("TEST_TOKEN" to "test-bearer-token")), + TestPlatformProvider(mutableMapOf("TEST_TOKEN" to "test-bearer-token")), ) val token = provider.resolve() @@ -35,7 +24,7 @@ class EnvironmentBearerTokenProviderTest { fun testResolveWithMissingToken() = runTest { val provider = EnvironmentBearerTokenProvider( "MISSING_TEST_TOKEN", - MutableTestPlatformProvider(mutableMapOf()), + TestPlatformProvider(mutableMapOf()), ) val exception = assertFailsWith { @@ -43,18 +32,4 @@ class EnvironmentBearerTokenProviderTest { } assertEquals("MISSING_TEST_TOKEN environment variable is not set", exception.message) } - - @Test - fun testResolveChecksEnvironmentOnEachCall() = runTest { - val envVars = mutableMapOf("DYNAMIC_TEST_TOKEN" to "initial-bearer-token") - val testPlatformProvider = MutableTestPlatformProvider(envVars) - val provider = EnvironmentBearerTokenProvider( - "DYNAMIC_TEST_TOKEN", - testPlatformProvider, - ) - - assertEquals("initial-bearer-token", provider.resolve().token) - testPlatformProvider.setEnv("DYNAMIC_TEST_TOKEN", "updated-bearer-token") - assertEquals("updated-bearer-token", provider.resolve().token) - } } diff --git a/runtime/runtime-core/api/runtime-core.api b/runtime/runtime-core/api/runtime-core.api index e693470c7..fa4c1d2d2 100644 --- a/runtime/runtime-core/api/runtime-core.api +++ b/runtime/runtime-core/api/runtime-core.api @@ -2424,7 +2424,7 @@ public final class aws/smithy/kotlin/runtime/util/SingleFlightGroup { public final fun singleFlight (Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } -public class aws/smithy/kotlin/runtime/util/TestPlatformProvider : aws/smithy/kotlin/runtime/util/Filesystem, aws/smithy/kotlin/runtime/util/PlatformProvider { +public final class aws/smithy/kotlin/runtime/util/TestPlatformProvider : aws/smithy/kotlin/runtime/util/Filesystem, aws/smithy/kotlin/runtime/util/PlatformProvider { public static final field Companion Laws/smithy/kotlin/runtime/util/TestPlatformProvider$Companion; public fun ()V public fun (Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Laws/smithy/kotlin/runtime/util/OperatingSystem;)V diff --git a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/TestPlatformProvider.kt b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/TestPlatformProvider.kt index fe304ab1b..e284630fa 100644 --- a/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/TestPlatformProvider.kt +++ b/runtime/runtime-core/common/src/aws/smithy/kotlin/runtime/util/TestPlatformProvider.kt @@ -15,7 +15,7 @@ import aws.smithy.kotlin.runtime.InternalApi * @param os Operating system info to emulate */ @InternalApi -public open class TestPlatformProvider( +public class TestPlatformProvider( env: Map = emptyMap(), private val props: Map = emptyMap(), private val fs: Map = emptyMap(),