Skip to content

Commit

Permalink
#691 OAuth2TokenProvider should allow dynamic systemTime (#693)
Browse files Browse the repository at this point in the history
* #691 `OAuth2TokenProvider` should allow dynamic `systemTime`

* #691 implement test for timeProvider
  • Loading branch information
xuanswe authored Jun 17, 2024
1 parent 69fc64e commit a89015c
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,23 @@ import java.time.Instant
import java.util.Date
import java.util.UUID

typealias TimeProvider = () -> Instant?

class OAuth2TokenProvider
@JvmOverloads
constructor(
private val keyProvider: KeyProvider = KeyProvider(),
val systemTime: Instant? = null,
private val timeProvider: TimeProvider,
) {
val systemTime
get() = timeProvider()

@JvmOverloads
constructor(
keyProvider: KeyProvider = KeyProvider(),
systemTime: Instant? = null,
) : this(keyProvider, { systemTime })

@JvmOverloads
fun publicJwkSet(issuerId: String = "default"): JWKSet {
return JWKSet(keyProvider.signingKey(issuerId)).toPublicJWKSet()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ import okhttp3.HttpUrl.Companion.toHttpUrl
import org.junit.jupiter.api.Test
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.ValueSource
import java.time.Clock
import java.time.Instant
import java.time.ZoneId
import java.time.temporal.ChronoUnit
import java.util.Date

Expand Down Expand Up @@ -99,8 +101,8 @@ internal class OAuth2TokenProviderRSATest {

@Test
fun `token should have issuedAt set to systemTime if set, otherwise use now()`() {
val yesterDay = Instant.now().minus(1, ChronoUnit.DAYS)
val tokenProvider = OAuth2TokenProvider(systemTime = yesterDay)
val yesterday = Instant.now().minus(1, ChronoUnit.DAYS)
val tokenProvider = OAuth2TokenProvider(systemTime = yesterday)

tokenProvider.exchangeAccessToken(
tokenRequest =
Expand All @@ -118,6 +120,70 @@ internal class OAuth2TokenProviderRSATest {
}
}

@Test
fun `token should have issuedAt set dynamically according to timeProvider`() {
val clock =
object : Clock() {
private var clock = systemDefaultZone()

override fun instant() = clock.instant()

override fun withZone(zone: ZoneId) = clock.withZone(zone)

override fun getZone() = clock.zone

fun fixed(instant: Instant) {
clock = fixed(instant, zone)
}
}

val tokenProvider = OAuth2TokenProvider { clock.instant() }

val instant1 = Instant.parse("2000-12-03T10:15:30.00Z")
val instant2 = Instant.parse("2020-01-21T00:00:00.00Z")
instant1 shouldNotBe instant2

run {
clock.fixed(instant1)
tokenProvider.systemTime shouldBe instant1

tokenProvider.exchangeAccessToken(
tokenRequest =
nimbusTokenRequest(
"id",
"grant_type" to GrantType.CLIENT_CREDENTIALS.value,
"scope" to "scope1",
),
issuerUrl = "http://default_if_not_overridden".toHttpUrl(),
claimsSet = tokenProvider.jwt(mapOf()).jwtClaimsSet,
oAuth2TokenCallback = DefaultOAuth2TokenCallback(),
)
}.asClue {
it.jwtClaimsSet.issueTime shouldBe Date.from(instant1)
println(it.serialize())
}

run {
clock.fixed(instant2)
tokenProvider.systemTime shouldBe instant2

tokenProvider.exchangeAccessToken(
tokenRequest =
nimbusTokenRequest(
"id",
"grant_type" to GrantType.CLIENT_CREDENTIALS.value,
"scope" to "scope1",
),
issuerUrl = "http://default_if_not_overridden".toHttpUrl(),
claimsSet = tokenProvider.jwt(mapOf()).jwtClaimsSet,
oAuth2TokenCallback = DefaultOAuth2TokenCallback(),
)
}.asClue {
it.jwtClaimsSet.issueTime shouldBe Date.from(instant2)
println(it.serialize())
}
}

private fun idToken(issuerUrl: String): SignedJWT =
tokenProvider.idToken(
tokenRequest =
Expand Down

0 comments on commit a89015c

Please sign in to comment.