gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libeufin] branch master updated (46e4838f -> a917619a)


From: gnunet
Subject: [libeufin] branch master updated (46e4838f -> a917619a)
Date: Fri, 29 Sep 2023 10:51:19 +0200

This is an automated email from the git hooks/post-receive script.

ms pushed a change to branch master
in repository libeufin.

    from 46e4838f Stop using longs to manipulate time.
     new 677d30af Stop using amounts as strings.
     new a917619a Addressing FIXMEs.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../main/kotlin/tech/libeufin/bank/BankMessages.kt | 33 +++++----
 .../tech/libeufin/bank/CorebankApiHandlers.kt      | 57 +++++++--------
 .../src/main/kotlin/tech/libeufin/bank/Database.kt |  4 +-
 .../tech/libeufin/bank/IntegrationApiHandlers.kt   |  7 +-
 bank/src/main/kotlin/tech/libeufin/bank/Main.kt    | 19 ++---
 .../tech/libeufin/bank/WireGatewayApiHandlers.kt   | 16 ++---
 bank/src/main/kotlin/tech/libeufin/bank/helpers.kt |  3 +-
 bank/src/test/kotlin/JsonTest.kt                   |  6 ++
 bank/src/test/kotlin/TalerApiTest.kt               |  4 +-
 contrib/wallet-core                                |  2 +-
 util/src/main/kotlin/TalerErrorCode.kt             | 80 +++++++++++++++++-----
 11 files changed, 132 insertions(+), 99 deletions(-)

diff --git a/bank/src/main/kotlin/tech/libeufin/bank/BankMessages.kt 
b/bank/src/main/kotlin/tech/libeufin/bank/BankMessages.kt
index bf400026..aa399b53 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/BankMessages.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/BankMessages.kt
@@ -19,6 +19,7 @@
 
 package tech.libeufin.bank
 
+import CreditDebitIndicator
 import io.ktor.http.*
 import io.ktor.server.application.*
 import kotlinx.serialization.Serializable
@@ -30,12 +31,10 @@ import java.util.*
 /**
  * Allowed lengths for fractional digits in amounts.
  */
