diff options
author | MS <ms@taler.net> | 2023-09-29 12:19:05 +0200 |
---|---|---|
committer | MS <ms@taler.net> | 2023-09-29 12:19:05 +0200 |
commit | 0a1c5a7465418dff7d63dbcc2dccd58ca0cea6ab (patch) | |
tree | d9b1de46eabff21b53b781e45120f65041d8d12a | |
parent | a917619a31aa0abbedfa36def0def2b38bae3d43 (diff) | |
download | libeufin-0a1c5a7465418dff7d63dbcc2dccd58ca0cea6ab.tar.gz libeufin-0a1c5a7465418dff7d63dbcc2dccd58ca0cea6ab.tar.bz2 libeufin-0a1c5a7465418dff7d63dbcc2dccd58ca0cea6ab.zip |
Testing token timing.
-rw-r--r-- | bank/src/main/kotlin/tech/libeufin/bank/CorebankApiHandlers.kt | 2 | ||||
-rw-r--r-- | bank/src/main/kotlin/tech/libeufin/bank/Main.kt | 7 | ||||
-rw-r--r-- | bank/src/test/kotlin/LibeuFinApiTest.kt | 42 | ||||
-rw-r--r-- | util/src/main/kotlin/time.kt | 5 |
4 files changed, 53 insertions, 3 deletions
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/CorebankApiHandlers.kt b/bank/src/main/kotlin/tech/libeufin/bank/CorebankApiHandlers.kt index 07056ed5..fc3ca211 100644 --- a/bank/src/main/kotlin/tech/libeufin/bank/CorebankApiHandlers.kt +++ b/bank/src/main/kotlin/tech/libeufin/bank/CorebankApiHandlers.kt @@ -58,9 +58,11 @@ fun Routing.accountsMgmtHandlers(db: Database, ctx: BankApplicationContext) { val creationTime = Instant.now() val expirationTimestamp = if (tokenDuration == ChronoUnit.FOREVER.duration) { + logger.debug("Creating 'forever' token.") Instant.MAX } else { try { + logger.debug("Creating token with days duration: ${tokenDuration.toDays()}") creationTime.plus(tokenDuration) } catch (e: Exception) { logger.error("Could not add token duration to current time: ${e.message}") diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Main.kt b/bank/src/main/kotlin/tech/libeufin/bank/Main.kt index 307b29bd..f34212b4 100644 --- a/bank/src/main/kotlin/tech/libeufin/bank/Main.kt +++ b/bank/src/main/kotlin/tech/libeufin/bank/Main.kt @@ -153,6 +153,9 @@ object TalerProtocolTimestampSerializer : KSerializer<TalerProtocolTimestamp> { } val ts: Long = maybeTs.longOrNull ?: throw badRequest("Could not convert t_s '${maybeTs.content}' to a number") + // Not allowing negative values, despite java.time allowance. + if (ts < 0) + throw badRequest("Negative timestamp not allowed.") val instant = try { Instant.ofEpochSecond(ts) } catch (e: Exception) { @@ -217,8 +220,10 @@ object RelativeTimeSerializer : KSerializer<RelativeTime> { } val dUs: Long = maybeDUs.longOrNull ?: throw badRequest("Could not convert d_us: '${maybeDUs.content}' to a number") + if (dUs < 0) + throw badRequest("Negative duration specified.") val duration = try { - Duration.ofNanos(dUs * 1000L) + Duration.of(dUs, ChronoUnit.MICROS) } catch (e: Exception) { logger.error("Could not get Duration out of d_us content: ${dUs}. ${e.message}") throw badRequest("Could not get Duration out of d_us content: ${dUs}") diff --git a/bank/src/test/kotlin/LibeuFinApiTest.kt b/bank/src/test/kotlin/LibeuFinApiTest.kt index 8683fef8..18020481 100644 --- a/bank/src/test/kotlin/LibeuFinApiTest.kt +++ b/bank/src/test/kotlin/LibeuFinApiTest.kt @@ -157,6 +157,45 @@ class LibeuFinApiTest { } } + // Testing that too big or invalid durations fail the request. + @Test + fun tokenInvalidDurationTest() { + val db = initDb() + val ctx = getTestContext() + assert(db.customerCreate(customerFoo) != null) + testApplication { + application { + corebankWebApp(db, ctx) + } + var r = client.post("/accounts/foo/token") { + expectSuccess = false + contentType(ContentType.Application.Json) + basicAuth("foo", "pw") + setBody("""{ + "duration": {"d_us": "invalid"}, + "scope": "readonly"}""".trimIndent()) + } + assert(r.status == HttpStatusCode.BadRequest) + r = client.post("/accounts/foo/token") { + expectSuccess = false + contentType(ContentType.Application.Json) + basicAuth("foo", "pw") + setBody("""{ + "duration": {"d_us": ${Long.MAX_VALUE}}, + "scope": "readonly"}""".trimIndent()) + } + assert(r.status == HttpStatusCode.BadRequest) + r = client.post("/accounts/foo/token") { + expectSuccess = false + contentType(ContentType.Application.Json) + basicAuth("foo", "pw") + setBody("""{ + "duration": {"d_us": -1}, + "scope": "readonly"}""".trimIndent()) + } + assert(r.status == HttpStatusCode.BadRequest) + } + } // Checking the POST /token handling. @Test fun tokenTest() { @@ -182,7 +221,8 @@ class LibeuFinApiTest { val newTokDb = db.bearerTokenGet(Base32Crockford.decode(newTokObj.access_token)) val lifeTime = Duration.between(newTokDb!!.creationTime, newTokDb.expirationTime) assert(lifeTime == Duration.ofDays(1)) - // foo tries on bar endpoint + + // foo tries to create a token on behalf of bar, expect 403. val r = client.post("/accounts/bar/token") { expectSuccess = false basicAuth("foo", "pw") diff --git a/util/src/main/kotlin/time.kt b/util/src/main/kotlin/time.kt index 6c1b9464..c0b85171 100644 --- a/util/src/main/kotlin/time.kt +++ b/util/src/main/kotlin/time.kt @@ -58,7 +58,10 @@ private fun Instant.toNanos(): Long? { fun Instant.toDbMicros(): Long? { if (this == Instant.MAX) return Long.MAX_VALUE - val nanos = this.toNanos() ?: return null + val nanos = this.toNanos() ?: run { + logger.error("Could not obtain micros to store to database, convenience conversion to nanos overflew.") + return null + } return nanos / 1000L } |