libeufin

Integration and sandbox testing for FinTech APIs and data formats
Log | Files | Refs | Submodules | README | LICENSE

commit 736c3998648ad249577f8930b616e1f27647f938
parent e34e42758c4159d5dfeb8f2efad4b170e2425e09
Author: Antoine A <>
Date:   Mon, 27 Nov 2023 14:20:26 +0000

Improve config and HTTP query parsing

Diffstat:
Mbank/conf/test_restrict.conf | 2+-
Mbank/src/main/kotlin/tech/libeufin/bank/Config.kt | 8++++----
Mbank/src/main/kotlin/tech/libeufin/bank/CoreBankApi.kt | 8++++----
Mbank/src/main/kotlin/tech/libeufin/bank/Params.kt | 16+++++++++++-----
Mbank/src/test/kotlin/CoreBankApiTest.kt | 3+++
Mcontrib/libeufin-bank.conf | 22+++++++++++-----------
6 files changed, 34 insertions(+), 25 deletions(-)

diff --git a/bank/conf/test_restrict.conf b/bank/conf/test_restrict.conf @@ -2,7 +2,7 @@ CURRENCY = KUDOS DEFAULT_CUSTOMER_DEBT_LIMIT = KUDOS:100 DEFAULT_ADMIN_DEBT_LIMIT = KUDOS:10000 -restrict_registration = YES +ALLOW_REGISTRATION = NO [libeufin-bankdb-postgres] SQL_DIR = $DATADIR/sql/ diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Config.kt b/bank/src/main/kotlin/tech/libeufin/bank/Config.kt @@ -36,8 +36,8 @@ private val BANK_CONFIG_SOURCE = ConfigSource("libeufin-bank", "libeufin-bank") data class BankConfig( val regionalCurrency: String, val regionalCurrencySpec: CurrencySpecification, - val restrictRegistration: Boolean, - val restrictAccountDeletion: Boolean, + val allowRegistration: Boolean, + val allowAccountDeletion: Boolean, val defaultCustomerDebtLimit: TalerAmount, val defaultAdminDebtLimit: TalerAmount, val registrationBonus: TalerAmount, @@ -108,14 +108,14 @@ fun TalerConfig.loadBankConfig(): BankConfig = catchError { BankConfig( regionalCurrency = regionalCurrency, regionalCurrencySpec = currencySpecificationFor(regionalCurrency), - restrictRegistration = lookupBoolean("libeufin-bank", "restrict_registration") ?: false, + allowRegistration = lookupBoolean("libeufin-bank", "allow_registration") ?: false, + allowAccountDeletion = lookupBoolean("libeufin-bank", "allow_account_deletion") ?: false, defaultCustomerDebtLimit = requireAmount("libeufin-bank", "default_customer_debt_limit", regionalCurrency), registrationBonus = amount("libeufin-bank", "registration_bonus", regionalCurrency) ?: TalerAmount(0, 0, regionalCurrency), suggestedWithdrawalExchange = lookupString("libeufin-bank", "suggested_withdrawal_exchange"), defaultAdminDebtLimit = requireAmount("libeufin-bank", "default_admin_debt_limit", regionalCurrency), spaCaptchaURL = lookupString("libeufin-bank", "spa_captcha_url"), spaPath = lookupPath("libeufin-bank", "spa"), - restrictAccountDeletion = lookupBoolean("libeufin-bank", "restrict_account_deletion") ?: true, allowConversion = allowConversion, fiatCurrency = fiatCurrency, fiatCurrencySpec = fiatCurrencySpec, diff --git a/bank/src/main/kotlin/tech/libeufin/bank/CoreBankApi.kt b/bank/src/main/kotlin/tech/libeufin/bank/CoreBankApi.kt @@ -51,8 +51,8 @@ fun Routing.coreBankApi(db: Database, ctx: BankConfig) { currency = ctx.regionalCurrency, currency_specification = ctx.regionalCurrencySpec, allow_conversion = ctx.allowConversion, - allow_registrations = !ctx.restrictRegistration, - allow_deletions = !ctx.restrictAccountDeletion + allow_registrations = ctx.allowRegistration, + allow_deletions = ctx.allowAccountDeletion ) ) } @@ -137,7 +137,7 @@ private fun Routing.coreBankTokenApi(db: Database) { } private fun Routing.coreBankAccountsApi(db: Database, ctx: BankConfig) { - authAdmin(db, TokenScope.readwrite, ctx.restrictRegistration) { + authAdmin(db, TokenScope.readwrite, !ctx.allowRegistration) { post("/accounts") { val req = call.receive<RegisterAccountRequest>() // Prohibit reserved usernames: @@ -184,7 +184,7 @@ private fun Routing.coreBankAccountsApi(db: Database, ctx: BankConfig) { db, TokenScope.readwrite, allowAdmin = true, - requireAdmin = ctx.restrictAccountDeletion + requireAdmin = !ctx.allowAccountDeletion ) { delete("/accounts/{USERNAME}") { // Not deleting reserved names. diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Params.kt b/bank/src/main/kotlin/tech/libeufin/bank/Params.kt @@ -54,20 +54,26 @@ data class MonitorParams( val which: Int? ) { companion object { + val names = Timeframe.values().map { it.name } + val names_fmt = names.joinToString() fun extract(params: Parameters): MonitorParams { - val timeframe = Timeframe.valueOf(params["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) + } + val timeframe = Timeframe.valueOf(raw) val which = params.int("which") if (which != null) { val lastDayOfMonth = OffsetDateTime.now(ZoneOffset.UTC).with(TemporalAdjusters.lastDayOfMonth()).dayOfMonth when { timeframe == Timeframe.hour && (0 > which || which > 23) -> - throw badRequest("For hour timestamp param 'which' must be between 00 to 23") + throw badRequest("For hour timestamp param 'which' must be between 00 to 23", TalerErrorCode.GENERIC_PARAMETER_MALFORMED) timeframe == Timeframe.day && (1 > which || which > lastDayOfMonth) -> - throw badRequest("For day timestamp param 'which' must be between 1 to $lastDayOfMonth") + throw badRequest("For day timestamp param 'which' must be between 1 to $lastDayOfMonth", TalerErrorCode.GENERIC_PARAMETER_MALFORMED) timeframe == Timeframe.month && (1 > which || which > 12) -> - throw badRequest("For month timestamp param 'which' must be between 1 to 12") + throw badRequest("For month timestamp param 'which' must be between 1 to 12", TalerErrorCode.GENERIC_PARAMETER_MALFORMED) timeframe == Timeframe.year && (1 > which|| which > 9999) -> - throw badRequest("For year timestamp param 'which' must be between 0001 to 9999") + throw badRequest("For year timestamp param 'which' must be between 0001 to 9999", TalerErrorCode.GENERIC_PARAMETER_MALFORMED) else -> {} } } diff --git a/bank/src/test/kotlin/CoreBankApiTest.kt b/bank/src/test/kotlin/CoreBankApiTest.kt @@ -51,6 +51,9 @@ class CoreBankConfigTest { client.get("/monitor?timeframe=day&wich=25") { pwAuth("admin") }.assertOk() + client.get("/monitor?timeframe=day=wich=25") { + pwAuth("admin") + }.assertBadRequest() } } diff --git a/contrib/libeufin-bank.conf b/contrib/libeufin-bank.conf @@ -14,15 +14,22 @@ DEFAULT_ADMIN_DEBT_LIMIT = KUDOS:2000 # Value of the registration bonus for new users. REGISTRATION_BONUS = KUDOS:100 -# Restrict account registration to admin. -RESTRICT_REGISTRATION = no +# Allow account registration by anyone. +ALLOW_REGISTRATION = yes -# Restrict account deletion to admin. -RESTRICT_ACCOUNT_DELETION = no +# Allow an account to delete itself +ALLOW_ACCOUNT_DELETION = yes # Exchange that is suggested to wallets when withdrawing. SUGGESTED_WITHDRAWAL_EXCHANGE = https://exchange.demo.taler.net/ +# Where "libeufin-bank serve" serves its API +SERVE = tcp +PORT = 8080 + +# Path to spa files +SPA = $DATADIR/spa/ + # URL that wallets are redirected to when they need to confirm # a withdrawal. # The string {woid} is replaced with the withdrawal operation ID. @@ -30,13 +37,6 @@ SUGGESTED_WITHDRAWAL_EXCHANGE = https://exchange.demo.taler.net/ # or something similar? SPA_CAPTCHA_URL = https://bank.demo.taler.net/webui/#/operation/{woid} -# Where "libeufin-bank serve" serves its API -SERVE = tcp -PORT = 8080 - -# Path to spa files -spa = $DATADIR/spa/ - # Enable regional currency conversion ALLOW_CONVERSION = no