diff options
author | Antoine A <> | 2023-12-16 17:52:21 +0000 |
---|---|---|
committer | Antoine A <> | 2023-12-16 17:52:21 +0000 |
commit | e6d6a3e447bc2fa9f87f86cf8086b21a0e1a6d41 (patch) | |
tree | 27843a622d5d7a8881824967919ebde3daa6753d | |
parent | 106f680ead96946a5f53e038ed29f46bd1e127ce (diff) | |
download | libeufin-e6d6a3e447bc2fa9f87f86cf8086b21a0e1a6d41.tar.gz libeufin-e6d6a3e447bc2fa9f87f86cf8086b21a0e1a6d41.tar.bz2 libeufin-e6d6a3e447bc2fa9f87f86cf8086b21a0e1a6d41.zip |
Retry account registration with random IBAN up to 5 times
-rw-r--r-- | bank/src/main/kotlin/tech/libeufin/bank/Constants.kt | 2 | ||||
-rw-r--r-- | bank/src/main/kotlin/tech/libeufin/bank/CoreBankApi.kt | 44 | ||||
-rw-r--r-- | bank/src/main/kotlin/tech/libeufin/bank/db/Database.kt | 1 | ||||
-rw-r--r-- | util/src/main/kotlin/DB.kt | 2 | ||||
-rw-r--r-- | util/src/main/kotlin/iban.kt | 2 |
5 files changed, 31 insertions, 20 deletions
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Constants.kt b/bank/src/main/kotlin/tech/libeufin/bank/Constants.kt index 465de572..5567e13c 100644 --- a/bank/src/main/kotlin/tech/libeufin/bank/Constants.kt +++ b/bank/src/main/kotlin/tech/libeufin/bank/Constants.kt @@ -34,12 +34,14 @@ val TOKEN_DEFAULT_DURATION: java.time.Duration = Duration.ofDays(1L) // Account val RESERVED_ACCOUNTS = setOf("admin", "bank") +const val IBAN_ALLOCATION_RETRY_COUNTER: Int = 5; // Security const val MAX_BODY_LENGTH: Long = 4 * 1024 // 4kB // DB const val MIN_VERSION: Int = 14 +const val SERIALIZATION_RETRY: Int = 10; // API version const val COREBANK_API_VERSION: String = "3:0:3" diff --git a/bank/src/main/kotlin/tech/libeufin/bank/CoreBankApi.kt b/bank/src/main/kotlin/tech/libeufin/bank/CoreBankApi.kt index 64d27490..33c98780 100644 --- a/bank/src/main/kotlin/tech/libeufin/bank/CoreBankApi.kt +++ b/bank/src/main/kotlin/tech/libeufin/bank/CoreBankApi.kt @@ -159,24 +159,34 @@ suspend fun createAccount(db: Database, ctx: BankConfig, req: RegisterAccountReq TalerErrorCode.END ) - val internalPayto = req.payto_uri ?: req.internal_payto_uri ?: IbanPayTo(genIbanPaytoUri()) + val reqPayto = req.payto_uri ?: req.internal_payto_uri val contactData = req.contact_data ?: req.challenge_contact_data - val res = db.account.create( - login = req.username, - name = req.name, - email = contactData?.email?.get(), - phone = contactData?.phone?.get(), - cashoutPayto = req.cashout_payto_uri, - password = req.password, - internalPaytoUri = internalPayto, - isPublic = req.is_public, - isTalerExchange = req.is_taler_exchange, - maxDebt = req.debit_threshold ?: ctx.defaultDebtLimit, - bonus = if (!req.is_taler_exchange) ctx.registrationBonus - else TalerAmount(0, 0, ctx.regionalCurrency), - checkPaytoIdempotent = req.internal_payto_uri != null - ) - return Pair(res, internalPayto) + var retry = if (reqPayto == null) IBAN_ALLOCATION_RETRY_COUNTER else 0 + + while (true) { + val internalPayto = reqPayto ?: IbanPayTo(genIbanPaytoUri()) + val res = db.account.create( + login = req.username, + name = req.name, + email = contactData?.email?.get(), + phone = contactData?.phone?.get(), + cashoutPayto = req.cashout_payto_uri, + password = req.password, + internalPaytoUri = internalPayto, + isPublic = req.is_public, + isTalerExchange = req.is_taler_exchange, + maxDebt = req.debit_threshold ?: ctx.defaultDebtLimit, + bonus = if (!req.is_taler_exchange) ctx.registrationBonus + else TalerAmount(0, 0, ctx.regionalCurrency), + checkPaytoIdempotent = req.internal_payto_uri != null + ) + // Retry with new IBAN + if (res == AccountCreationResult.PayToReuse && retry > 0) { + retry-- + continue + } + return Pair(res, internalPayto) + } } suspend fun patchAccount(db: Database, ctx: BankConfig, req: AccountReconfiguration, username: String, isAdmin: Boolean): AccountPatchResult { 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 9c783af2..be1dd340 100644 --- a/bank/src/main/kotlin/tech/libeufin/bank/db/Database.kt +++ b/bank/src/main/kotlin/tech/libeufin/bank/db/Database.kt @@ -38,7 +38,6 @@ import io.ktor.http.HttpStatusCode import net.taler.common.errorcodes.TalerErrorCode private val logger: Logger = LoggerFactory.getLogger("tech.libeufin.bank.Database") -private val SERIALIZATION_RETRY: Int = 10; /** * This error occurs in case the timestamp took by the bank for some diff --git a/util/src/main/kotlin/DB.kt b/util/src/main/kotlin/DB.kt index cf168539..13fe1b2b 100644 --- a/util/src/main/kotlin/DB.kt +++ b/util/src/main/kotlin/DB.kt @@ -168,7 +168,7 @@ fun PreparedStatement.executeUpdateViolation(): Boolean { return try { executeUpdateCheck() } catch (e: SQLException) { - logger.error(e.message) + logger.debug(e.message) if (e.sqlState == PSQLState.UNIQUE_VIOLATION.state) return false throw e // rethrowing, not to hide other types of errors. } diff --git a/util/src/main/kotlin/iban.kt b/util/src/main/kotlin/iban.kt index 5306915a..b1ce37d1 100644 --- a/util/src/main/kotlin/iban.kt +++ b/util/src/main/kotlin/iban.kt @@ -4,7 +4,7 @@ fun getIban(): String { val ccNoCheck = "131400" // DE00 val bban = (0..10).map { (0..9).random() - }.joinToString("") // 4 digits BBAN. + }.joinToString("") // 10 digits account number var checkDigits: String = "98".toBigInteger().minus("$bban$ccNoCheck".toBigInteger().mod("97".toBigInteger())).toString() if (checkDigits.length == 1) { checkDigits = "0${checkDigits}" |