summaryrefslogtreecommitdiff
path: root/bank
diff options
context:
space:
mode:
authorAntoine A <>2024-02-13 20:35:04 +0100
committerAntoine A <>2024-02-13 20:39:29 +0100
commit3d1dfce83bf74917886a5f3cc55aa7f97b74aac4 (patch)
tree5b6f2863451e3dd62fb5267a33c0753fa4770729 /bank
parent3046601e239d774716527d4a0a34f585ac5ade79 (diff)
downloadlibeufin-3d1dfce83bf74917886a5f3cc55aa7f97b74aac4.tar.gz
libeufin-3d1dfce83bf74917886a5f3cc55aa7f97b74aac4.tar.bz2
libeufin-3d1dfce83bf74917886a5f3cc55aa7f97b74aac4.zip
Code cleanup
Diffstat (limited to 'bank')
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/BankIntegrationApi.kt8
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/Config.kt12
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/Constants.kt8
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/ConversionApi.kt13
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/CoreBankApi.kt28
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/Error.kt10
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/Main.kt43
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/Metadata.kt2
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/Params.kt21
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/RevenueApi.kt11
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/TalerCommon.kt43
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/TalerMessage.kt45
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/Tan.kt26
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/WireGatewayApi.kt19
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/auth/auth.kt20
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/db/AccountDAO.kt7
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/db/CashoutDAO.kt6
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/db/ConversionDAO.kt15
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/db/Database.kt24
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/db/ExchangeDAO.kt10
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/db/NotificationWatcher.kt16
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/db/TanDAO.kt10
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/db/TokenDAO.kt8
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/db/TransactionDAO.kt7
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/db/WithdrawalDAO.kt16
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/helpers.kt30
-rw-r--r--bank/src/test/kotlin/AmountTest.kt14
-rw-r--r--bank/src/test/kotlin/BankIntegrationApiTest.kt21
-rw-r--r--bank/src/test/kotlin/ConversionApiTest.kt14
-rw-r--r--bank/src/test/kotlin/CoreBankApiTest.kt19
-rw-r--r--bank/src/test/kotlin/DatabaseTest.kt18
-rw-r--r--bank/src/test/kotlin/JsonTest.kt12
-rw-r--r--bank/src/test/kotlin/PaytoTest.kt17
-rw-r--r--bank/src/test/kotlin/RevenueApiTest.kt9
-rw-r--r--bank/src/test/kotlin/SecurityTest.kt17
-rw-r--r--bank/src/test/kotlin/StatsTest.kt22
-rw-r--r--bank/src/test/kotlin/WireGatewayApiTest.kt18
-rw-r--r--bank/src/test/kotlin/helpers.kt43
-rw-r--r--bank/src/test/kotlin/routines.kt23
39 files changed, 345 insertions, 360 deletions
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/BankIntegrationApi.kt b/bank/src/main/kotlin/tech/libeufin/bank/BankIntegrationApi.kt
index f5477896..17d2a917 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/BankIntegrationApi.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/BankIntegrationApi.kt
@@ -21,15 +21,15 @@
* that are typically requested by wallets. */
package tech.libeufin.bank
+import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
-import io.ktor.http.*
+import tech.libeufin.bank.db.AbortResult
+import tech.libeufin.bank.db.Database
+import tech.libeufin.bank.db.WithdrawalDAO.WithdrawalSelectionResult
import tech.libeufin.common.TalerErrorCode
-import tech.libeufin.bank.db.*
-import tech.libeufin.bank.db.WithdrawalDAO.*
-import java.lang.AssertionError
fun Routing.bankIntegrationApi(db: Database, ctx: BankConfig) {
get("/taler-integration/config") {
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Config.kt b/bank/src/main/kotlin/tech/libeufin/bank/Config.kt
index 2c15f43b..42df06b4 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/Config.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/Config.kt
@@ -18,14 +18,12 @@
*/
package tech.libeufin.bank
-import tech.libeufin.common.*
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
-import tech.libeufin.common.DatabaseConfig
-import java.nio.file.*
-import kotlin.io.path.*
import org.slf4j.Logger
import org.slf4j.LoggerFactory
+import tech.libeufin.common.*
+import java.nio.file.Path
private val logger: Logger = LoggerFactory.getLogger("libeufin-bank")
@@ -89,11 +87,11 @@ fun TalerConfig.loadServerConfig(): ServerConfig {
fun TalerConfig.loadBankConfig(): BankConfig {
val regionalCurrency = requireString("libeufin-bank", "currency")
- var fiatCurrency: String? = null;
+ var fiatCurrency: String? = null
var fiatCurrencySpec: CurrencySpecification? = null
- val allowConversion = lookupBoolean("libeufin-bank", "allow_conversion") ?: false;
+ val allowConversion = lookupBoolean("libeufin-bank", "allow_conversion") ?: false
if (allowConversion) {
- fiatCurrency = requireString("libeufin-bank", "fiat_currency");
+ fiatCurrency = requireString("libeufin-bank", "fiat_currency")
fiatCurrencySpec = currencySpecificationFor(fiatCurrency)
}
val tanChannels = buildMap {
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Constants.kt b/bank/src/main/kotlin/tech/libeufin/bank/Constants.kt
index 1a746488..8bb59bc2 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/Constants.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/Constants.kt
@@ -18,23 +18,23 @@
*/
package tech.libeufin.bank
-import tech.libeufin.common.*
+import tech.libeufin.common.ConfigSource
import java.time.Duration
// Config
val BANK_CONFIG_SOURCE = ConfigSource("libeufin", "libeufin-bank", "libeufin-bank")
// TAN
-const val TAN_RETRY_COUNTER: Int = 3;
+const val TAN_RETRY_COUNTER: Int = 3
val TAN_VALIDITY_PERIOD: Duration = Duration.ofHours(1)
val TAN_RETRANSMISSION_PERIOD: Duration = Duration.ofMinutes(1)
// Token
-val TOKEN_DEFAULT_DURATION: java.time.Duration = Duration.ofDays(1L)
+val TOKEN_DEFAULT_DURATION: Duration = Duration.ofDays(1L)
// Account
val RESERVED_ACCOUNTS = setOf("admin", "bank")
-const val IBAN_ALLOCATION_RETRY_COUNTER: Int = 5;
+const val IBAN_ALLOCATION_RETRY_COUNTER: Int = 5
// Security
const val MAX_BODY_LENGTH: Long = 4 * 1024 // 4kB
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/ConversionApi.kt b/bank/src/main/kotlin/tech/libeufin/bank/ConversionApi.kt
index 6707eff0..168b2034 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/ConversionApi.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/ConversionApi.kt
@@ -23,11 +23,12 @@ import io.ktor.server.application.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
-import java.util.*
-import tech.libeufin.common.*
-import tech.libeufin.bank.auth.*
-import tech.libeufin.bank.db.ConversionDAO.*
-import tech.libeufin.bank.db.*
+import tech.libeufin.bank.auth.authAdmin
+import tech.libeufin.bank.db.ConversionDAO
+import tech.libeufin.bank.db.ConversionDAO.ConversionResult
+import tech.libeufin.bank.db.Database
+import tech.libeufin.common.TalerAmount
+import tech.libeufin.common.TalerErrorCode
fun Routing.conversionApi(db: Database, ctx: BankConfig) = conditional(ctx.allowConversion) {
get("/conversion-info/config") {
@@ -108,7 +109,7 @@ fun Routing.conversionApi(db: Database, ctx: BankConfig) = conditional(ctx.allow
for (fiatAmount in sequenceOf(req.cashout_fee, req.cashout_tiny_amount, req.cashin_min_amount)) {
ctx.checkFiatCurrency(fiatAmount)
}
- db.conversion.updateConfig(req);
+ db.conversion.updateConfig(req)
call.respond(HttpStatusCode.NoContent)
}
}
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/CoreBankApi.kt b/bank/src/main/kotlin/tech/libeufin/bank/CoreBankApi.kt
index 6dab5571..5d7646ce 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/CoreBankApi.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/CoreBankApi.kt
@@ -23,27 +23,27 @@ import io.ktor.server.application.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
-import java.time.Duration
-import java.time.Instant
-import java.time.temporal.ChronoUnit
-import java.util.*
-import kotlin.random.Random
-import kotlinx.serialization.json.Json
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.future.await
import kotlinx.coroutines.withContext
import org.slf4j.Logger
import org.slf4j.LoggerFactory
-import tech.libeufin.bank.*
import tech.libeufin.bank.auth.*
-import tech.libeufin.bank.db.*
-import tech.libeufin.bank.db.TanDAO.*
+import tech.libeufin.bank.db.AbortResult
import tech.libeufin.bank.db.AccountDAO.*
-import tech.libeufin.bank.db.CashoutDAO.*
-import tech.libeufin.bank.db.ExchangeDAO.*
-import tech.libeufin.bank.db.TransactionDAO.*
-import tech.libeufin.bank.db.WithdrawalDAO.*
+import tech.libeufin.bank.db.CashoutDAO.CashoutCreationResult
+import tech.libeufin.bank.db.Database
+import tech.libeufin.bank.db.TanDAO.TanSendResult
+import tech.libeufin.bank.db.TanDAO.TanSolveResult
+import tech.libeufin.bank.db.TransactionDAO.BankTransactionResult
+import tech.libeufin.bank.db.WithdrawalDAO.WithdrawalConfirmationResult
+import tech.libeufin.bank.db.WithdrawalDAO.WithdrawalCreationResult
import tech.libeufin.common.*
+import java.time.Duration
+import java.time.Instant
+import java.time.temporal.ChronoUnit
+import java.util.*
+import kotlin.random.Random
private val logger: Logger = LoggerFactory.getLogger("libeufin-bank-api")
@@ -293,7 +293,7 @@ private fun Routing.coreBankAccountsApi(db: Database, ctx: BankConfig) {
authAdmin(db, TokenScope.readwrite, !ctx.allowRegistration) {
post("/accounts") {
val req = call.receive<RegisterAccountRequest>()
- val (result, internalPayto) = createAccount(db, ctx, req, isAdmin);
+ val (result, internalPayto) = createAccount(db, ctx, req, isAdmin)
when (result) {
AccountCreationResult.BonusBalanceInsufficient -> throw conflict(
"Insufficient admin funds to grant bonus",
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Error.kt b/bank/src/main/kotlin/tech/libeufin/bank/Error.kt
index 7fd4c3b5..f6c83224 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/Error.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/Error.kt
@@ -19,11 +19,13 @@
package tech.libeufin.bank
import io.ktor.http.*
+import io.ktor.server.application.*
import io.ktor.server.response.*
-import io.ktor.server.application.ApplicationCall
-import io.ktor.util.AttributeKey
+import io.ktor.util.*
import kotlinx.serialization.Serializable
-import tech.libeufin.common.*
+import tech.libeufin.common.TalerAmount
+import tech.libeufin.common.TalerErrorCode
+
/**
* Convenience type to throw errors along the bank activity
* and that is meant to be caught by Ktor and responded to the
@@ -50,7 +52,7 @@ data class TalerError(
val detail: String? = null
)
-private val LOG_MSG = AttributeKey<String>("log_msg");
+private val LOG_MSG = AttributeKey<String>("log_msg")
fun ApplicationCall.logMsg(): String? = attributes.getOrNull(LOG_MSG)
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Main.kt b/bank/src/main/kotlin/tech/libeufin/bank/Main.kt
index f0d8ac89..e6245238 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/Main.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/Main.kt
@@ -21,41 +21,46 @@ package tech.libeufin.bank
import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.core.subcommands
-import com.github.ajalt.clikt.parameters.types.*
-import com.github.ajalt.clikt.parameters.arguments.*
+import com.github.ajalt.clikt.parameters.arguments.argument
+import com.github.ajalt.clikt.parameters.arguments.convert
+import com.github.ajalt.clikt.parameters.arguments.optional
+import com.github.ajalt.clikt.parameters.groups.OptionGroup
+import com.github.ajalt.clikt.parameters.groups.cooccurring
+import com.github.ajalt.clikt.parameters.groups.provideDelegate
import com.github.ajalt.clikt.parameters.options.*
-import com.github.ajalt.clikt.parameters.groups.*
+import com.github.ajalt.clikt.parameters.types.boolean
import io.ktor.http.*
-import io.ktor.server.application.*
-import io.ktor.server.http.content.*
import io.ktor.serialization.kotlinx.json.*
+import io.ktor.server.application.*
import io.ktor.server.engine.*
+import io.ktor.server.http.content.*
import io.ktor.server.netty.*
import io.ktor.server.plugins.*
import io.ktor.server.plugins.callloging.*
import io.ktor.server.plugins.contentnegotiation.*
import io.ktor.server.plugins.cors.routing.*
-import io.ktor.server.plugins.statuspages.*
import io.ktor.server.plugins.forwardedheaders.*
+import io.ktor.server.plugins.statuspages.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.ktor.utils.io.*
-import java.time.Duration
-import java.util.zip.DataFormatException
-import java.util.zip.Inflater
-import java.sql.SQLException
-import kotlinx.coroutines.*
+import kotlinx.coroutines.runBlocking
import kotlinx.serialization.ExperimentalSerializationApi
-import kotlinx.serialization.json.*
+import kotlinx.serialization.json.Json
+import org.postgresql.util.PSQLState
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.slf4j.event.Level
-import org.postgresql.util.PSQLState
import tech.libeufin.bank.db.AccountDAO.*
-import tech.libeufin.bank.db.*
+import tech.libeufin.bank.db.Database
import tech.libeufin.common.*
-import kotlin.io.path.*
+import java.sql.SQLException
+import java.util.zip.DataFormatException
+import java.util.zip.Inflater
+import kotlin.io.path.Path
+import kotlin.io.path.exists
+import kotlin.io.path.readText
private val logger: Logger = LoggerFactory.getLogger("libeufin-bank")
// Dirty local variable to stop the server in test TODO remove this ugly hack
@@ -69,7 +74,7 @@ val bodyPlugin = createApplicationPlugin("BodyLimitAndDecompression") {
// TODO check content length as an optimisation
transformBody { body ->
val bytes = ByteArray(MAX_BODY_LENGTH.toInt() + 1)
- var read = 0;
+ var read = 0
when (val encoding = call.request.headers[HttpHeaders.ContentEncoding]) {
"deflate" -> {
// Decompress and check decompressed length
@@ -95,7 +100,7 @@ val bodyPlugin = createApplicationPlugin("BodyLimitAndDecompression") {
// Check body length
while (true) {
val new = body.readAvailable(bytes, read, bytes.size - read)
- if (new == -1) break; // Channel is closed
+ if (new == -1) break // Channel is closed
read += new
if (read > MAX_BODY_LENGTH)
throw badRequest("Body is suspiciously big > $MAX_BODY_LENGTH B")
@@ -239,7 +244,7 @@ class BankDbInit : CliktCommand("Initialize the libeufin-bank database", name =
override fun run() = cliCmd(logger, common.log) {
val config = talerConfig(common.config)
val cfg = config.loadDbConfig()
- val ctx = config.loadBankConfig();
+ val ctx = config.loadBankConfig()
Database(cfg.dbConnStr, ctx.regionalCurrency, ctx.fiatCurrency).use { db ->
runBlocking {
db.conn { conn ->
@@ -480,7 +485,7 @@ class CreateAccount : CliktCommand(
)
}
req?.let {
- val (result, internalPayto) = createAccount(db, ctx, req, true);
+ val (result, internalPayto) = createAccount(db, ctx, req, true)
when (result) {
AccountCreationResult.BonusBalanceInsufficient ->
throw Exception("Insufficient admin funds to grant bonus")
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Metadata.kt b/bank/src/main/kotlin/tech/libeufin/bank/Metadata.kt
index 4c1a13d7..8bfbe80c 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/Metadata.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/Metadata.kt
@@ -21,7 +21,7 @@ package tech.libeufin.bank
private val PATTERN = Regex("[a-z0-9A-Z]{52}")
fun parseIncomingTxMetadata(subject: String): EddsaPublicKey? {
- val match = PATTERN.find(subject)?.value ?: return null;
+ val match = PATTERN.find(subject)?.value ?: return null
try {
return EddsaPublicKey(match)
} catch (e: Exception) {
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Params.kt b/bank/src/main/kotlin/tech/libeufin/bank/Params.kt
index 7b3e53e8..59210164 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/Params.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/Params.kt
@@ -20,14 +20,11 @@
package tech.libeufin.bank
import io.ktor.http.*
-import io.ktor.server.application.*
-import io.ktor.server.plugins.*
-import io.ktor.server.request.*
-import io.ktor.server.util.*
-import java.time.*
-import java.time.temporal.*
-import java.util.*
-import tech.libeufin.common.*
+import tech.libeufin.common.TalerAmount
+import tech.libeufin.common.TalerErrorCode
+import java.time.OffsetDateTime
+import java.time.ZoneOffset
+import java.time.temporal.TemporalAdjusters
fun Parameters.expect(name: String): String
= get(name) ?: throw badRequest("Missing '$name' parameter", TalerErrorCode.GENERIC_PARAMETER_MISSING)
@@ -53,10 +50,10 @@ data class MonitorParams(
val which: Int?
) {
companion object {
- val names = Timeframe.values().map { it.name }
+ val names = Timeframe.entries.map { it.name }
val names_fmt = names.joinToString()
fun extract(params: Parameters): MonitorParams {
- val raw = params.get("timeframe") ?: "hour";
+ val raw = params.get("timeframe") ?: "hour"
if (!names.contains(raw)) {
throw badRequest("Param 'timeframe' must be one of $names_fmt", TalerErrorCode.GENERIC_PARAMETER_MALFORMED)
}
@@ -150,10 +147,10 @@ data class StatusParams(
val old_state: WithdrawalStatus
) {
companion object {
- val names = WithdrawalStatus.values().map { it.name }
+ val names = WithdrawalStatus.entries.map { it.name }
val names_fmt = names.joinToString()
fun extract(params: Parameters): StatusParams {
- val old_state = params.get("old_state") ?: "pending";
+ val old_state = params.get("old_state") ?: "pending"
if (!names.contains(old_state)) {
throw badRequest("Param 'old_state' must be one of $names_fmt", TalerErrorCode.GENERIC_PARAMETER_MALFORMED)
}
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/RevenueApi.kt b/bank/src/main/kotlin/tech/libeufin/bank/RevenueApi.kt
index 9009e1a5..fe16a23c 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/RevenueApi.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/RevenueApi.kt
@@ -20,13 +20,10 @@ package tech.libeufin.bank
import io.ktor.http.*
import io.ktor.server.application.*
-import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
-import java.util.*
-import tech.libeufin.common.*
-import tech.libeufin.bank.auth.*
-import tech.libeufin.bank.db.*
+import tech.libeufin.bank.auth.auth
+import tech.libeufin.bank.db.Database
fun Routing.revenueApi(db: Database, ctx: BankConfig) {
auth(db, TokenScope.readonly) {
@@ -38,8 +35,8 @@ fun Routing.revenueApi(db: Database, ctx: BankConfig) {
get("/accounts/{USERNAME}/taler-revenue/history") {
val params = HistoryParams.extract(context.request.queryParameters)
val bankAccount = call.bankInfo(db, ctx.payto)
- val items = db.transaction.revenueHistory(params, bankAccount.bankAccountId, ctx.payto);
-
+ val items = db.transaction.revenueHistory(params, bankAccount.bankAccountId, ctx.payto)
+
if (items.isEmpty()) {
call.respond(HttpStatusCode.NoContent)
} else {
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/TalerCommon.kt b/bank/src/main/kotlin/tech/libeufin/bank/TalerCommon.kt
index 77a67274..de0ebc20 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/TalerCommon.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/TalerCommon.kt
@@ -19,20 +19,25 @@
package tech.libeufin.bank
-import tech.libeufin.common.*
-import io.ktor.http.*
-import io.ktor.serialization.kotlinx.json.*
-import io.ktor.server.application.*
-import java.net.*
+import kotlinx.serialization.KSerializer
+import kotlinx.serialization.Serializable
+import kotlinx.serialization.descriptors.PrimitiveKind
+import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
+import kotlinx.serialization.descriptors.SerialDescriptor
+import kotlinx.serialization.encoding.Decoder
+import kotlinx.serialization.encoding.Encoder
+import kotlinx.serialization.json.JsonDecoder
+import kotlinx.serialization.json.JsonElement
+import kotlinx.serialization.json.jsonPrimitive
+import kotlinx.serialization.json.longOrNull
+import tech.libeufin.common.Base32Crockford
+import tech.libeufin.common.EncodingException
+import tech.libeufin.common.TalerAmount
+import java.net.URL
import java.time.Duration
import java.time.Instant
import java.time.temporal.ChronoUnit
-import java.util.*
import java.util.concurrent.TimeUnit
-import kotlinx.serialization.*
-import kotlinx.serialization.descriptors.*
-import kotlinx.serialization.encoding.*
-import kotlinx.serialization.json.*
/** 32-byte Crockford's Base32 encoded data */
@Serializable(with = Base32Crockford32B.Serializer::class)
@@ -141,20 +146,20 @@ class Base32Crockford64B {
}
/** 32-byte hash code */
-typealias ShortHashCode = Base32Crockford32B;
+typealias ShortHashCode = Base32Crockford32B
/** 64-byte hash code */
-typealias HashCode = Base32Crockford64B;
+typealias HashCode = Base32Crockford64B
/**
* EdDSA and ECDHE public keys always point on Curve25519
* and represented using the standard 256 bits Ed25519 compact format,
* converted to Crockford Base32.
*/
-typealias EddsaPublicKey = Base32Crockford32B;
+typealias EddsaPublicKey = Base32Crockford32B
/** Timestamp containing the number of seconds since epoch */
@Serializable
data class TalerProtocolTimestamp(
- @Serializable(with = TalerProtocolTimestamp.Serializer::class)
+ @Serializable(with = Serializer::class)
val t_s: Instant,
) {
companion object {
@@ -186,7 +191,7 @@ data class TalerProtocolTimestamp(
?: throw badRequest("Could not convert t_s '${maybeTs.content}' to a number")
when {
ts < 0 -> throw badRequest("Negative timestamp not allowed")
- ts > Instant.MAX.getEpochSecond() -> throw badRequest("Timestamp $ts too big to be represented in Kotlin")
+ ts > Instant.MAX.epochSecond -> throw badRequest("Timestamp $ts too big to be represented in Kotlin")
else -> return Instant.ofEpochSecond(ts)
}
}
@@ -205,7 +210,7 @@ class DecimalNumber {
this.frac = frac
}
constructor(encoded: String) {
- val match = PATTERN.matchEntire(encoded) ?: throw badRequest("Invalid decimal number format");
+ val match = PATTERN.matchEntire(encoded) ?: throw badRequest("Invalid decimal number format")
val (value, frac) = match.destructured
this.value = value.toLongOrNull() ?: throw badRequest("Invalid value")
if (this.value > TalerAmount.MAX_VALUE) throw badRequest("Value specified in decimal number is too large")
@@ -249,7 +254,7 @@ class DecimalNumber {
}
companion object {
- private val PATTERN = Regex("([0-9]+)(?:\\.([0-9]{1,8}))?");
+ private val PATTERN = Regex("([0-9]+)(?:\\.([0-9]{1,8}))?")
}
}
@@ -260,7 +265,7 @@ class DecimalNumber {
*/
@Serializable()
data class RelativeTime(
- @Serializable(with = RelativeTime.Serializer::class)
+ @Serializable(with = Serializer::class)
val d_us: Duration
) {
internal object Serializer : KSerializer<Duration> {
@@ -292,7 +297,7 @@ data class RelativeTime(
}
companion object {
- private const val MAX_SAFE_INTEGER = 9007199254740991L; // 2^53 - 1
+ private const val MAX_SAFE_INTEGER = 9007199254740991L // 2^53 - 1
}
}
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/TalerMessage.kt b/bank/src/main/kotlin/tech/libeufin/bank/TalerMessage.kt
index 6f926c10..5f98ae07 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/TalerMessage.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/TalerMessage.kt
@@ -19,18 +19,17 @@
package tech.libeufin.bank
-import tech.libeufin.common.*
-import io.ktor.http.*
-import io.ktor.server.application.*
-import kotlinx.serialization.*
-import java.time.Duration
-import java.time.Instant
-import java.time.temporal.ChronoUnit
-import java.util.*
+import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
-import kotlinx.serialization.descriptors.*
-import kotlinx.serialization.encoding.*
import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+import kotlinx.serialization.descriptors.SerialDescriptor
+import kotlinx.serialization.encoding.Decoder
+import kotlinx.serialization.encoding.Encoder
+import tech.libeufin.common.IbanPayto
+import tech.libeufin.common.Payto
+import tech.libeufin.common.TalerAmount
+import java.time.Instant
/**
* Allowed lengths for fractional digits in amounts.
@@ -92,18 +91,18 @@ sealed class Option<out T> {
fun get(): T? {
return when (this) {
- Option.None -> null
- is Option.Some -> this.value
+ None -> null
+ is Some -> this.value
}
}
inline fun some(lambda: (T) -> Unit) {
- if (this is Option.Some) {
+ if (this is Some) {
lambda(value)
}
}
- fun isSome(): Boolean = this is Option.Some
+ fun isSome(): Boolean = this is Some
@OptIn(ExperimentalSerializationApi::class)
internal class Serializer<T> (
@@ -113,13 +112,13 @@ sealed class Option<out T> {
override fun serialize(encoder: Encoder, value: Option<T>) {
when (value) {
- Option.None -> encoder.encodeNull()
- is Option.Some -> valueSerializer.serialize(encoder, value.value)
+ None -> encoder.encodeNull()
+ is Some -> valueSerializer.serialize(encoder, value.value)
}
}
override fun deserialize(decoder: Decoder): Option<T> {
- return Option.Some(valueSerializer.deserialize(decoder))
+ return Some(valueSerializer.deserialize(decoder))
}
}
}
@@ -156,10 +155,10 @@ data class ChallengeContactData(
val phone: Option<String?> = Option.None
) {
init {
- if (email.get()?.let { !EMAIL_PATTERN.matches(it) } ?: false)
+ if (email.get()?.let { !EMAIL_PATTERN.matches(it) } == true)
throw badRequest("email contact data '$email' is malformed")
- if (phone.get()?.let { !PHONE_PATTERN.matches(it) } ?: false)
+ if (phone.get()?.let { !PHONE_PATTERN.matches(it) } == true)
throw badRequest("phone contact data '$phone' is malformed")
}
companion object {
@@ -215,10 +214,10 @@ data class TokenRequest(
@Serializable
sealed interface MonitorResponse {
- abstract val talerInCount: Long
- abstract val talerInVolume: TalerAmount
- abstract val talerOutCount: Long
- abstract val talerOutVolume: TalerAmount
+ val talerInCount: Long
+ val talerInVolume: TalerAmount
+ val talerOutCount: Long
+ val talerOutVolume: TalerAmount
}
@Serializable
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Tan.kt b/bank/src/main/kotlin/tech/libeufin/bank/Tan.kt
index 5dddd807..eadddc29 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/Tan.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/Tan.kt
@@ -18,29 +18,27 @@
*/
package tech.libeufin.bank
-import java.security.SecureRandom
-import java.time.Instant
-import java.time.Duration
-import java.text.DecimalFormat
-import kotlinx.serialization.json.Json
import io.ktor.http.*
+import io.ktor.server.application.*
import io.ktor.server.request.*
import io.ktor.server.response.*
-import io.ktor.server.application.*
-import tech.libeufin.bank.db.TanDAO.*
-import tech.libeufin.bank.db.*
-import tech.libeufin.bank.auth.*
-import io.ktor.util.pipeline.PipelineContext
+import kotlinx.serialization.json.Json
+import tech.libeufin.bank.auth.username
+import tech.libeufin.bank.db.Database
+import tech.libeufin.bank.db.TanDAO.Challenge
+import java.security.SecureRandom
+import java.text.DecimalFormat
+import java.time.Instant
-inline suspend fun <reified B> ApplicationCall.respondChallenge(
+suspend inline fun <reified B> ApplicationCall.respondChallenge(
db: Database,
op: Operation,
body: B,
channel: TanChannel? = null,
info: String? = null
) {
- val json = Json.encodeToString(kotlinx.serialization.serializer<B>(), body);
+ val json = Json.encodeToString(kotlinx.serialization.serializer<B>(), body)
val code = Tan.genCode()
val id = db.tan.new(
login = username,
@@ -59,7 +57,7 @@ inline suspend fun <reified B> ApplicationCall.respondChallenge(
)
}
-inline suspend fun <reified B> ApplicationCall.receiveChallenge(
+suspend inline fun <reified B> ApplicationCall.receiveChallenge(
db: Database,
op: Operation
): Pair<B, Challenge?> {
@@ -85,7 +83,7 @@ suspend fun ApplicationCall.challenge(
}
object Tan {
- private val CODE_FORMAT = DecimalFormat("00000000");
+ private val CODE_FORMAT = DecimalFormat("00000000")
private val SECURE_RNG = SecureRandom()
fun genCode(): String {
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/WireGatewayApi.kt b/bank/src/main/kotlin/tech/libeufin/bank/WireGatewayApi.kt
index 0a197422..92a0390d 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/WireGatewayApi.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/WireGatewayApi.kt
@@ -26,12 +26,17 @@ import io.ktor.server.application.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
-import io.ktor.util.pipeline.PipelineContext
+import io.ktor.util.pipeline.*
+import tech.libeufin.bank.auth.auth
+import tech.libeufin.bank.auth.authAdmin
+import tech.libeufin.bank.auth.username
+import tech.libeufin.bank.db.Database
+import tech.libeufin.bank.db.ExchangeDAO
+import tech.libeufin.bank.db.ExchangeDAO.AddIncomingResult
+import tech.libeufin.bank.db.ExchangeDAO.TransferResult
+import tech.libeufin.common.BankPaytoCtx
+import tech.libeufin.common.TalerErrorCode
import java.time.Instant
-import tech.libeufin.common.*
-import tech.libeufin.bank.db.*
-import tech.libeufin.bank.db.ExchangeDAO.*
-import tech.libeufin.bank.auth.*
fun Routing.wireGatewayApi(db: Database, ctx: BankConfig) {
@@ -94,8 +99,8 @@ fun Routing.wireGatewayApi(db: Database, ctx: BankConfig) {
TalerErrorCode.BANK_ACCOUNT_IS_NOT_EXCHANGE
)
- val items = db.exchange.dbLambda(params, bankAccount.bankAccountId, ctx.payto);
-
+ val items = db.exchange.dbLambda(params, bankAccount.bankAccountId, ctx.payto)
+
if (items.isEmpty()) {
call.respond(HttpStatusCode.NoContent)
} else {
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/auth/auth.kt b/bank/src/main/kotlin/tech/libeufin/bank/auth/auth.kt
index 93baecc5..425af5e8 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/auth/auth.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/auth/auth.kt
@@ -21,20 +21,20 @@ package tech.libeufin.bank.auth
import io.ktor.http.*
import io.ktor.server.application.*
-import io.ktor.server.routing.Route
-import io.ktor.server.response.header
-import io.ktor.util.AttributeKey
-import io.ktor.util.pipeline.PipelineContext
-import java.time.Instant
-import tech.libeufin.bank.db.AccountDAO.*
-import tech.libeufin.bank.db.*
+import io.ktor.server.response.*
+import io.ktor.server.routing.*
+import io.ktor.util.*
+import io.ktor.util.pipeline.*
import tech.libeufin.bank.*
+import tech.libeufin.bank.db.Database
import tech.libeufin.common.*
+import java.time.Instant
/** Used to store if the currenly authenticated user is admin */
-private val AUTH_IS_ADMIN = AttributeKey<Boolean>("is_admin");
+private val AUTH_IS_ADMIN = AttributeKey<Boolean>("is_admin")
+
/** Used to store used auth token */
-private val AUTH_TOKEN = AttributeKey<ByteArray>("auth_token");
+private val AUTH_TOKEN = AttributeKey<ByteArray>("auth_token")
/** Get username of the request account */
val ApplicationCall.username: String get() = expectParameter("USERNAME")
@@ -89,7 +89,7 @@ fun Route.auth(db: Database, scope: TokenScope, allowAdmin: Boolean = false, req
if (requireAdmin && authLogin != "admin") {
throw unauthorized("Only administrator allowed")
} else {
- val hasRight = authLogin == username || (allowAdmin && authLogin == "admin");
+ val hasRight = authLogin == username || (allowAdmin && authLogin == "admin")
if (!hasRight) {
throw unauthorized("Customer $authLogin have no right on $username account")
}
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/db/AccountDAO.kt b/bank/src/main/kotlin/tech/libeufin/bank/db/AccountDAO.kt
index e172ea78..18432e59 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/db/AccountDAO.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/db/AccountDAO.kt
@@ -19,10 +19,9 @@
package tech.libeufin.bank.db
-import tech.libeufin.common.*
-import java.time.*
-import java.sql.Types
import tech.libeufin.bank.*
+import tech.libeufin.common.*
+import java.time.Instant
/** Data access logic for accounts */
class AccountDAO(private val db: Database) {
@@ -51,7 +50,7 @@ class AccountDAO(private val db: Database) {
// Whether to check [internalPaytoUri] for idempotency
checkPaytoIdempotent: Boolean
): AccountCreationResult = db.serializable { it ->
- val now = Instant.now().toDbMicros() ?: throw faultyTimestampByBank();
+ val now = Instant.now().toDbMicros() ?: throw faultyTimestampByBank()
it.transaction { conn ->
val idempotent = conn.prepareStatement("""
SELECT password_hash, name=?
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/db/CashoutDAO.kt b/bank/src/main/kotlin/tech/libeufin/bank/db/CashoutDAO.kt
index 2033e101..3f044ea1 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/db/CashoutDAO.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/db/CashoutDAO.kt
@@ -19,11 +19,9 @@
package tech.libeufin.bank.db
-import java.time.Duration
-import java.time.Instant
-import java.util.concurrent.TimeUnit
-import tech.libeufin.common.*
import tech.libeufin.bank.*
+import tech.libeufin.common.*
+import java.time.Instant
/** Data access logic for cashout operations */
class CashoutDAO(private val db: Database) {
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/db/ConversionDAO.kt b/bank/src/main/kotlin/tech/libeufin/bank/db/ConversionDAO.kt
index bb311eba..a76b7630 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/db/ConversionDAO.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/db/ConversionDAO.kt
@@ -19,9 +19,14 @@
package tech.libeufin.bank.db
-import tech.libeufin.common.*
-import tech.libeufin.bank.*
-import tech.libeufin.bank.*
+import tech.libeufin.bank.ConversionRate
+import tech.libeufin.bank.DecimalNumber
+import tech.libeufin.bank.RoundingMode
+import tech.libeufin.bank.internalServerError
+import tech.libeufin.common.TalerAmount
+import tech.libeufin.common.getAmount
+import tech.libeufin.common.oneOrNull
+import tech.libeufin.common.transaction
/** Data access logic for conversion */
class ConversionDAO(private val db: Database) {
@@ -68,8 +73,8 @@ class ConversionDAO(private val db: Database) {
it.transaction { conn ->
val check = conn.prepareStatement("select exists(select 1 from config where key='cashin_ratio')").oneOrNull { it.getBoolean(1) }!!
if (!check) return@transaction null
- val amount = conn.prepareStatement("SELECT (amount).val as amount_val, (amount).frac as amount_frac FROM config_get_amount(?) as amount");
- val roundingMode = conn.prepareStatement("SELECT config_get_rounding_mode(?)");
+ val amount = conn.prepareStatement("SELECT (amount).val as amount_val, (amount).frac as amount_frac FROM config_get_amount(?) as amount")
+ val roundingMode = conn.prepareStatement("SELECT config_get_rounding_mode(?)")
fun getAmount(name: String, currency: String): TalerAmount {
amount.setString(1, name)
return amount.oneOrNull { it.getAmount("amount", currency) }!!
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/db/Database.kt b/bank/src/main/kotlin/tech/libeufin/bank/db/Database.kt
index 91262ce5..1880b67b 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/db/Database.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/db/Database.kt
@@ -19,21 +19,19 @@
package tech.libeufin.bank.db
-import org.postgresql.jdbc.PgConnection
-import org.postgresql.ds.PGSimpleDataSource
-import org.postgresql.util.PSQLState
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withTimeoutOrNull
import org.slf4j.Logger
import org.slf4j.LoggerFactory
-import java.sql.*
-import java.time.*
-import java.util.*
-import java.util.concurrent.TimeUnit
-import kotlin.math.abs
-import kotlinx.coroutines.flow.*
-import kotlinx.coroutines.*
-import tech.libeufin.common.*
-import io.ktor.http.HttpStatusCode
import tech.libeufin.bank.*
+import tech.libeufin.common.*
+import java.sql.PreparedStatement
+import java.sql.ResultSet
+import java.sql.Types
+import kotlin.math.abs
private val logger: Logger = LoggerFactory.getLogger("libeufin-bank-db")
@@ -95,7 +93,7 @@ class Database(dbConfig: String, internal val bankCurrency: String, internal val
if (params.which != null) {
stmt.setInt(2, params.which)
} else {
- stmt.setNull(2, java.sql.Types.INTEGER)
+ stmt.setNull(2, Types.INTEGER)
}
stmt.oneOrNull {
fiatCurrency?.run {
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/db/ExchangeDAO.kt b/bank/src/main/kotlin/tech/libeufin/bank/db/ExchangeDAO.kt
index a8d926f9..af4639df 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/db/ExchangeDAO.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/db/ExchangeDAO.kt
@@ -19,12 +19,12 @@
package tech.libeufin.bank.db
-import java.util.UUID
-import java.time.Instant
-import java.time.Duration
-import java.util.concurrent.TimeUnit
-import tech.libeufin.common.*
import tech.libeufin.bank.*
+import tech.libeufin.common.BankPaytoCtx
+import tech.libeufin.common.getAmount
+import tech.libeufin.common.getBankPayto
+import tech.libeufin.common.toDbMicros
+import java.time.Instant
/** Data access logic for exchange specific logic */
class ExchangeDAO(private val db: Database) {
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/db/NotificationWatcher.kt b/bank/src/main/kotlin/tech/libeufin/bank/db/NotificationWatcher.kt
index eb6cd879..ab8814b4 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/db/NotificationWatcher.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/db/NotificationWatcher.kt
@@ -19,15 +19,15 @@
package tech.libeufin.bank.db
-import java.util.UUID
-import java.util.concurrent.ConcurrentHashMap
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import org.postgresql.ds.PGSimpleDataSource
import org.slf4j.Logger
import org.slf4j.LoggerFactory
-import tech.libeufin.common.*
import tech.libeufin.bank.*
+import tech.libeufin.common.*
+import java.util.*
+import java.util.concurrent.ConcurrentHashMap
private val logger: Logger = LoggerFactory.getLogger("libeufin-bank-db-watcher")
@@ -115,18 +115,18 @@ internal class NotificationWatcher(private val pgSource: PGSimpleDataSource) {
private suspend fun <R, K, V> listen(map: ConcurrentHashMap<K, CountedSharedFlow<V>>, key: K, lambda: suspend (Flow<V>) -> R): R {
// Register listener, create a new flow if missing
val flow = map.compute(key) { _, v ->
- val tmp = v ?: CountedSharedFlow(MutableSharedFlow(), 0);
- tmp.count++;
+ val tmp = v ?: CountedSharedFlow(MutableSharedFlow(), 0)
+ tmp.count++
tmp
- }!!.flow;
+ }!!.flow
try {
return lambda(flow)
} finally {
// Unregister listener, removing unused flow
map.compute(key) { _, v ->
- v!!;
- v.count--;
+ v!!
+ v.count--
if (v.count > 0) v else null
}
}
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/db/TanDAO.kt b/bank/src/main/kotlin/tech/libeufin/bank/db/TanDAO.kt
index 46692204..9017540d 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/db/TanDAO.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/db/TanDAO.kt
@@ -19,12 +19,14 @@
package tech.libeufin.bank.db
-import tech.libeufin.common.*
-import tech.libeufin.bank.*
-import tech.libeufin.bank.db.*
-import java.util.concurrent.TimeUnit
+import tech.libeufin.bank.Operation
+import tech.libeufin.bank.TanChannel
+import tech.libeufin.bank.internalServerError
+import tech.libeufin.common.oneOrNull
+import tech.libeufin.common.toDbMicros
import java.time.Duration
import java.time.Instant
+import java.util.concurrent.TimeUnit
/** Data access logic for tan challenged */
class TanDAO(private val db: Database) {
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/db/TokenDAO.kt b/bank/src/main/kotlin/tech/libeufin/bank/db/TokenDAO.kt
index 92708308..8a5c594c 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/db/TokenDAO.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/db/TokenDAO.kt
@@ -19,9 +19,13 @@
package tech.libeufin.bank.db
-import tech.libeufin.common.*
+import tech.libeufin.bank.BearerToken
+import tech.libeufin.bank.TokenScope
+import tech.libeufin.common.executeUpdateViolation
+import tech.libeufin.common.microsToJavaInstant
+import tech.libeufin.common.oneOrNull
+import tech.libeufin.common.toDbMicros
import java.time.Instant
-import tech.libeufin.bank.*
/** Data access logic for auth tokens */
class TokenDAO(private val db: Database) {
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/db/TransactionDAO.kt b/bank/src/main/kotlin/tech/libeufin/bank/db/TransactionDAO.kt
index f3c8cd30..be427b66 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/db/TransactionDAO.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/db/TransactionDAO.kt
@@ -21,10 +21,9 @@ package tech.libeufin.bank.db
import org.slf4j.Logger
import org.slf4j.LoggerFactory
-import tech.libeufin.common.*
-import java.time.*
-import java.sql.Types
import tech.libeufin.bank.*
+import tech.libeufin.common.*
+import java.time.Instant
private val logger: Logger = LoggerFactory.getLogger("libeufin-bank-tx-dao")
@@ -50,7 +49,7 @@ class TransactionDAO(private val db: Database) {
timestamp: Instant,
is2fa: Boolean
): BankTransactionResult = db.serializable { conn ->
- val now = timestamp.toDbMicros() ?: throw faultyTimestampByBank();
+ val now = timestamp.toDbMicros() ?: throw faultyTimestampByBank()
conn.transaction {
val stmt = conn.prepareStatement("""
SELECT
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/db/WithdrawalDAO.kt b/bank/src/main/kotlin/tech/libeufin/bank/db/WithdrawalDAO.kt
index 12977610..330006a1 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/db/WithdrawalDAO.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/db/WithdrawalDAO.kt
@@ -19,14 +19,14 @@
package tech.libeufin.bank.db
-import java.util.UUID
-import java.time.Instant
-import java.time.Duration
-import java.util.concurrent.TimeUnit
-import tech.libeufin.common.*
-import kotlinx.coroutines.flow.*
-import kotlinx.coroutines.*
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withTimeoutOrNull
import tech.libeufin.bank.*
+import tech.libeufin.common.*
+import java.time.Instant
+import java.util.*
/** Data access logic for withdrawal operations */
class WithdrawalDAO(private val db: Database) {
@@ -213,7 +213,7 @@ class WithdrawalDAO(private val db: Database) {
// Initial loading
val init = load()
// Long polling if there is no operation or its not confirmed
- if (init?.run { status(this) == params.old_state } ?: true) {
+ if (init?.run { status(this) == params.old_state } != false) {
polling.join()
load()
} else {
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/helpers.kt b/bank/src/main/kotlin/tech/libeufin/bank/helpers.kt
index 39d21cf4..dd827f2b 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/helpers.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/helpers.kt
@@ -23,23 +23,21 @@ import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.plugins.*
import io.ktor.server.request.*
-import io.ktor.server.routing.Route
-import io.ktor.server.routing.RouteSelector
-import io.ktor.server.routing.RouteSelectorEvaluation
-import io.ktor.server.routing.RoutingResolveContext
+import io.ktor.server.routing.*
import io.ktor.server.util.*
-import io.ktor.util.pipeline.PipelineContext
-import kotlinx.serialization.*
-import kotlinx.serialization.descriptors.*
-import kotlinx.serialization.encoding.*
-import java.net.*
-import java.time.*
-import java.time.temporal.*
-import java.util.*
+import io.ktor.util.pipeline.*
+import kotlinx.serialization.KSerializer
+import kotlinx.serialization.Serializable
+import kotlinx.serialization.descriptors.PrimitiveKind
+import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
+import kotlinx.serialization.descriptors.SerialDescriptor
+import kotlinx.serialization.encoding.Decoder
+import kotlinx.serialization.encoding.Encoder
+import tech.libeufin.bank.auth.username
+import tech.libeufin.bank.db.AccountDAO.AccountCreationResult
+import tech.libeufin.bank.db.Database
import tech.libeufin.common.*
-import tech.libeufin.bank.db.*
-import tech.libeufin.bank.db.AccountDAO.*
-import tech.libeufin.bank.auth.*
+import java.util.*
fun ApplicationCall.expectParameter(name: String) =
parameters[name] ?: throw badRequest(
@@ -108,7 +106,7 @@ fun ApplicationCall.longParameter(name: String): Long {
* It returns false in case of problems, true otherwise.
*/
suspend fun createAdminAccount(db: Database, cfg: BankConfig, pw: String? = null): AccountCreationResult {
- var pwStr = pw;
+ var pwStr = pw
if (pwStr == null) {
val pwBuf = ByteArray(32)
Random().nextBytes(pwBuf)
diff --git a/bank/src/test/kotlin/AmountTest.kt b/bank/src/test/kotlin/AmountTest.kt
index 5f51b5ad..94716208 100644
--- a/bank/src/test/kotlin/AmountTest.kt
+++ b/bank/src/test/kotlin/AmountTest.kt
@@ -17,16 +17,14 @@
* <http://www.gnu.org/licenses/>
*/
-import java.time.Instant
-import java.util.*
-import kotlin.test.*
import org.junit.Test
-import org.postgresql.jdbc.PgConnection
-import tech.libeufin.bank.*
-import tech.libeufin.bank.db.*
-import tech.libeufin.bank.db.TransactionDAO.*
-import tech.libeufin.bank.db.WithdrawalDAO.*
+import tech.libeufin.bank.DecimalNumber
+import tech.libeufin.bank.db.TransactionDAO.BankTransactionResult
+import tech.libeufin.bank.db.WithdrawalDAO.WithdrawalCreationResult
import tech.libeufin.common.*
+import java.time.Instant
+import java.util.*
+import kotlin.test.assertEquals
class AmountTest {
// Test amount computation in database
diff --git a/bank/src/test/kotlin/BankIntegrationApiTest.kt b/bank/src/test/kotlin/BankIntegrationApiTest.kt
index 5f516525..f84c382c 100644
--- a/bank/src/test/kotlin/BankIntegrationApiTest.kt
+++ b/bank/src/test/kotlin/BankIntegrationApiTest.kt
@@ -17,19 +17,18 @@
* <http://www.gnu.org/licenses/>
*/
-import io.ktor.client.plugins.*
import io.ktor.client.request.*
-import io.ktor.client.statement.*
-import io.ktor.http.*
-import io.ktor.server.testing.*
-import java.util.*
-import kotlin.test.*
-import kotlinx.coroutines.*
-import kotlinx.serialization.json.*
import org.junit.Test
-import tech.libeufin.bank.*
-import tech.libeufin.bank.db.*
-import tech.libeufin.common.*
+import tech.libeufin.bank.BankAccountCreateWithdrawalResponse
+import tech.libeufin.bank.BankWithdrawalOperationPostResponse
+import tech.libeufin.bank.BankWithdrawalOperationStatus
+import tech.libeufin.bank.WithdrawalStatus
+import tech.libeufin.common.TalerAmount
+import tech.libeufin.common.TalerErrorCode
+import tech.libeufin.common.json
+import tech.libeufin.common.obj
+import java.util.*
+import kotlin.test.assertEquals
class BankIntegrationApiTest {
// GET /taler-integration/config
diff --git a/bank/src/test/kotlin/ConversionApiTest.kt b/bank/src/test/kotlin/ConversionApiTest.kt
index a228705f..89de59d1 100644
--- a/bank/src/test/kotlin/ConversionApiTest.kt
+++ b/bank/src/test/kotlin/ConversionApiTest.kt
@@ -17,18 +17,12 @@
* <http://www.gnu.org/licenses/>
*/
-import io.ktor.client.plugins.*
import io.ktor.client.request.*
-import io.ktor.client.statement.*
-import io.ktor.http.*
-import io.ktor.server.testing.*
-import java.util.*
-import kotlin.test.*
-import kotlinx.coroutines.*
-import kotlinx.serialization.json.*
import org.junit.Test
-import tech.libeufin.bank.*
-import tech.libeufin.common.*
+import tech.libeufin.bank.ConversionResponse
+import tech.libeufin.common.TalerAmount
+import tech.libeufin.common.TalerErrorCode
+import kotlin.test.assertEquals
class ConversionApiTest {
// GET /conversion-info/config
diff --git a/bank/src/test/kotlin/CoreBankApiTest.kt b/bank/src/test/kotlin/CoreBankApiTest.kt
index 0660b892..02d410bf 100644
--- a/bank/src/test/kotlin/CoreBankApiTest.kt
+++ b/bank/src/test/kotlin/CoreBankApiTest.kt
@@ -17,23 +17,20 @@
* <http://www.gnu.org/licenses/>
*/
-import io.ktor.client.plugins.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
-import io.ktor.http.content.*
-import io.ktor.server.engine.*
import io.ktor.server.testing.*
-import java.time.Duration
-import java.time.Instant
-import java.util.*
-import kotlin.test.*
-import kotlinx.coroutines.*
import kotlinx.serialization.json.JsonElement
import org.junit.Test
import tech.libeufin.bank.*
-import tech.libeufin.bank.db.*
import tech.libeufin.common.*
+import java.time.Duration
+import java.time.Instant
+import java.util.*
+import kotlin.test.assertEquals
+import kotlin.test.assertNotNull
+import kotlin.test.assertNull
class CoreBankConfigTest {
// GET /config
@@ -592,7 +589,7 @@ class CoreBankAccountsApiTest {
client.getA("/accounts/merchant").assertOkJson<AccountData> { obj ->
assert(obj.is_public)
}
- }.assertNoContent();
+ }.assertNoContent()
client.getA("/accounts/merchant").assertOkJson<AccountData> { obj ->
assert(!obj.is_public)
}
@@ -945,7 +942,7 @@ class CoreBankTransactionsApiTest {
assertBalance("exchange", "+KUDOS:0")
tx("merchant", "KUDOS:1", "exchange", "") // Bounce common to transaction
tx("merchant", "KUDOS:1", "exchange", "Malformed") // Bounce malformed transaction
- val reservePub = randEddsaPublicKey();
+ val reservePub = randEddsaPublicKey()
tx("merchant", "KUDOS:1", "exchange", randIncomingSubject(reservePub)) // Accept incoming
tx("merchant", "KUDOS:1", "exchange", randIncomingSubject(reservePub)) // Bounce reserve_pub reuse
assertBalance("merchant", "-KUDOS:1")
diff --git a/bank/src/test/kotlin/DatabaseTest.kt b/bank/src/test/kotlin/DatabaseTest.kt
index 97a1b4f5..9b84fcc3 100644
--- a/bank/src/test/kotlin/DatabaseTest.kt
+++ b/bank/src/test/kotlin/DatabaseTest.kt
@@ -17,20 +17,18 @@
* <http://www.gnu.org/licenses/>
*/
-import io.ktor.client.plugins.*
-import io.ktor.client.request.*
-import io.ktor.client.statement.*
-import io.ktor.http.*
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.launch
+import org.junit.Test
+import tech.libeufin.bank.createAdminAccount
+import tech.libeufin.bank.db.AccountDAO.AccountCreationResult
+import tech.libeufin.common.oneOrNull
import java.time.Duration
import java.time.Instant
import java.time.temporal.ChronoUnit
import java.util.concurrent.TimeUnit
-import kotlin.test.*
-import kotlinx.coroutines.*
-import org.junit.Test
-import tech.libeufin.bank.*
-import tech.libeufin.bank.db.AccountDAO.*
-import tech.libeufin.common.*
+import kotlin.test.assertEquals
+import kotlin.test.assertNull
class DatabaseTest {
diff --git a/bank/src/test/kotlin/JsonTest.kt b/bank/src/test/kotlin/JsonTest.kt
index 3a7e5f21..06bb7498 100644
--- a/bank/src/test/kotlin/JsonTest.kt
+++ b/bank/src/test/kotlin/JsonTest.kt
@@ -17,15 +17,17 @@
* <http://www.gnu.org/licenses/>
*/
-import java.time.Duration
-import java.time.Instant
-import java.time.temporal.ChronoUnit
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import org.junit.Test
-import tech.libeufin.bank.*
-import tech.libeufin.common.*
+import tech.libeufin.bank.CreditDebitInfo
+import tech.libeufin.bank.RelativeTime
+import tech.libeufin.bank.TalerProtocolTimestamp
+import tech.libeufin.common.TalerAmount
+import java.time.Duration
+import java.time.Instant
+import java.time.temporal.ChronoUnit
@Serializable
data class MyJsonType(
diff --git a/bank/src/test/kotlin/PaytoTest.kt b/bank/src/test/kotlin/PaytoTest.kt
index a5211194..e75b8d9f 100644
--- a/bank/src/test/kotlin/PaytoTest.kt
+++ b/bank/src/test/kotlin/PaytoTest.kt
@@ -17,18 +17,15 @@
* <http://www.gnu.org/licenses/>
*/
-import io.ktor.client.plugins.*
import io.ktor.client.request.*
-import io.ktor.client.statement.*
-import io.ktor.http.*
-import io.ktor.server.testing.*
-import java.util.*
-import kotlinx.coroutines.*
-import kotlinx.serialization.json.*
import org.junit.Test
-import tech.libeufin.bank.*
-import tech.libeufin.common.*
-import kotlin.test.*
+import tech.libeufin.bank.BankAccountTransactionInfo
+import tech.libeufin.bank.RegisterAccountResponse
+import tech.libeufin.bank.TransactionCreateResponse
+import tech.libeufin.common.IbanPayto
+import tech.libeufin.common.TalerAmount
+import tech.libeufin.common.json
+import kotlin.test.assertEquals
class PaytoTest {
// x-taler-bank
diff --git a/bank/src/test/kotlin/RevenueApiTest.kt b/bank/src/test/kotlin/RevenueApiTest.kt
index dfa0e69c..2a458cd8 100644
--- a/bank/src/test/kotlin/RevenueApiTest.kt
+++ b/bank/src/test/kotlin/RevenueApiTest.kt
@@ -17,16 +17,9 @@
* <http://www.gnu.org/licenses/>
*/
-import io.ktor.client.plugins.*
-import io.ktor.client.request.*
-import io.ktor.client.statement.*
import io.ktor.http.*
-import io.ktor.server.testing.*
-import java.util.*
-import kotlinx.coroutines.*
-import kotlinx.serialization.json.*
import org.junit.Test
-import tech.libeufin.bank.*
+import tech.libeufin.bank.RevenueIncomingHistory
class RevenueApiTest {
// GET /accounts/{USERNAME}/taler-revenue/config
diff --git a/bank/src/test/kotlin/SecurityTest.kt b/bank/src/test/kotlin/SecurityTest.kt
index 16d2b3f8..b37c665b 100644
--- a/bank/src/test/kotlin/SecurityTest.kt
+++ b/bank/src/test/kotlin/SecurityTest.kt
@@ -17,22 +17,17 @@
* <http://www.gnu.org/licenses/>
*/
-import io.ktor.client.plugins.*
import io.ktor.client.request.*
-import io.ktor.client.statement.*
import io.ktor.http.*
-import io.ktor.http.content.*
-import io.ktor.server.engine.*
-import io.ktor.server.testing.*
-import kotlin.test.*
-import kotlinx.coroutines.*
-import kotlinx.serialization.json.*
+import kotlinx.serialization.json.Json
import org.junit.Test
-import tech.libeufin.bank.*
-import tech.libeufin.common.*
+import tech.libeufin.common.TalerErrorCode
+import tech.libeufin.common.deflate
+import tech.libeufin.common.json
+import tech.libeufin.common.obj
inline fun <reified B> HttpRequestBuilder.jsonDeflate(b: B) {
- val json = Json.encodeToString(kotlinx.serialization.serializer<B>(), b);
+ val json = Json.encodeToString(kotlinx.serialization.serializer<B>(), b)
contentType(ContentType.Application.Json)
headers.set(HttpHeaders.ContentEncoding, "deflate")
setBody(json.toByteArray().inputStream().deflate().readBytes())
diff --git a/bank/src/test/kotlin/StatsTest.kt b/bank/src/test/kotlin/StatsTest.kt
index 1aa1979e..edbd26b6 100644
--- a/bank/src/test/kotlin/StatsTest.kt
+++ b/bank/src/test/kotlin/StatsTest.kt
@@ -18,17 +18,17 @@
*/
import io.ktor.client.request.*
-import io.ktor.client.statement.*
-import io.ktor.http.*
-import io.ktor.http.content.*
-import io.ktor.server.testing.*
-import java.time.*
-import java.time.Instant
-import java.util.*
-import kotlin.test.*
import org.junit.Test
-import tech.libeufin.bank.*
-import tech.libeufin.common.*
+import tech.libeufin.bank.MonitorResponse
+import tech.libeufin.bank.MonitorWithConversion
+import tech.libeufin.bank.Timeframe
+import tech.libeufin.common.TalerAmount
+import tech.libeufin.common.executeQueryCheck
+import tech.libeufin.common.oneOrNull
+import tech.libeufin.common.toDbMicros
+import java.time.Instant
+import java.time.LocalDateTime
+import kotlin.test.assertEquals
class StatsTest {
@Test
@@ -46,7 +46,7 @@ class StatsTest {
stmt.setLong(3, amount.value)
stmt.setInt(4, amount.frac)
stmt.setString(5, "")
- stmt.executeQueryCheck();
+ stmt.executeQueryCheck()
}
}
diff --git a/bank/src/test/kotlin/WireGatewayApiTest.kt b/bank/src/test/kotlin/WireGatewayApiTest.kt
index ba1f3360..676e455b 100644
--- a/bank/src/test/kotlin/WireGatewayApiTest.kt
+++ b/bank/src/test/kotlin/WireGatewayApiTest.kt
@@ -17,17 +17,13 @@
* <http://www.gnu.org/licenses/>
*/
-import io.ktor.client.plugins.*
-import io.ktor.client.request.*
-import io.ktor.client.statement.*
import io.ktor.http.*
-import io.ktor.server.testing.*
-import java.util.*
-import kotlinx.coroutines.*
-import kotlinx.serialization.json.*
import org.junit.Test
-import tech.libeufin.bank.*
-import tech.libeufin.common.*
+import tech.libeufin.bank.IncomingHistory
+import tech.libeufin.bank.OutgoingHistory
+import tech.libeufin.common.TalerErrorCode
+import tech.libeufin.common.json
+import tech.libeufin.common.obj
class WireGatewayApiTest {
// GET /accounts/{USERNAME}/taler-wire-gateway/config
@@ -47,7 +43,7 @@ class WireGatewayApiTest {
"exchange_base_url" to "http://exchange.example.com/"
"wtid" to randShortHashCode()
"credit_account" to merchantPayto.canonical
- };
+ }
authRoutine(HttpMethod.Post, "/accounts/merchant/taler-wire-gateway/transfer", valid_req)
@@ -208,7 +204,7 @@ class WireGatewayApiTest {
"amount" to "KUDOS:44"
"reserve_pub" to randEddsaPublicKey()
"debit_account" to merchantPayto.canonical
- };
+ }
authRoutine(HttpMethod.Post, "/accounts/merchant/taler-wire-gateway/admin/add-incoming", valid_req, requireAdmin = true)
diff --git a/bank/src/test/kotlin/helpers.kt b/bank/src/test/kotlin/helpers.kt
index f4d3a4a6..40c8bb59 100644
--- a/bank/src/test/kotlin/helpers.kt
+++ b/bank/src/test/kotlin/helpers.kt
@@ -17,22 +17,23 @@
* <http://www.gnu.org/licenses/>
*/
-import io.ktor.client.HttpClient
+import io.ktor.client.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import io.ktor.server.testing.*
-import java.io.ByteArrayOutputStream
-import java.nio.file.*
-import kotlin.test.*
-import kotlin.io.path.*
-import kotlin.random.Random
-import kotlinx.coroutines.*
-import kotlinx.serialization.json.*
+import kotlinx.coroutines.runBlocking
import tech.libeufin.bank.*
-import tech.libeufin.bank.db.*
-import tech.libeufin.bank.db.AccountDAO.*
+import tech.libeufin.bank.db.AccountDAO.AccountCreationResult
+import tech.libeufin.bank.db.Database
import tech.libeufin.common.*
+import java.nio.file.NoSuchFileException
+import kotlin.io.path.Path
+import kotlin.io.path.deleteExisting
+import kotlin.io.path.readText
+import kotlin.random.Random
+import kotlin.test.assertEquals
+import kotlin.test.assertNotNull
/* ----- Setup ----- */
@@ -156,7 +157,7 @@ fun bankSetup(
}
fun dbSetup(lambda: suspend (Database) -> Unit) {
- setup() { db, _ -> lambda(db) }
+ setup { db, _ -> lambda(db) }
}
/* ----- Common actions ----- */
@@ -174,7 +175,7 @@ suspend fun ApplicationTestBuilder.assertBalance(account: String, amount: String
client.get("/accounts/$account") {
pwAuth("admin")
}.assertOkJson<AccountData> {
- val balance = it.balance;
+ val balance = it.balance
val fmt = "${if (balance.credit_debit_indicator == CreditDebitInfo.debit) '-' else '+'}${balance.amount}"
assertEquals(amount, fmt, "For $account")
}
@@ -305,7 +306,7 @@ suspend fun tanCode(info: String): String? {
val file = Path("/tmp/tan-$info.txt")
val code = file.readText()
file.deleteExisting()
- return code;
+ return code
} catch (e: Exception) {
if (e is NoSuchFileException) return null
throw e
@@ -391,7 +392,7 @@ fun assertException(msg: String, lambda: () -> Unit) {
}
}
-inline suspend fun <reified B> HttpResponse.assertHistoryIds(size: Int, ids: (B) -> List<Long>): B {
+suspend inline fun <reified B> HttpResponse.assertHistoryIds(size: Int, ids: (B) -> List<Long>): B {
assertOk()
val body = json<B>()
val history = ids(body)
@@ -418,14 +419,14 @@ inline suspend fun <reified B> HttpResponse.assertHistoryIds(size: Int, ids: (B)
/* ----- Body helper ----- */
-inline suspend fun <reified B> HttpResponse.assertOkJson(lambda: (B) -> Unit = {}): B {
+suspend inline fun <reified B> HttpResponse.assertOkJson(lambda: (B) -> Unit = {}): B {
assertOk()
val body = json<B>()
lambda(body)
return body
}
-inline suspend fun <reified B> HttpResponse.assertAcceptedJson(lambda: (B) -> Unit = {}): B {
+suspend inline fun <reified B> HttpResponse.assertAcceptedJson(lambda: (B) -> Unit = {}): B {
assertAccepted()
val body = json<B>()
lambda(body)
@@ -435,7 +436,7 @@ inline suspend fun <reified B> HttpResponse.assertAcceptedJson(lambda: (B) -> Un
/* ----- Auth ----- */
/** Auto auth get request */
-inline suspend fun HttpClient.getA(url: String, builder: HttpRequestBuilder.() -> Unit = {}): HttpResponse {
+suspend inline fun HttpClient.getA(url: String, builder: HttpRequestBuilder.() -> Unit = {}): HttpResponse {
return get(url) {
pwAuth()
builder(this)
@@ -443,7 +444,7 @@ inline suspend fun HttpClient.getA(url: String, builder: HttpRequestBuilder.() -
}
/** Auto auth post request */
-inline suspend fun HttpClient.postA(url: String, builder: HttpRequestBuilder.() -> Unit = {}): HttpResponse {
+suspend inline fun HttpClient.postA(url: String, builder: HttpRequestBuilder.() -> Unit = {}): HttpResponse {
return post(url) {
pwAuth()
builder(this)
@@ -451,7 +452,7 @@ inline suspend fun HttpClient.postA(url: String, builder: HttpRequestBuilder.()
}
/** Auto auth patch request */
-inline suspend fun HttpClient.patchA(url: String, builder: HttpRequestBuilder.() -> Unit = {}): HttpResponse {
+suspend inline fun HttpClient.patchA(url: String, builder: HttpRequestBuilder.() -> Unit = {}): HttpResponse {
return patch(url) {
pwAuth()
builder(this)
@@ -459,7 +460,7 @@ inline suspend fun HttpClient.patchA(url: String, builder: HttpRequestBuilder.()
}
/** Auto auth delete request */
-inline suspend fun HttpClient.deleteA(url: String, builder: HttpRequestBuilder.() -> Unit = {}): HttpResponse {
+suspend inline fun HttpClient.deleteA(url: String, builder: HttpRequestBuilder.() -> Unit = {}): HttpResponse {
return delete(url) {
pwAuth()
builder(this)
@@ -483,7 +484,7 @@ fun HttpRequestBuilder.pwAuth(username: String? = null) {
fun randBytes(lenght: Int): ByteArray {
val bytes = ByteArray(lenght)
- kotlin.random.Random.nextBytes(bytes)
+ Random.nextBytes(bytes)
return bytes
}
diff --git a/bank/src/test/kotlin/routines.kt b/bank/src/test/kotlin/routines.kt
index 6618b157..c0c10c54 100644
--- a/bank/src/test/kotlin/routines.kt
+++ b/bank/src/test/kotlin/routines.kt
@@ -17,15 +17,20 @@
* <http://www.gnu.org/licenses/>
*/
-import tech.libeufin.bank.*
-import tech.libeufin.common.*
-import io.ktor.client.statement.HttpResponse
-import io.ktor.server.testing.ApplicationTestBuilder
import io.ktor.client.request.*
+import io.ktor.client.statement.*
import io.ktor.http.*
-import kotlin.test.*
-import kotlinx.coroutines.*
-import kotlinx.serialization.json.*
+import io.ktor.server.testing.*
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+import kotlinx.serialization.json.JsonObject
+import tech.libeufin.bank.BankAccountCreateWithdrawalResponse
+import tech.libeufin.bank.WithdrawalStatus
+import tech.libeufin.common.TalerAmount
+import tech.libeufin.common.TalerErrorCode
+import tech.libeufin.common.json
+import kotlin.test.assertEquals
// Test endpoint is correctly authenticated
suspend fun ApplicationTestBuilder.authRoutine(
@@ -80,7 +85,7 @@ suspend fun ApplicationTestBuilder.authRoutine(
}
}
-inline suspend fun <reified B> ApplicationTestBuilder.historyRoutine(
+suspend inline fun <reified B> ApplicationTestBuilder.historyRoutine(
url: String,
crossinline ids: (B) -> List<Long>,
registered: List<suspend () -> Unit>,
@@ -201,7 +206,7 @@ inline suspend fun <reified B> ApplicationTestBuilder.historyRoutine(
history("delta=-10&start=${id-4}").assertHistory(10)
}
-inline suspend fun <reified B> ApplicationTestBuilder.statusRoutine(
+suspend inline fun <reified B> ApplicationTestBuilder.statusRoutine(
url: String,
crossinline status: (B) -> WithdrawalStatus
) {