summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMS <ms@taler.net>2023-09-29 12:19:05 +0200
committerMS <ms@taler.net>2023-09-29 12:19:05 +0200
commit0a1c5a7465418dff7d63dbcc2dccd58ca0cea6ab (patch)
treed9b1de46eabff21b53b781e45120f65041d8d12a
parenta917619a31aa0abbedfa36def0def2b38bae3d43 (diff)
downloadlibeufin-0a1c5a7465418dff7d63dbcc2dccd58ca0cea6ab.tar.gz
libeufin-0a1c5a7465418dff7d63dbcc2dccd58ca0cea6ab.tar.bz2
libeufin-0a1c5a7465418dff7d63dbcc2dccd58ca0cea6ab.zip
Testing token timing.
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/CorebankApiHandlers.kt2
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/Main.kt7
-rw-r--r--bank/src/test/kotlin/LibeuFinApiTest.kt42
-rw-r--r--util/src/main/kotlin/time.kt5
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
}