
commonTest.aws.sdk.kotlin.runtime.auth.credentials.StsWebIdentityCredentialsProviderTest.kt Maven / Gradle / Ivy
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package aws.sdk.kotlin.runtime.auth.credentials
import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials
import aws.smithy.kotlin.runtime.auth.awscredentials.CredentialsProviderException
import aws.smithy.kotlin.runtime.http.Headers
import aws.smithy.kotlin.runtime.http.HttpStatusCode
import aws.smithy.kotlin.runtime.http.content.ByteArrayContent
import aws.smithy.kotlin.runtime.http.response.HttpResponse
import aws.smithy.kotlin.runtime.httptest.TestConnection
import aws.smithy.kotlin.runtime.httptest.buildTestConnection
import aws.smithy.kotlin.runtime.time.Instant
import aws.smithy.kotlin.runtime.time.TimestampFormat
import aws.smithy.kotlin.runtime.util.TestPlatformProvider
import io.kotest.matchers.string.shouldContain
import kotlinx.coroutines.test.runTest
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.time.Duration.Companion.minutes
import kotlin.time.ExperimentalTime
@OptIn(ExperimentalTime::class)
class StsWebIdentityCredentialsProviderTest {
private val epoch = Instant.fromIso8601("2020-10-16T03:56:00Z")
private val expectedCredentialsBase = Credentials(
"AKIDTest",
"test-secret",
"test-token",
epoch + 15.minutes,
"WebIdentityToken",
)
private val testArn = "arn:aws:iam:1234567/test-role"
// see https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html#API_AssumeRoleWithWebIdentity_ResponseElements
private fun stsResponse(
roleArn: String,
expiration: Instant? = null,
): HttpResponse {
val roleId = roleArn.split("/").last()
val expiry = expiration ?: expectedCredentialsBase.expiration!!
val body = """
amzn1.account.AF6RHO7KZU5XRVQJGXK6HB56KR2A
[email protected]
$roleArn
ARO123EXAMPLE123:$roleId
AKIDTest
test-secret
test-token
${expiry.format(TimestampFormat.ISO_8601)}
SourceIdentityValue
www.amazon.com
ad4156e9-bce1-11e2-82e6-6b6efEXAMPLE
""".trimIndent()
return HttpResponse(HttpStatusCode.OK, Headers.Empty, ByteArrayContent(body.encodeToByteArray()))
}
@Test
fun testSuccess() = runTest {
val testEngine = buildTestConnection {
expect(stsResponse(testArn))
}
val testPlatform = TestPlatformProvider(
fs = mapOf("token-path" to "jwt-token"),
)
val provider = StsWebIdentityCredentialsProvider(
roleArn = testArn,
webIdentityTokenFilePath = "token-path",
region = "us-east-2",
httpClient = testEngine,
platformProvider = testPlatform,
)
val actual = provider.resolve()
assertEquals(expectedCredentialsBase, actual)
}
@Test
fun testServiceFailure() = runTest {
val errorResponseBody = """
Sender
AccessDeniedException
You do not have sufficient access to perform this action
foo-id
"""
val testEngine = buildTestConnection {
expect(HttpResponse(HttpStatusCode.BadRequest, Headers.Empty, ByteArrayContent(errorResponseBody.encodeToByteArray())))
}
val testPlatform = TestPlatformProvider(
fs = mapOf("token-path" to "jwt-token"),
)
val provider = StsWebIdentityCredentialsProvider(
roleArn = testArn,
webIdentityTokenFilePath = "token-path",
region = "us-east-2",
httpClient = testEngine,
platformProvider = testPlatform,
)
assertFailsWith {
provider.resolve()
}.message.shouldContain("STS failed to assume role from web identity")
}
@Test
fun testJwtTokenMissing() = runTest {
val testEngine = TestConnection()
val testPlatform = TestPlatformProvider()
val provider = StsWebIdentityCredentialsProvider(
roleArn = testArn,
webIdentityTokenFilePath = "token-path",
region = "us-east-2",
httpClient = testEngine,
platformProvider = testPlatform,
)
assertFailsWith {
provider.resolve()
}.message.shouldContain("failed to read webIdentityToken from token-path")
}
@Test
fun testFromEnvironment() {
val tp1 = TestPlatformProvider(
env = mapOf(
"AWS_ROLE_ARN" to "my-role",
"AWS_WEB_IDENTITY_TOKEN_FILE" to "token-file-path",
"AWS_REGION" to "us-east-2",
),
)
StsWebIdentityCredentialsProvider.fromEnvironment(platformProvider = tp1)
// missing AWS_ROLE_ARN
assertFailsWith {
val tp2 = TestPlatformProvider(
env = mapOf(
"AWS_WEB_IDENTITY_TOKEN_FILE" to "token-file-path",
"AWS_REGION" to "us-east-2",
),
)
StsWebIdentityCredentialsProvider.fromEnvironment(platformProvider = tp2)
}.message.shouldContain("Required field `roleArn` could not be automatically inferred for StsWebIdentityCredentialsProvider. Either explicitly pass a value, set the environment variable `AWS_ROLE_ARN`, or set the JVM system property `aws.roleArn`")
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy