Skip to content

Commit 179c1c0

Browse files
committed
Relocate AuthTokenGenerator to aws-signing-common
1 parent d06ee0a commit 179c1c0

File tree

1 file changed

+63
-0
lines changed
  • runtime/auth/aws-signing-common/common/src/aws/smithy/kotlin/runtime/auth/awssigning

1 file changed

+63
-0
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
package aws.smithy.kotlin.runtime.auth.awssigning
6+
7+
import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials
8+
import aws.smithy.kotlin.runtime.auth.awscredentials.CredentialsProvider
9+
import aws.smithy.kotlin.runtime.auth.awssigning.AwsSigningConfig.Companion.invoke
10+
import aws.smithy.kotlin.runtime.http.HttpMethod
11+
import aws.smithy.kotlin.runtime.http.request.HttpRequest
12+
import aws.smithy.kotlin.runtime.net.url.Url
13+
import aws.smithy.kotlin.runtime.time.Clock
14+
import aws.smithy.kotlin.runtime.util.ExpiringValue
15+
import kotlin.time.Duration
16+
import kotlin.time.Duration.Companion.minutes
17+
import kotlin.time.Duration.Companion.seconds
18+
19+
// The default expiration value to use for [Credentials] when none is provided.
20+
private val DEFAULT_CREDENTIALS_EXPIRATION = 10.minutes
21+
22+
/**
23+
* Generates an authentication token, which is a SigV4-signed URL with the HTTP scheme removed.
24+
* @param service The name of the service the token is being generated for
25+
* @param credentialsProvider The [CredentialsProvider] which will provide credentials to use when generating the auth token
26+
* @param credentialsRefreshBuffer The amount of time before the resolved [Credentials] expire in which they are considered expired, defaults to 10 seconds.
27+
* @param signer The [AwsSigner] implementation to use when creating the authentication token
28+
* @param clock The [Clock] implementation to use
29+
*/
30+
public class AuthTokenGenerator(
31+
public val service: String,
32+
public val credentialsProvider: CredentialsProvider,
33+
public val credentialsRefreshBuffer: Duration = 10.seconds,
34+
public val signer: AwsSigner,
35+
public val clock: Clock = Clock.System,
36+
) {
37+
private lateinit var credentials: ExpiringValue<Credentials>
38+
39+
private fun Url.trimScheme(): String = toString().removePrefix(scheme.protocolName).removePrefix("://")
40+
41+
public suspend fun generateAuthToken(endpoint: Url, region: String, expiration: Duration): String {
42+
if (!::credentials.isInitialized || (credentials.expiresAt - clock.now()).absoluteValue <= credentialsRefreshBuffer) {
43+
val resolved = credentialsProvider.resolve()
44+
credentials = ExpiringValue(resolved, resolved.expiration ?: (clock.now() + DEFAULT_CREDENTIALS_EXPIRATION))
45+
}
46+
47+
val req = HttpRequest(HttpMethod.GET, endpoint)
48+
49+
val creds = credentials.value
50+
val serv = service
51+
52+
val config = AwsSigningConfig {
53+
credentials = creds
54+
this.region = region
55+
service = serv
56+
signingDate = clock.now()
57+
expiresAfter = expiration
58+
signatureType = AwsSignatureType.HTTP_REQUEST_VIA_QUERY_PARAMS
59+
}
60+
61+
return signer.sign(req, config).output.url.trimScheme()
62+
}
63+
}

0 commit comments

Comments
 (0)