-enum class FracDigits(howMany: Int) {
-    TWO(2),
-    EIGHT(8)
+enum class FracDigits {
+    TWO, EIGHT
 }
 
-
 /**
  * Timestamp containing the number of seconds since epoch.
  */
@@ -357,12 +356,14 @@ data class Config(
     val fiat_currency: String? = null
 )
 
+enum class CorebankCreditDebitInfo {
+    credit, debit
+}
+
 @Serializable
 data class Balance(
-    // FIXME: Should not be a string
-    val amount: String,
-    // FIXME: Should not be a string
-    val credit_debit_indicator: String,
+    val amount: TalerAmount,
+    val credit_debit_indicator: CorebankCreditDebitInfo,
 )
 
 /**
@@ -384,7 +385,7 @@ data class AccountData(
 @Serializable
 data class BankAccountTransactionCreate(
     val payto_uri: String,
-    val amount: String
+    val amount: TalerAmount
 )
 
 /* History element, either from GET /transactions/T_ID
@@ -393,7 +394,7 @@ data class BankAccountTransactionCreate(
 data class BankAccountTransactionInfo(
     val creditor_payto_uri: String,
     val debtor_payto_uri: String,
-    val amount: String,
+    val amount: TalerAmount,
     val direction: TransactionDirection,
     val subject: String,
     val row_id: Long, // is T_ID
@@ -409,7 +410,7 @@ data class BankAccountTransactionsResponse(
 // Taler withdrawal request.
 @Serializable
 data class BankAccountCreateWithdrawalRequest(
-    val amount: String
+    val amount: TalerAmount
 )
 
 // Taler withdrawal response.
@@ -422,7 +423,7 @@ data class BankAccountCreateWithdrawalResponse(
 // Taler withdrawal details response
 @Serializable
 data class BankAccountGetWithdrawalResponse(
-    val amount: String,
+    val amount: TalerAmount,
     val aborted: Boolean,
     val confirmation_done: Boolean,
     val selection_done: Boolean,
@@ -434,8 +435,6 @@ typealias ResourceName = String
 
 /**
  * Checks if the input Customer has the rights over ResourceName.
- * FIXME: myAuth() gives null on failures, but this gives false.
- * Should they return the same, for consistency?
  */
 fun ResourceName.canI(c: Customer, withAdmin: Boolean = true): Boolean {
     if (c.login == this) return true
@@ -504,7 +503,7 @@ data class BankWithdrawalOperationStatus(
 
     /* Amount that will be withdrawn with this operation
        (raw amount without fee considerations). */
-    val amount: String,
+    val amount: TalerAmount,
 
     /* Bank account of the customer that is withdrawing, as a
       ``payto`` URI. */
@@ -547,7 +546,7 @@ data class BankWithdrawalOperationPostResponse(
  */
 @Serializable
 data class AddIncomingRequest(
-    val amount: String,
+    val amount: TalerAmount,
     val reserve_pub: String,
     val debit_account: String
 )
@@ -585,7 +584,7 @@ data class IncomingReserveTransaction(
     val type: String = "RESERVE",
     val row_id: Long, // DB row ID of the payment.
     val date: TalerProtocolTimestamp,
-    val amount: String,
+    val amount: TalerAmount,
     val debit_account: String, // Payto of the sender.
     val reserve_pub: String
 )
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/CorebankApiHandlers.kt 
b/bank/src/main/kotlin/tech/libeufin/bank/CorebankApiHandlers.kt
index f4286e58..07056ed5 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/CorebankApiHandlers.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/CorebankApiHandlers.kt
@@ -33,7 +33,8 @@ fun Routing.accountsMgmtHandlers(db: Database, ctx: 
BankApplicationContext) {
             call.authenticateBankRequest(db, TokenScope.refreshable) ?: throw 
unauthorized("Authentication failed")
         val endpointOwner = call.maybeUriComponent("USERNAME")
         if (customer.login != endpointOwner) throw forbidden(
-            "User has no rights on this enpoint", TalerErrorCode.TALER_EC_END 
// FIXME: need generic forbidden
+            "User has no rights on this enpoint",
+            TalerErrorCode.TALER_EC_GENERIC_FORBIDDEN
         )
         val maybeAuthToken = call.getAuthToken()
         val req = call.receive<TokenRequest>()
@@ -93,16 +94,18 @@ fun Routing.accountsMgmtHandlers(db: Database, ctx: 
BankApplicationContext) {
         if (ctx.restrictRegistration) {
             val customer: Customer? = call.authenticateBankRequest(db, 
TokenScope.readwrite)
             if (customer == null || customer.login != "admin") throw 
LibeufinBankException(
-                httpStatus = HttpStatusCode.Unauthorized, talerError = 
TalerError(
-                    code = TalerErrorCode.TALER_EC_BANK_LOGIN_FAILED.code,
+                httpStatus = HttpStatusCode.Unauthorized,
+                talerError = TalerError(
+                    code = TalerErrorCode.TALER_EC_GENERIC_UNAUTHORIZED.code,
                     hint = "Either 'admin' not authenticated or an ordinary 
user tried this operation."
                 )
             )
         } // auth passed, proceed with activity.
         val req = call.receive<RegisterAccountRequest>() // Prohibit reserved 
usernames:
         if (req.username == "admin" || req.username == "bank") throw 
LibeufinBankException(
-            httpStatus = HttpStatusCode.Conflict, talerError = TalerError(
-                code = GENERIC_UNDEFINED, // FIXME: this waits GANA.
+            httpStatus = HttpStatusCode.Conflict,
+            talerError = TalerError(
+                code = 
TalerErrorCode.TALER_EC_BANK_RESERVED_USERNAME_CONFLICT.code,
                 hint = "Username '${req.username}' is reserved."
             )
         ) // Checking idempotency.
@@ -207,10 +210,11 @@ fun Routing.accountsMgmtHandlers(db: Database, ctx: 
BankApplicationContext) {
         val bankAccountData = db.bankAccountGetFromOwnerId(customerInternalId)
             ?: throw internalServerError("Customer '${c.login} had no bank 
account despite they are customer.'")
         val balance = Balance(
-            amount = bankAccountData.balance.toString(), 
credit_debit_indicator = if (bankAccountData.hasDebt) {
-                "debit"
+            amount = bankAccountData.balance ?: throw 
internalServerError("Account '${c.login}' lacks balance!"),
+            credit_debit_indicator = if (bankAccountData.hasDebt) {
+                CorebankCreditDebitInfo.debit
             } else {
-                "credit"
+                CorebankCreditDebitInfo.credit
             }
         )
         call.respond(
@@ -236,17 +240,16 @@ fun Routing.accountsMgmtHandlers(db: Database, ctx: 
BankApplicationContext) {
         val req = call.receive<BankAccountCreateWithdrawalRequest>() // 
Checking that the user has enough funds.
         val b = db.bankAccountGetFromOwnerId(c.expectRowId())
             ?: throw internalServerError("Customer '${c.login}' lacks bank 
account.")
-        val withdrawalAmount = parseTalerAmount(req.amount)
         if (!isBalanceEnough(
-                balance = b.expectBalance(), due = withdrawalAmount, maxDebt = 
b.maxDebt, hasBalanceDebt = b.hasDebt
+                balance = b.expectBalance(), due = req.amount, maxDebt = 
b.maxDebt, hasBalanceDebt = b.hasDebt
             )
         ) throw forbidden(
             hint = "Insufficient funds to withdraw with Taler",
-            talerErrorCode = TalerErrorCode.TALER_EC_NONE // FIXME: need EC.
+            talerErrorCode = TalerErrorCode.TALER_EC_BANK_UNALLOWED_DEBIT
         ) // Auth and funds passed, create the operation now!
         val opId = UUID.randomUUID()
         if (!db.talerWithdrawalCreate(
-                opId, b.expectRowId(), withdrawalAmount
+                opId, b.expectRowId(), req.amount
             )
         ) throw internalServerError("Bank failed at creating the withdraw 
operation.")
 
@@ -263,7 +266,7 @@ fun Routing.accountsMgmtHandlers(db: Database, ctx: 
BankApplicationContext) {
         val op = getWithdrawal(db, call.expectUriComponent("withdrawal_id"))
         call.respond(
             BankAccountGetWithdrawalResponse(
-                amount = op.amount.toString(),
+                amount = op.amount,
                 aborted = op.aborted,
                 confirmation_done = op.confirmationDone,
                 selection_done = op.selectionDone,
@@ -308,7 +311,7 @@ fun Routing.accountsMgmtHandlers(db: Database, ctx: 
BankApplicationContext) {
             WithdrawalConfirmationResult.BALANCE_INSUFFICIENT ->
                 throw conflict(
                 "Insufficient funds",
-                    TalerErrorCode.TALER_EC_END // FIXME: define EC for this.
+                    TalerErrorCode.TALER_EC_BANK_UNALLOWED_DEBIT
                 )
             WithdrawalConfirmationResult.OP_NOT_FOUND ->
                 /**
@@ -324,7 +327,8 @@ fun Routing.accountsMgmtHandlers(db: Database, ctx: 
BankApplicationContext) {
                  * bank account got removed before this confirmation.
                  */
                 throw conflict(
-                    hint = "Exchange to withdraw from not found", talerEc = 
TalerErrorCode.TALER_EC_END // FIXME
+                    hint = "Exchange to withdraw from not found",
+                    talerEc = TalerErrorCode.TALER_EC_BANK_UNKNOWN_ACCOUNT
                 )
 
             WithdrawalConfirmationResult.CONFLICT -> throw 
internalServerError("Bank didn't check for idempotency")
@@ -354,7 +358,7 @@ fun Routing.accountsMgmtHandlers(db: Database, ctx: 
BankApplicationContext) {
                     debtor_payto_uri = it.debtorPaytoUri,
                     creditor_payto_uri = it.creditorPaytoUri,
                     subject = it.subject,
-                    amount = it.amount.toString(),
+                    amount = it.amount,
                     direction = it.direction,
                     date = TalerProtocolTimestamp(it.transactionDate),
                     row_id = it.dbRowId ?: throw internalServerError(
@@ -380,29 +384,27 @@ fun Routing.accountsMgmtHandlers(db: Database, ctx: 
BankApplicationContext) {
             ?: throw internalServerError("Debtor database ID not found") // 
This performs already a SELECT on the bank account, like the wire transfer will 
do as well later!
         logger.info("creditor payto: $paytoWithoutParams")
         val creditorCustomerData = 
db.bankAccountGetFromInternalPayto(paytoWithoutParams) ?: throw notFound(
-            "Creditor account not found", TalerErrorCode.TALER_EC_END // 
FIXME: define this EC.
+            "Creditor account not found",
+            TalerErrorCode.TALER_EC_BANK_UNKNOWN_ACCOUNT
         )
-        val amount = parseTalerAmount(txData.amount)
-        if (amount.currency != ctx.currency) throw badRequest(
-            "Wrong currency: ${amount.currency}", talerErrorCode = 
TalerErrorCode.TALER_EC_GENERIC_CURRENCY_MISMATCH
+        if (txData.amount.currency != ctx.currency) throw badRequest(
+            "Wrong currency: ${txData.amount.currency}", talerErrorCode = 
TalerErrorCode.TALER_EC_GENERIC_CURRENCY_MISMATCH
         )
         val dbInstructions = BankInternalTransaction(
             debtorAccountId = debtorId,
             creditorAccountId = creditorCustomerData.owningCustomerId,
             subject = subject,
-            amount = amount,
+            amount = txData.amount,
             transactionDate = Instant.now()
         )
         val res = db.bankTransactionCreate(dbInstructions)
         when (res) {
             Database.BankTransactionResult.CONFLICT -> throw conflict(
-                "Insufficient funds", TalerErrorCode.TALER_EC_END // FIXME: 
need bank 'insufficient funds' EC.
+                "Insufficient funds",
+                TalerErrorCode.TALER_EC_BANK_UNALLOWED_DEBIT
             )
-
             Database.BankTransactionResult.NO_CREDITOR -> throw 
internalServerError("Creditor not found despite previous checks.")
-
             Database.BankTransactionResult.NO_DEBTOR -> throw 
internalServerError("Debtor not found despite the request was authenticated.")
-
             Database.BankTransactionResult.SUCCESS -> 
call.respond(HttpStatusCode.OK)
         }
         return@post
@@ -421,14 +423,15 @@ fun Routing.accountsMgmtHandlers(db: Database, ctx: 
BankApplicationContext) {
         }
         val customerRowId = c.dbRowId ?: throw 
internalServerError("Authenticated client lacks database entry")
         val tx = db.bankTransactionGetFromInternalId(txRowId) ?: throw 
notFound(
-            "Bank transaction '$tId' not found", TalerErrorCode.TALER_EC_NONE 
// FIXME: need def.
+            "Bank transaction '$tId' not found",
+            TalerErrorCode.TALER_EC_BANK_TRANSACTION_NOT_FOUND
         )
         val customerBankAccount = db.bankAccountGetFromOwnerId(customerRowId)
             ?: throw internalServerError("Customer '${c.login}' lacks bank 
account.")
         if (tx.bankAccountId != customerBankAccount.bankAccountId) throw 
forbidden("Client has no rights over the bank transaction: $tId") // auth and 
rights, respond.
         call.respond(
             BankAccountTransactionInfo(
-                amount = 
"${tx.amount.currency}:${tx.amount.value}.${tx.amount.frac}",
+                amount = tx.amount,
                 creditor_payto_uri = tx.creditorPaytoUri,
                 debtor_payto_uri = tx.debtorPaytoUri,
                 date = TalerProtocolTimestamp(tx.transactionDate),
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Database.kt 
b/bank/src/main/kotlin/tech/libeufin/bank/Database.kt
index c5f06190..07ae1bd3 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/Database.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/Database.kt
@@ -371,7 +371,6 @@ class Database(private val dbConfig: String, private val 
bankCurrency: String) {
             throw internalServerError(
                 "Do not pass a balance upon bank account creation, do a wire 
transfer instead."
             )
-        // FIXME: likely to be changed to only do internal_payto_uri
         val stmt = prepare("""
             INSERT INTO bank_accounts
               (internal_payto_uri
@@ -1116,6 +1115,8 @@ class Database(private val dbConfig: String, private val 
bankCurrency: String) {
         val txResult: BankTransactionResult,
         /**
          * bank transaction that backs this Taler transfer request.
+         * This is the debit transactions associated to the exchange
+         * bank account.
          */
         val txRowId: Long? = null
     )
@@ -1139,7 +1140,6 @@ class Database(private val dbConfig: String, private val 
bankCurrency: String) {
         endToEndId: String = "not used",
         ): TalerTransferCreationResult {
         reconnect()
-        // FIXME: future versions should return the exchange's latest bank 
transaction ID
         val stmt = prepare("""
             SELECT
               out_exchange_balance_insufficient
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/IntegrationApiHandlers.kt 
b/bank/src/main/kotlin/tech/libeufin/bank/IntegrationApiHandlers.kt
index 2933dfcd..e05d64fa 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/IntegrationApiHandlers.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/IntegrationApiHandlers.kt
@@ -40,11 +40,8 @@ fun Routing.talerIntegrationHandlers(db: Database, ctx: 
BankApplicationContext)
         val wopid = call.expectUriComponent("wopid")
         val op = getWithdrawal(db, wopid) // throws 404 if not found.
         val relatedBankAccount = 
db.bankAccountGetFromOwnerId(op.walletBankAccount)
-        if (relatedBankAccount == null) throw internalServerError("Bank has a 
withdrawal not related to any bank account.")
+            ?: throw internalServerError("Bank has a withdrawal not related to 
any bank account.")
         val suggestedExchange = ctx.suggestedWithdrawalExchange
-        val walletCustomer = 
db.customerGetFromRowId(relatedBankAccount.owningCustomerId)
-        if (walletCustomer == null)
-            throw internalServerError("Could not get the username that owns 
this withdrawal")
         val confirmUrl = if (ctx.spaCaptchaURL == null) null else
             getWithdrawalConfirmUrl(
                 baseUrl = ctx.spaCaptchaURL,
@@ -55,7 +52,7 @@ fun Routing.talerIntegrationHandlers(db: Database, ctx: 
BankApplicationContext)
                 aborted = op.aborted,
                 selection_done = op.selectionDone,
                 transfer_done = op.confirmationDone,
-                amount = op.amount.toString(),
+                amount = op.amount,
                 sender_wire = relatedBankAccount.internalPaytoUri,
                 suggested_exchange = suggestedExchange,
                 confirm_transfer_url = confirmUrl
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Main.kt 
b/bank/src/main/kotlin/tech/libeufin/bank/Main.kt
index a8ef3e81..307b29bd 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/Main.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/Main.kt
@@ -239,7 +239,7 @@ object TalerAmountSerializer : KSerializer<TalerAmount> {
         PrimitiveSerialDescriptor("TalerAmount", PrimitiveKind.STRING)
 
     override fun serialize(encoder: Encoder, value: TalerAmount) {
-        throw internalServerError("Encoding of TalerAmount not implemented.") 
// API doesn't require this.
+        encoder.encodeString(value.toString())
     }
 
     override fun deserialize(decoder: Decoder): TalerAmount {
@@ -275,7 +275,7 @@ val corebankDecompressionPlugin = 
createApplicationPlugin("RequestingBodyDecompr
                     logger.error("Deflated request failed to inflate: 
${e.message}")
                     throw badRequest(
                         hint = "Could not inflate request",
-                        talerErrorCode = TalerErrorCode.TALER_EC_END // FIXME: 
provide dedicated EC.
+                        talerErrorCode = 
TalerErrorCode.TALER_EC_GENERIC_COMPRESSION_INVALID
                     )
                 }
                 brc
@@ -284,7 +284,6 @@ val corebankDecompressionPlugin = 
createApplicationPlugin("RequestingBodyDecompr
     }
 }
 
-
 /**
  * Set up web server handlers for the Taler corebank API.
  */
@@ -309,6 +308,7 @@ fun Application.corebankWebApp(db: Database, ctx: 
BankApplicationContext) {
     install(IgnoreTrailingSlash)
     install(ContentNegotiation) {
         json(Json {
+            @OptIn(ExperimentalSerializationApi::class)
             explicitNulls = false
             encodeDefaults = true
             prettyPrint = true
@@ -443,17 +443,6 @@ fun durationFromPretty(s: String): Long {
     return durationUs
 }
 
-/**
- * FIXME: Introduce a datatype for this instead of using Long
- */
-fun TalerConfig.requireValueDuration(section: String, option: String): Long {
-    val durationStr = lookupValueString(section, option)
-    if (durationStr == null) {
-        throw TalerConfigError("expected duration for section $section, option 
$option, but config value is empty")
-    }
-    return durationFromPretty(durationStr)
-}
-
 fun TalerConfig.requireValueAmount(section: String, option: String, currency: 
String): TalerAmount {
     val amountStr = lookupValueString(section, option)
     if (amountStr == null) {
@@ -573,7 +562,7 @@ class ChangePw : CliktCommand("Change account password", 
name = "passwd") {
         val config = TalerConfig.load(this.configFile)
         val ctx = readBankApplicationContextFromConfig(config)
         val dbConnStr = config.requireValueString("libeufin-bankdb-postgres", 
"config")
-        val servePortLong = config.requireValueNumber("libeufin-bank", "port")
+        config.requireValueNumber("libeufin-bank", "port")
         val db = Database(dbConnStr, ctx.currency)
         if (!maybeCreateAdminAccount(db, ctx)) // logs provided by the helper
             exitProcess(1)
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/WireGatewayApiHandlers.kt 
b/bank/src/main/kotlin/tech/libeufin/bank/WireGatewayApiHandlers.kt
index b040883d..7e5d154c 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/WireGatewayApiHandlers.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/WireGatewayApiHandlers.kt
@@ -59,7 +59,7 @@ fun Routing.talerWireGatewayHandlers(db: Database, ctx: 
BankApplicationContext)
             resp.incoming_transactions.add(
                 IncomingReserveTransaction(
                     row_id = it.expectRowId(),
-                    amount = it.amount.toString(),
+                    amount = it.amount,
                     date = TalerProtocolTimestamp(it.transactionDate),
                     debit_account = it.debtorPaytoUri,
                     reserve_pub = it.subject
@@ -93,7 +93,7 @@ fun Routing.talerWireGatewayHandlers(db: Database, ctx: 
BankApplicationContext)
             }
             throw conflict(
                 hint = "request_uid used already",
-                talerEc = TalerErrorCode.TALER_EC_END // FIXME: need 
appropriate Taler EC.
+                talerEc = 
TalerErrorCode.TALER_EC_BANK_TRANSFER_REQUEST_UID_REUSED
             )
         }
         // Legitimate request, go on.
@@ -111,12 +111,12 @@ fun Routing.talerWireGatewayHandlers(db: Database, ctx: 
BankApplicationContext)
         if (dbRes.txResult == Database.BankTransactionResult.CONFLICT)
             throw conflict(
                 "Insufficient balance for exchange",
-                TalerErrorCode.TALER_EC_END // FIXME
+                TalerErrorCode.TALER_EC_BANK_UNALLOWED_DEBIT
             )
         if (dbRes.txResult == Database.BankTransactionResult.NO_CREDITOR)
             throw notFound(
                 "Creditor account was not found",
-                TalerErrorCode.TALER_EC_END // FIXME
+                TalerErrorCode.TALER_EC_BANK_UNKNOWN_ACCOUNT
             )
         val debitRowId = dbRes.txRowId
             ?: throw internalServerError("Database did not return the debit tx 
row ID")
@@ -133,9 +133,8 @@ fun Routing.talerWireGatewayHandlers(db: Database, ctx: 
BankApplicationContext)
         val c = call.authenticateBankRequest(db, TokenScope.readwrite) ?: 
throw unauthorized()
         if (!call.getResourceName("USERNAME").canI(c, withAdmin = false)) 
throw forbidden()
         val req = call.receive<AddIncomingRequest>()
-        val amount = parseTalerAmount(req.amount)
         val internalCurrency = ctx.currency
-        if (amount.currency != internalCurrency)
+        if (req.amount.currency != internalCurrency)
             throw badRequest(
                 "Currency mismatch",
                 TalerErrorCode.TALER_EC_GENERIC_CURRENCY_MISMATCH
@@ -155,7 +154,7 @@ fun Routing.talerWireGatewayHandlers(db: Database, ctx: 
BankApplicationContext)
         val txTimestamp = Instant.now()
         val op = BankInternalTransaction(
             debtorAccountId = walletAccount.expectRowId(),
-            amount = amount,
+            amount = req.amount,
             creditorAccountId = exchangeAccount.expectRowId(),
             transactionDate = txTimestamp,
             subject = req.reserve_pub
@@ -180,5 +179,4 @@ fun Routing.talerWireGatewayHandlers(db: Database, ctx: 
BankApplicationContext)
         )
         return@post
     }
-}
-
+}
\ No newline at end of file
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/helpers.kt 
b/bank/src/main/kotlin/tech/libeufin/bank/helpers.kt
index 3007021b..a5200426 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/helpers.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/helpers.kt
@@ -141,7 +141,6 @@ fun doTokenAuth(
 
 fun forbidden(
     hint: String = "No rights on the resource",
-    // FIXME: create a 'generic forbidden' Taler EC.
     talerErrorCode: TalerErrorCode = TalerErrorCode.TALER_EC_END
 ): LibeufinBankException = LibeufinBankException(
     httpStatus = HttpStatusCode.Forbidden, talerError = TalerError(
@@ -151,7 +150,7 @@ fun forbidden(
 
 fun unauthorized(hint: String = "Login failed"): LibeufinBankException = 
LibeufinBankException(
     httpStatus = HttpStatusCode.Unauthorized, talerError = TalerError(
-        code = TalerErrorCode.TALER_EC_BANK_LOGIN_FAILED.code, hint = hint
+        code = TalerErrorCode.TALER_EC_GENERIC_UNAUTHORIZED.code, hint = hint
     )
 )
 
diff --git a/bank/src/test/kotlin/JsonTest.kt b/bank/src/test/kotlin/JsonTest.kt
index 263ed613..0f01faa1 100644
--- a/bank/src/test/kotlin/JsonTest.kt
+++ b/bank/src/test/kotlin/JsonTest.kt
@@ -46,4 +46,10 @@ class JsonTest {
         val foreverSerial = Json.encodeToString(forever)
         assert(Json.decodeFromString<RelativeTime>(foreverSerial).d_us == 
forever.d_us)
     }
+
+    @Test
+    fun enumSerializer() {
+        assert("\"credit\"" == 
Json.encodeToString(CorebankCreditDebitInfo.credit))
+        assert("\"debit\"" == 
Json.encodeToString(CorebankCreditDebitInfo.debit))
+    }
 }
\ No newline at end of file
diff --git a/bank/src/test/kotlin/TalerApiTest.kt 
b/bank/src/test/kotlin/TalerApiTest.kt
index 8bdcc283..a78a7a1a 100644
--- a/bank/src/test/kotlin/TalerApiTest.kt
+++ b/bank/src/test/kotlin/TalerApiTest.kt
@@ -72,7 +72,7 @@ class TalerApiTest {
                       "credit_account": "BAR-IBAN-ABC"
                     }
                 """.trimIndent()
-            val resp = 
client.post("/accounts/foo/taler-wire-gateway/transfer") {
+            client.post("/accounts/foo/taler-wire-gateway/transfer") {
                 basicAuth("foo", "pw")
                 contentType(ContentType.Application.Json)
                 expectSuccess = true
@@ -80,7 +80,7 @@ class TalerApiTest {
             }
             // println(resp.bodyAsText())
             // check idempotency
-            val idemResp = 
client.post("/accounts/foo/taler-wire-gateway/transfer") {
+            client.post("/accounts/foo/taler-wire-gateway/transfer") {
                 basicAuth("foo", "pw")
                 contentType(ContentType.Application.Json)
                 expectSuccess = true
diff --git a/contrib/wallet-core b/contrib/wallet-core
index 8a9eea81..c5a3cd4c 160000
--- a/contrib/wallet-core
+++ b/contrib/wallet-core
@@ -1 +1 @@
-Subproject commit 8a9eea812bd17a54fa63b5450d0c9e562700589a
+Subproject commit c5a3cd4c50676c49fa6c67cbdeb609101c38e764
diff --git a/util/src/main/kotlin/TalerErrorCode.kt 
b/util/src/main/kotlin/TalerErrorCode.kt
index bf46a498..db89eb25 100644
--- a/util/src/main/kotlin/TalerErrorCode.kt
+++ b/util/src/main/kotlin/TalerErrorCode.kt
@@ -169,6 +169,14 @@ enum class TalerErrorCode(val code: Int) {
   TALER_EC_GENERIC_RESERVE_PUB_MALFORMED(27),
 
 
+  /**
+   * The body in the request could not be decompressed by the server.
+   * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
+   * (A value of 0 indicates that the error is generated client-side).
+   */
+  TALER_EC_GENERIC_COMPRESSION_INVALID(28),
+
+
   /**
    * The currencies involved in the operation do not match.
    * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
@@ -201,6 +209,38 @@ enum class TalerErrorCode(val code: Int) {
   TALER_EC_GENERIC_UNAUTHORIZED(40),
 
 
+  /**
+   * The service refused the request as the given authorization token is 
unknown.
+   * Returned with an HTTP status code of #MHD_HTTP_UNAUTHORIZED (401).
+   * (A value of 0 indicates that the error is generated client-side).
+   */
+  TALER_EC_GENERIC_TOKEN_UNKNOWN(41),
+
+
+  /**
+   * The service refused the request as the given authorization token expired.
+   * Returned with an HTTP status code of #MHD_HTTP_UNAUTHORIZED (401).
+   * (A value of 0 indicates that the error is generated client-side).
+   */
+  TALER_EC_GENERIC_TOKEN_EXPIRED(42),
+
+
+  /**
+   * The service refused the request as the given authorization token is 
malformed.
+   * Returned with an HTTP status code of #MHD_HTTP_UNAUTHORIZED (401).
+   * (A value of 0 indicates that the error is generated client-side).
+   */
+  TALER_EC_GENERIC_TOKEN_MALFORMED(43),
+
+
+  /**
+   * The service refused the request due to lack of proper rights on the 
resource.
+   * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
+   * (A value of 0 indicates that the error is generated client-side).
+   */
+  TALER_EC_GENERIC_FORBIDDEN(44),
+
+
   /**
    * The service failed initialize its connection to the database.
    * Returned with an HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR 
(500).
@@ -481,6 +521,14 @@ enum class TalerErrorCode(val code: Int) {
   TALER_EC_EXCHANGE_GENERIC_NEW_DENOMS_ARRAY_SIZE_EXCESSIVE(1018),
 
 
+  /**
+   * The coin is not known to the exchange (yet).
+   * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
+   * (A value of 0 indicates that the error is generated client-side).
+   */
+  TALER_EC_EXCHANGE_GENERIC_COIN_UNKNOWN(1019),
+
+
   /**
    * The time at the server is too far off from the time specified in the 
request. Most likely the client system time is wrong.
    * Returned with an HTTP status code of #MHD_HTTP_BAD_REQUEST (400).
@@ -890,19 +938,11 @@ enum class TalerErrorCode(val code: Int) {
 
 
   /**
-   * The reserve balance, status or history was requested for a reserve which 
is not known to the exchange.
-   * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
-   * (A value of 0 indicates that the error is generated client-side).
-   */
-  TALER_EC_EXCHANGE_RESERVES_STATUS_UNKNOWN(1250),
-
-
-  /**
-   * The reserve status was requested with a bad signature.
+   * The coin history was requested with a bad signature.
    * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
    * (A value of 0 indicates that the error is generated client-side).
    */
-  TALER_EC_EXCHANGE_RESERVES_STATUS_BAD_SIGNATURE(1251),
+  TALER_EC_EXCHANGE_COIN_HISTORY_BAD_SIGNATURE(1251),
 
 
   /**
@@ -910,7 +950,7 @@ enum class TalerErrorCode(val code: Int) {
    * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
    * (A value of 0 indicates that the error is generated client-side).
    */
-  TALER_EC_EXCHANGE_RESERVES_HISTORY_BAD_SIGNATURE(1252),
+  TALER_EC_EXCHANGE_RESERVE_HISTORY_BAD_SIGNATURE(1252),
 
 
   /**
@@ -3145,14 +3185,6 @@ enum class TalerErrorCode(val code: Int) {
   TALER_EC_BANK_NUMBER_TOO_BIG(5104),
 
 
-  /**
-   * Could not login for the requested operation.
-   * Returned with an HTTP status code of #MHD_HTTP_FORBIDDEN (403).
-   * (A value of 0 indicates that the error is generated client-side).
-   */
-  TALER_EC_BANK_LOGIN_FAILED(5105),
-
-
   /**
    * The bank account referenced in the requested operation was not found.
    * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
@@ -3265,6 +3297,14 @@ enum class TalerErrorCode(val code: Int) {
   TALER_EC_BANK_POST_WITHDRAWAL_OPERATION_REQUIRED(5119),
 
 
+  /**
+   * The client tried to register a new account under a reserved username 
(like 'admin' for example).
+   * Returned with an HTTP status code of #MHD_HTTP_CONFLICT (409).
+   * (A value of 0 indicates that the error is generated client-side).
+   */
+  TALER_EC_BANK_RESERVED_USERNAME_CONFLICT(5120),
+
+
   /**
    * The sync service failed find the account in its database.
    * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404).
@@ -4295,4 +4335,6 @@ enum class TalerErrorCode(val code: Int) {
    * (A value of 0 indicates that the error is generated client-side).
    */
   TALER_EC_END(9999),
+
+
 }

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]