[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libeufin] 02/02: Addressing FIXMEs.
From: |
gnunet |
Subject: |
[libeufin] 02/02: Addressing FIXMEs. |
Date: |
Fri, 29 Sep 2023 10:51:21 +0200 |
This is an automated email from the git hooks/post-receive script.
ms pushed a commit to branch master
in repository libeufin.
commit a917619a31aa0abbedfa36def0def2b38bae3d43
Author: MS <ms@taler.net>
AuthorDate: Fri Sep 29 10:50:32 2023 +0200
Addressing FIXMEs.
---
.../main/kotlin/tech/libeufin/bank/BankMessages.kt | 8 +--
.../tech/libeufin/bank/CorebankApiHandlers.kt | 32 +++++----
.../src/main/kotlin/tech/libeufin/bank/Database.kt | 4 +-
bank/src/main/kotlin/tech/libeufin/bank/Main.kt | 17 +----
.../tech/libeufin/bank/WireGatewayApiHandlers.kt | 6 +-
bank/src/main/kotlin/tech/libeufin/bank/helpers.kt | 3 +-
bank/src/test/kotlin/TalerApiTest.kt | 4 +-
util/src/main/kotlin/TalerErrorCode.kt | 80 +++++++++++++++++-----
8 files changed, 92 insertions(+), 62 deletions(-)
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/BankMessages.kt
b/bank/src/main/kotlin/tech/libeufin/bank/BankMessages.kt
index 234f29df..aa399b53 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/BankMessages.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/BankMessages.kt
@@ -31,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.
*/
@@ -437,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
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/CorebankApiHandlers.kt
b/bank/src/main/kotlin/tech/libeufin/bank/CorebankApiHandlers.kt
index 702e4386..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.
@@ -242,7 +245,7 @@ fun Routing.accountsMgmtHandlers(db: Database, ctx:
BankApplicationContext) {
)
) 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(
@@ -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")
@@ -380,7 +384,8 @@ 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
)
if (txData.amount.currency != ctx.currency) throw badRequest(
"Wrong currency: ${txData.amount.currency}", talerErrorCode =
TalerErrorCode.TALER_EC_GENERIC_CURRENCY_MISMATCH
@@ -395,13 +400,11 @@ fun Routing.accountsMgmtHandlers(db: Database, ctx:
BankApplicationContext) {
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
@@ -420,7 +423,8 @@ 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.")
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/Main.kt
b/bank/src/main/kotlin/tech/libeufin/bank/Main.kt
index 3799c0a3..307b29bd 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/Main.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/Main.kt
@@ -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 4aa816d8..7e5d154c 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/WireGatewayApiHandlers.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/WireGatewayApiHandlers.kt
@@ -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")
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/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/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.