summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntoine A <>2023-12-16 17:52:21 +0000
committerAntoine A <>2023-12-16 17:52:21 +0000
commite6d6a3e447bc2fa9f87f86cf8086b21a0e1a6d41 (patch)
tree27843a622d5d7a8881824967919ebde3daa6753d
parent106f680ead96946a5f53e038ed29f46bd1e127ce (diff)
downloadlibeufin-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.kt2
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/CoreBankApi.kt44
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/db/Database.kt1
-rw-r--r--util/src/main/kotlin/DB.kt2
-rw-r--r--util/src/main/kotlin/iban.kt2
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}"