libeufin

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

commit 0684a2c0097bbaef65f569d8dae14fdb4a1aa965
parent 55006bcb8c3f4fb8986fb93deaa0e2213eeb4832
Author: Antoine A <>
Date:   Fri,  5 Jan 2024 12:33:54 +0000

Improve package hierarchy

Diffstat:
Dbank/src/main/kotlin/tech/libeufin/bank/Authentication.kt | 189-------------------------------------------------------------------------------
Mbank/src/main/kotlin/tech/libeufin/bank/BankIntegrationApi.kt | 3++-
Mbank/src/main/kotlin/tech/libeufin/bank/ConversionApi.kt | 4+++-
Mbank/src/main/kotlin/tech/libeufin/bank/CoreBankApi.kt | 12+++++++-----
Mbank/src/main/kotlin/tech/libeufin/bank/Main.kt | 3++-
Mbank/src/main/kotlin/tech/libeufin/bank/RevenueApi.kt | 2++
Mbank/src/main/kotlin/tech/libeufin/bank/WireGatewayApi.kt | 4+++-
Abank/src/main/kotlin/tech/libeufin/bank/auth/auth.kt | 191+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mbank/src/main/kotlin/tech/libeufin/bank/db/AccountDAO.kt | 3++-
Mbank/src/main/kotlin/tech/libeufin/bank/db/CashoutDAO.kt | 3++-
Mbank/src/main/kotlin/tech/libeufin/bank/db/ConversionDAO.kt | 3++-
Mbank/src/main/kotlin/tech/libeufin/bank/db/Database.kt | 3++-
Mbank/src/main/kotlin/tech/libeufin/bank/db/ExchangeDAO.kt | 3++-
Mbank/src/main/kotlin/tech/libeufin/bank/db/NotificationWatcher.kt | 3++-
Mbank/src/main/kotlin/tech/libeufin/bank/db/TokenDAO.kt | 3++-
Mbank/src/main/kotlin/tech/libeufin/bank/db/TransactionDAO.kt | 3++-
Mbank/src/main/kotlin/tech/libeufin/bank/db/WithdrawalDAO.kt | 3++-
Mbank/src/main/kotlin/tech/libeufin/bank/helpers.kt | 4+++-
Mbank/src/test/kotlin/AmountTest.kt | 5+++--
Mbank/src/test/kotlin/BankIntegrationApiTest.kt | 1+
Mbank/src/test/kotlin/CoreBankApiTest.kt | 1+
Mbank/src/test/kotlin/DatabaseTest.kt | 2+-
Mbank/src/test/kotlin/helpers.kt | 3++-
Mintegration/test/IntegrationTest.kt | 2+-
24 files changed, 240 insertions(+), 213 deletions(-)

diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Authentication.kt b/bank/src/main/kotlin/tech/libeufin/bank/Authentication.kt @@ -1,188 +0,0 @@ -/* - * This file is part of LibEuFin. - * Copyright (C) 2023 Stanisci and Dold. - - * LibEuFin is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation; either version 3, or - * (at your option) any later version. - - * LibEuFin is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General - * Public License for more details. - - * You should have received a copy of the GNU Affero General Public - * License along with LibEuFin; see the file COPYING. If not, see - * <http://www.gnu.org/licenses/> - */ -package tech.libeufin.bank - -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 net.taler.common.errorcodes.TalerErrorCode -import net.taler.wallet.crypto.Base32Crockford -import org.slf4j.Logger -import org.slf4j.LoggerFactory -import tech.libeufin.bank.AccountDAO.* -import tech.libeufin.util.* - -private val logger: Logger = LoggerFactory.getLogger("tech.libeufin.bank.Authentication") - -/** Used to store if the currenly authenticated user 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"); - -/** Get username of the request account */ -val ApplicationCall.username: String get() = expectParameter("USERNAME") -/** Get username of the request account */ -val PipelineContext<Unit, ApplicationCall>.username: String get() = call.username - -/** Check if current auth account is admin */ -val ApplicationCall.isAdmin: Boolean get() = attributes.getOrNull(AUTH_IS_ADMIN) ?: false -/** Check if current auth account is admin */ -val PipelineContext<Unit, ApplicationCall>.isAdmin: Boolean get() = call.isAdmin - -/** Check auth token used for authentification */ -val ApplicationCall.authToken: ByteArray? get() = attributes.getOrNull(AUTH_TOKEN) - -/** - * Create an admin authenticated route for [scope]. - * - * If [enforce], only admin can access this route. - * - * You can check is the currently authenticated user is admin using [isAdmin]. - **/ -fun Route.authAdmin(db: Database, scope: TokenScope, enforce: Boolean = true, callback: Route.() -> Unit): Route = - intercept(callback) { - if (enforce) { - val login = context.authenticateBankRequest(db, scope) - if (login != "admin") { - throw unauthorized("Only administrator allowed") - } - context.attributes.put(AUTH_IS_ADMIN, true) - } else { - val login = try { - context.authenticateBankRequest(db, scope) - } catch (e: Exception) { - null - } - context.attributes.put(AUTH_IS_ADMIN, login == "admin") - } - } - - -/** - * Create an authenticated route for [scope]. - * - * If [allowAdmin], admin is allowed to auth for any user. - * If [requireAdmin], only admin can access this route. - * - * You can check is the currently authenticated user is admin using [isAdmin]. - **/ -fun Route.auth(db: Database, scope: TokenScope, allowAdmin: Boolean = false, requireAdmin: Boolean = false, callback: Route.() -> Unit): Route = - intercept(callback) { - val authLogin = context.authenticateBankRequest(db, scope) - if (requireAdmin && authLogin != "admin") { - if (authLogin != "admin") { - throw unauthorized("Only administrator allowed") - } - } else { - val hasRight = authLogin == username || (allowAdmin && authLogin == "admin"); - if (!hasRight) { - throw unauthorized("Customer $authLogin have no right on $username account") - } - } - context.attributes.put(AUTH_IS_ADMIN, authLogin == "admin") - } - -/** - * Authenticate an HTTP request for [requiredScope] according to the scheme that is mentioned - * in the Authorization header. - * The allowed schemes are either 'Basic' or 'Bearer'. - * - * Returns the authenticated customer login. - */ -private suspend fun ApplicationCall.authenticateBankRequest(db: Database, requiredScope: TokenScope): String { - val header = request.headers["Authorization"] - - // Basic auth challenge - if (header == null) { - response.header(HttpHeaders.WWWAuthenticate, "Basic") - throw unauthorized( - "Authorization header not found", - TalerErrorCode.GENERIC_PARAMETER_MISSING - ) - } - - // Parse header - val (scheme, content) = header.splitOnce(" ") ?: throw badRequest( - "Authorization is invalid", - TalerErrorCode.GENERIC_HTTP_HEADERS_MALFORMED - ) - return when (scheme) { - "Basic" -> doBasicAuth(db, content) - "Bearer" -> doTokenAuth(db, content, requiredScope) - else -> throw unauthorized("Authorization method wrong or not supported") - } -} - -/** - * Performs the HTTP Basic Authentication. - * - * Returns the authenticated customer login - */ -private suspend fun doBasicAuth(db: Database, encoded: String): String { - val decoded = String(base64ToBytes(encoded), Charsets.UTF_8) - val (login, plainPassword) = decoded.splitOnce(":") ?: throw badRequest( - "Malformed Basic auth credentials found in the Authorization header", - TalerErrorCode.GENERIC_HTTP_HEADERS_MALFORMED - ) - val hash = db.account.passwordHash(login) ?: throw unauthorized("Unknown account") - if (!CryptoUtil.checkpw(plainPassword, hash)) throw unauthorized("Bad password") - return login -} - -/** - * Performs the secret-token HTTP Bearer Authentication. - * - * Returns the authenticated customer login - */ -private suspend fun ApplicationCall.doTokenAuth( - db: Database, - bearer: String, - requiredScope: TokenScope, -): String { - if (!bearer.startsWith("secret-token:")) throw badRequest( - "Bearer token malformed", - TalerErrorCode.GENERIC_HTTP_HEADERS_MALFORMED - ) - val decoded = try { - Base32Crockford.decode(bearer.slice(13..bearer.length-1)) - } catch (e: Exception) { - throw badRequest( - e.message, TalerErrorCode.GENERIC_HTTP_HEADERS_MALFORMED - ) - } - val token: BearerToken = db.token.get(decoded) ?: throw unauthorized("Unknown token") - when { - token.expirationTime.isBefore(Instant.now()) - -> throw unauthorized("Expired auth token") - - token.scope == TokenScope.readonly && requiredScope == TokenScope.readwrite - -> throw unauthorized("Auth token has insufficient scope") - - !token.isRefreshable && requiredScope == TokenScope.refreshable - -> throw unauthorized("Unrefreshable token") - } - - attributes.put(AUTH_TOKEN, decoded) - - return token.login -} -\ No newline at end of file diff --git a/bank/src/main/kotlin/tech/libeufin/bank/BankIntegrationApi.kt b/bank/src/main/kotlin/tech/libeufin/bank/BankIntegrationApi.kt @@ -27,7 +27,8 @@ import io.ktor.server.response.* import io.ktor.server.routing.* import io.ktor.http.* import net.taler.common.errorcodes.TalerErrorCode -import tech.libeufin.bank.WithdrawalDAO.* +import tech.libeufin.bank.db.* +import tech.libeufin.bank.db.WithdrawalDAO.* import java.lang.AssertionError fun Routing.bankIntegrationApi(db: Database, ctx: BankConfig) { diff --git a/bank/src/main/kotlin/tech/libeufin/bank/ConversionApi.kt b/bank/src/main/kotlin/tech/libeufin/bank/ConversionApi.kt @@ -25,7 +25,9 @@ import io.ktor.server.response.* import io.ktor.server.routing.* import java.util.* import tech.libeufin.util.* -import tech.libeufin.bank.ConversionDAO.* +import tech.libeufin.bank.auth.* +import tech.libeufin.bank.db.ConversionDAO.* +import tech.libeufin.bank.db.* import net.taler.common.errorcodes.TalerErrorCode fun Routing.conversionApi(db: Database, ctx: BankConfig) = conditional(ctx.allowConversion) { diff --git a/bank/src/main/kotlin/tech/libeufin/bank/CoreBankApi.kt b/bank/src/main/kotlin/tech/libeufin/bank/CoreBankApi.kt @@ -35,11 +35,13 @@ import net.taler.common.errorcodes.TalerErrorCode import net.taler.wallet.crypto.Base32Crockford import org.slf4j.Logger import org.slf4j.LoggerFactory -import tech.libeufin.bank.AccountDAO.* -import tech.libeufin.bank.CashoutDAO.* -import tech.libeufin.bank.ExchangeDAO.* -import tech.libeufin.bank.TransactionDAO.* -import tech.libeufin.bank.WithdrawalDAO.* +import tech.libeufin.bank.auth.* +import tech.libeufin.bank.db.* +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.util.* private val logger: Logger = LoggerFactory.getLogger("tech.libeufin.bank.accountsMgmtHandlers") diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Main.kt b/bank/src/main/kotlin/tech/libeufin/bank/Main.kt @@ -54,7 +54,8 @@ import org.slf4j.Logger import org.slf4j.LoggerFactory import org.slf4j.event.Level import org.postgresql.util.PSQLState -import tech.libeufin.bank.AccountDAO.* +import tech.libeufin.bank.db.AccountDAO.* +import tech.libeufin.bank.db.* import tech.libeufin.util.* private val logger: Logger = LoggerFactory.getLogger("tech.libeufin.bank.Main") diff --git a/bank/src/main/kotlin/tech/libeufin/bank/RevenueApi.kt b/bank/src/main/kotlin/tech/libeufin/bank/RevenueApi.kt @@ -25,6 +25,8 @@ import io.ktor.server.response.* import io.ktor.server.routing.* import java.util.* import tech.libeufin.util.* +import tech.libeufin.bank.auth.* +import tech.libeufin.bank.db.* fun Routing.revenueApi(db: Database) { auth(db, TokenScope.readonly) { diff --git a/bank/src/main/kotlin/tech/libeufin/bank/WireGatewayApi.kt b/bank/src/main/kotlin/tech/libeufin/bank/WireGatewayApi.kt @@ -31,7 +31,9 @@ import java.time.Instant import net.taler.common.errorcodes.TalerErrorCode import org.slf4j.Logger import org.slf4j.LoggerFactory -import tech.libeufin.bank.ExchangeDAO.* +import tech.libeufin.bank.db.* +import tech.libeufin.bank.db.ExchangeDAO.* +import tech.libeufin.bank.auth.* private val logger: Logger = LoggerFactory.getLogger("tech.libeufin.nexus") diff --git a/bank/src/main/kotlin/tech/libeufin/bank/auth/auth.kt b/bank/src/main/kotlin/tech/libeufin/bank/auth/auth.kt @@ -0,0 +1,190 @@ +/* + * This file is part of LibEuFin. + * Copyright (C) 2023 Stanisci and Dold. + + * LibEuFin is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3, or + * (at your option) any later version. + + * LibEuFin is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + + * You should have received a copy of the GNU Affero General Public + * License along with LibEuFin; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/> + */ +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 net.taler.common.errorcodes.TalerErrorCode +import net.taler.wallet.crypto.Base32Crockford +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import tech.libeufin.bank.db.AccountDAO.* +import tech.libeufin.bank.db.* +import tech.libeufin.bank.* +import tech.libeufin.util.* + +private val logger: Logger = LoggerFactory.getLogger("tech.libeufin.bank.Authentication") + +/** Used to store if the currenly authenticated user 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"); + +/** Get username of the request account */ +val ApplicationCall.username: String get() = expectParameter("USERNAME") +/** Get username of the request account */ +val PipelineContext<Unit, ApplicationCall>.username: String get() = call.username + +/** Check if current auth account is admin */ +val ApplicationCall.isAdmin: Boolean get() = attributes.getOrNull(AUTH_IS_ADMIN) ?: false +/** Check if current auth account is admin */ +val PipelineContext<Unit, ApplicationCall>.isAdmin: Boolean get() = call.isAdmin + +/** Check auth token used for authentification */ +val ApplicationCall.authToken: ByteArray? get() = attributes.getOrNull(AUTH_TOKEN) + +/** + * Create an admin authenticated route for [scope]. + * + * If [enforce], only admin can access this route. + * + * You can check is the currently authenticated user is admin using [isAdmin]. + **/ +fun Route.authAdmin(db: Database, scope: TokenScope, enforce: Boolean = true, callback: Route.() -> Unit): Route = + intercept(callback) { + if (enforce) { + val login = context.authenticateBankRequest(db, scope) + if (login != "admin") { + throw unauthorized("Only administrator allowed") + } + context.attributes.put(AUTH_IS_ADMIN, true) + } else { + val login = try { + context.authenticateBankRequest(db, scope) + } catch (e: Exception) { + null + } + context.attributes.put(AUTH_IS_ADMIN, login == "admin") + } + } + + +/** + * Create an authenticated route for [scope]. + * + * If [allowAdmin], admin is allowed to auth for any user. + * If [requireAdmin], only admin can access this route. + * + * You can check is the currently authenticated user is admin using [isAdmin]. + **/ +fun Route.auth(db: Database, scope: TokenScope, allowAdmin: Boolean = false, requireAdmin: Boolean = false, callback: Route.() -> Unit): Route = + intercept(callback) { + val authLogin = context.authenticateBankRequest(db, scope) + if (requireAdmin && authLogin != "admin") { + if (authLogin != "admin") { + throw unauthorized("Only administrator allowed") + } + } else { + val hasRight = authLogin == username || (allowAdmin && authLogin == "admin"); + if (!hasRight) { + throw unauthorized("Customer $authLogin have no right on $username account") + } + } + context.attributes.put(AUTH_IS_ADMIN, authLogin == "admin") + } + +/** + * Authenticate an HTTP request for [requiredScope] according to the scheme that is mentioned + * in the Authorization header. + * The allowed schemes are either 'Basic' or 'Bearer'. + * + * Returns the authenticated customer login. + */ +private suspend fun ApplicationCall.authenticateBankRequest(db: Database, requiredScope: TokenScope): String { + val header = request.headers["Authorization"] + + // Basic auth challenge + if (header == null) { + response.header(HttpHeaders.WWWAuthenticate, "Basic") + throw unauthorized( + "Authorization header not found", + TalerErrorCode.GENERIC_PARAMETER_MISSING + ) + } + + // Parse header + val (scheme, content) = header.splitOnce(" ") ?: throw badRequest( + "Authorization is invalid", + TalerErrorCode.GENERIC_HTTP_HEADERS_MALFORMED + ) + return when (scheme) { + "Basic" -> doBasicAuth(db, content) + "Bearer" -> doTokenAuth(db, content, requiredScope) + else -> throw unauthorized("Authorization method wrong or not supported") + } +} + +/** + * Performs the HTTP Basic Authentication. + * + * Returns the authenticated customer login + */ +private suspend fun doBasicAuth(db: Database, encoded: String): String { + val decoded = String(base64ToBytes(encoded), Charsets.UTF_8) + val (login, plainPassword) = decoded.splitOnce(":") ?: throw badRequest( + "Malformed Basic auth credentials found in the Authorization header", + TalerErrorCode.GENERIC_HTTP_HEADERS_MALFORMED + ) + val hash = db.account.passwordHash(login) ?: throw unauthorized("Unknown account") + if (!CryptoUtil.checkpw(plainPassword, hash)) throw unauthorized("Bad password") + return login +} + +/** + * Performs the secret-token HTTP Bearer Authentication. + * + * Returns the authenticated customer login + */ +private suspend fun ApplicationCall.doTokenAuth( + db: Database, + bearer: String, + requiredScope: TokenScope, +): String { + if (!bearer.startsWith("secret-token:")) throw badRequest( + "Bearer token malformed", + TalerErrorCode.GENERIC_HTTP_HEADERS_MALFORMED + ) + val decoded = try { + Base32Crockford.decode(bearer.slice(13..bearer.length-1)) + } catch (e: Exception) { + throw badRequest( + e.message, TalerErrorCode.GENERIC_HTTP_HEADERS_MALFORMED + ) + } + val token: BearerToken = db.token.get(decoded) ?: throw unauthorized("Unknown token") + when { + token.expirationTime.isBefore(Instant.now()) + -> throw unauthorized("Expired auth token") + + token.scope == TokenScope.readonly && requiredScope == TokenScope.readwrite + -> throw unauthorized("Auth token has insufficient scope") + + !token.isRefreshable && requiredScope == TokenScope.refreshable + -> throw unauthorized("Unrefreshable token") + } + + attributes.put(AUTH_TOKEN, decoded) + + return token.login +} +\ No newline at end of file diff --git a/bank/src/main/kotlin/tech/libeufin/bank/db/AccountDAO.kt b/bank/src/main/kotlin/tech/libeufin/bank/db/AccountDAO.kt @@ -17,11 +17,12 @@ * <http://www.gnu.org/licenses/> */ -package tech.libeufin.bank +package tech.libeufin.bank.db import tech.libeufin.util.* import java.time.* import java.sql.Types +import tech.libeufin.bank.* /** Data access logic for accounts */ class AccountDAO(private val db: Database) { diff --git a/bank/src/main/kotlin/tech/libeufin/bank/db/CashoutDAO.kt b/bank/src/main/kotlin/tech/libeufin/bank/db/CashoutDAO.kt @@ -17,12 +17,13 @@ * <http://www.gnu.org/licenses/> */ -package tech.libeufin.bank +package tech.libeufin.bank.db import java.time.Duration import java.time.Instant import java.util.concurrent.TimeUnit import tech.libeufin.util.* +import tech.libeufin.bank.* /** 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 @@ -17,10 +17,11 @@ * <http://www.gnu.org/licenses/> */ -package tech.libeufin.bank +package tech.libeufin.bank.db import tech.libeufin.util.* import tech.libeufin.bank.* +import tech.libeufin.bank.* /** Data access logic for conversion */ class ConversionDAO(private val db: Database) { diff --git a/bank/src/main/kotlin/tech/libeufin/bank/db/Database.kt b/bank/src/main/kotlin/tech/libeufin/bank/db/Database.kt @@ -17,7 +17,7 @@ * <http://www.gnu.org/licenses/> */ -package tech.libeufin.bank +package tech.libeufin.bank.db import org.postgresql.jdbc.PgConnection import org.postgresql.ds.PGSimpleDataSource @@ -36,6 +36,7 @@ import com.zaxxer.hikari.* import tech.libeufin.util.* import io.ktor.http.HttpStatusCode import net.taler.common.errorcodes.TalerErrorCode +import tech.libeufin.bank.* private val logger: Logger = LoggerFactory.getLogger("tech.libeufin.bank.Database") diff --git a/bank/src/main/kotlin/tech/libeufin/bank/db/ExchangeDAO.kt b/bank/src/main/kotlin/tech/libeufin/bank/db/ExchangeDAO.kt @@ -17,13 +17,14 @@ * <http://www.gnu.org/licenses/> */ -package tech.libeufin.bank +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.util.* +import tech.libeufin.bank.* /** 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 @@ -17,7 +17,7 @@ * <http://www.gnu.org/licenses/> */ -package tech.libeufin.bank +package tech.libeufin.bank.db import java.util.UUID import java.util.concurrent.ConcurrentHashMap @@ -27,6 +27,7 @@ import org.postgresql.ds.PGSimpleDataSource import org.slf4j.Logger import org.slf4j.LoggerFactory import tech.libeufin.util.* +import tech.libeufin.bank.* private val logger: Logger = LoggerFactory.getLogger("tech.libeufin.util.NotificationWatcher") diff --git a/bank/src/main/kotlin/tech/libeufin/bank/db/TokenDAO.kt b/bank/src/main/kotlin/tech/libeufin/bank/db/TokenDAO.kt @@ -17,10 +17,11 @@ * <http://www.gnu.org/licenses/> */ -package tech.libeufin.bank +package tech.libeufin.bank.db import tech.libeufin.util.* 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 @@ -17,13 +17,14 @@ * <http://www.gnu.org/licenses/> */ -package tech.libeufin.bank +package tech.libeufin.bank.db import org.slf4j.Logger import org.slf4j.LoggerFactory import tech.libeufin.util.* import java.time.* import java.sql.Types +import tech.libeufin.bank.* private val logger: Logger = LoggerFactory.getLogger("tech.libeufin.util.TransactionDAO") diff --git a/bank/src/main/kotlin/tech/libeufin/bank/db/WithdrawalDAO.kt b/bank/src/main/kotlin/tech/libeufin/bank/db/WithdrawalDAO.kt @@ -17,7 +17,7 @@ * <http://www.gnu.org/licenses/> */ -package tech.libeufin.bank +package tech.libeufin.bank.db import java.util.UUID import java.time.Instant @@ -26,6 +26,7 @@ import java.util.concurrent.TimeUnit import tech.libeufin.util.* import kotlinx.coroutines.flow.* import kotlinx.coroutines.* +import tech.libeufin.bank.* /** Data access logic for withdrawal operations */ class WithdrawalDAO(private val db: Database) { diff --git a/bank/src/main/kotlin/tech/libeufin/bank/helpers.kt b/bank/src/main/kotlin/tech/libeufin/bank/helpers.kt @@ -36,8 +36,10 @@ import java.util.* import net.taler.common.errorcodes.TalerErrorCode import org.slf4j.Logger import org.slf4j.LoggerFactory -import tech.libeufin.bank.AccountDAO.* import tech.libeufin.util.* +import tech.libeufin.bank.db.* +import tech.libeufin.bank.db.AccountDAO.* +import tech.libeufin.bank.auth.* private val logger: Logger = LoggerFactory.getLogger("tech.libeufin.bank.helpers") diff --git a/bank/src/test/kotlin/AmountTest.kt b/bank/src/test/kotlin/AmountTest.kt @@ -23,8 +23,9 @@ import kotlin.test.* import org.junit.Test import org.postgresql.jdbc.PgConnection import tech.libeufin.bank.* -import tech.libeufin.bank.TransactionDAO.* -import tech.libeufin.bank.WithdrawalDAO.* +import tech.libeufin.bank.db.* +import tech.libeufin.bank.db.TransactionDAO.* +import tech.libeufin.bank.db.WithdrawalDAO.* import tech.libeufin.util.* class AmountTest { diff --git a/bank/src/test/kotlin/BankIntegrationApiTest.kt b/bank/src/test/kotlin/BankIntegrationApiTest.kt @@ -29,6 +29,7 @@ import kotlinx.serialization.json.* import net.taler.common.errorcodes.TalerErrorCode import org.junit.Test import tech.libeufin.bank.* +import tech.libeufin.bank.db.* import tech.libeufin.util.* class BankIntegrationApiTest { diff --git a/bank/src/test/kotlin/CoreBankApiTest.kt b/bank/src/test/kotlin/CoreBankApiTest.kt @@ -34,6 +34,7 @@ import net.taler.common.errorcodes.TalerErrorCode import net.taler.wallet.crypto.Base32Crockford import org.junit.Test import tech.libeufin.bank.* +import tech.libeufin.bank.db.* import tech.libeufin.util.* class CoreBankConfigTest { diff --git a/bank/src/test/kotlin/DatabaseTest.kt b/bank/src/test/kotlin/DatabaseTest.kt @@ -29,7 +29,7 @@ import kotlin.test.* import kotlinx.coroutines.* import org.junit.Test import tech.libeufin.bank.* -import tech.libeufin.bank.AccountDAO.* +import tech.libeufin.bank.db.AccountDAO.* import tech.libeufin.util.* class DatabaseTest { diff --git a/bank/src/test/kotlin/helpers.kt b/bank/src/test/kotlin/helpers.kt @@ -31,7 +31,8 @@ import kotlinx.serialization.json.* import net.taler.common.errorcodes.TalerErrorCode import net.taler.wallet.crypto.Base32Crockford import tech.libeufin.bank.* -import tech.libeufin.bank.AccountDAO.* +import tech.libeufin.bank.db.* +import tech.libeufin.bank.db.AccountDAO.* import tech.libeufin.util.* /* ----- Setup ----- */ diff --git a/integration/test/IntegrationTest.kt b/integration/test/IntegrationTest.kt @@ -23,7 +23,7 @@ import tech.libeufin.bank.TalerAmount as BankAmount import tech.libeufin.nexus.* import tech.libeufin.nexus.Database as NexusDb import tech.libeufin.nexus.TalerAmount as NexusAmount -import tech.libeufin.bank.AccountDAO.* +import tech.libeufin.bank.db.AccountDAO.* import tech.libeufin.util.* import java.io.File import java.time.Instant