[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libeufin] branch master updated (0692f2f2 -> e0f1d57d)
From: |
gnunet |
Subject: |
[libeufin] branch master updated (0692f2f2 -> e0f1d57d) |
Date: |
Tue, 21 Nov 2023 05:42:10 +0100 |
This is an automated email from the git hooks/post-receive script.
antoine pushed a change to branch master
in repository libeufin.
from 0692f2f2 Test iban payto uri normalization
new 9e9cfb04 Catch and format SQLException
new e0f1d57d Basic auth challenge
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:
.../kotlin/tech/libeufin/bank/Authentication.kt | 19 ++++++---
bank/src/main/kotlin/tech/libeufin/bank/Error.kt | 6 ++-
bank/src/main/kotlin/tech/libeufin/bank/Main.kt | 45 ++++++++++++++--------
.../main/kotlin/tech/libeufin/bank/db/Database.kt | 17 ++++----
.../main/kotlin/tech/libeufin/nexus/Database.kt | 3 +-
util/src/main/kotlin/DB.kt | 5 ++-
util/src/main/kotlin/HTTP.kt | 3 +-
7 files changed, 61 insertions(+), 37 deletions(-)
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Authentication.kt
b/bank/src/main/kotlin/tech/libeufin/bank/Authentication.kt
index 6001be52..cbef0e1e 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/Authentication.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/Authentication.kt
@@ -21,6 +21,7 @@ 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
@@ -84,10 +85,16 @@ val ApplicationCall.isAdmin: Boolean get() =
attributes.getOrNull(AUTH_IS_ADMIN)
*/
private suspend fun ApplicationCall.authenticateBankRequest(db: Database,
requiredScope: TokenScope): String? {
// Extracting the Authorization header.
- val header = getAuthorizationRawHeader(this.request) ?: throw badRequest(
- "Authorization header not found.",
- TalerErrorCode.GENERIC_HTTP_HEADERS_MALFORMED
- )
+ val header = getAuthorizationRawHeader(this.request)
+ if (header == null) {
+ // Basic auth challenge
+ response.header(HttpHeaders.WWWAuthenticate, "Basic")
+ throw unauthorized(
+ "Authorization header not found.",
+ TalerErrorCode.GENERIC_PARAMETER_MISSING
+ )
+ }
+
val authDetails = getAuthorizationDetails(header) ?: throw badRequest(
"Authorization is invalid.",
TalerErrorCode.GENERIC_HTTP_HEADERS_MALFORMED
@@ -95,7 +102,7 @@ private suspend fun
ApplicationCall.authenticateBankRequest(db: Database, requir
return when (authDetails.scheme) {
"Basic" -> doBasicAuth(db, authDetails.content)
"Bearer" -> doTokenAuth(db, authDetails.content, requiredScope)
- else -> throw unauthorized("Authorization method wrong or not
supported.") // TODO basic auth challenge
+ else -> throw unauthorized("Authorization method wrong or not
supported.")
}
}
@@ -134,7 +141,7 @@ private suspend fun doBasicAuth(db: Database,
encodedCredentials: String): Strin
TalerErrorCode.GENERIC_HTTP_HEADERS_MALFORMED
)
val (login, plainPassword) = userAndPassSplit
- val passwordHash = db.account.passwordHash(login) ?: throw unauthorized()
+ val passwordHash = db.account.passwordHash(login) ?: throw
unauthorized("Bad password")
if (!CryptoUtil.checkpw(plainPassword, passwordHash)) return null
return login
}
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Error.kt
b/bank/src/main/kotlin/tech/libeufin/bank/Error.kt
index 77a584ab..ae879ebc 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/Error.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/Error.kt
@@ -63,8 +63,10 @@ fun forbidden(
error: TalerErrorCode = TalerErrorCode.END
): LibeufinBankException = libeufinError(HttpStatusCode.Forbidden, hint, error)
-fun unauthorized(hint: String? = "Login failed"): LibeufinBankException
- = libeufinError(HttpStatusCode.Unauthorized, hint,
TalerErrorCode.GENERIC_UNAUTHORIZED)
+fun unauthorized(
+ hint: String,
+ error: TalerErrorCode = TalerErrorCode.GENERIC_UNAUTHORIZED
+): LibeufinBankException = libeufinError(HttpStatusCode.Unauthorized, hint,
error)
fun internalServerError(hint: String?): LibeufinBankException
= libeufinError(HttpStatusCode.InternalServerError, hint,
TalerErrorCode.GENERIC_INTERNAL_INVARIANT_FAILURE)
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Main.kt
b/bank/src/main/kotlin/tech/libeufin/bank/Main.kt
index f3fffcbe..d381d984 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/Main.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/Main.kt
@@ -44,6 +44,7 @@ import io.ktor.utils.io.jvm.javaio.*
import java.time.Duration
import java.util.zip.DataFormatException
import java.util.zip.Inflater
+import java.sql.SQLException
import kotlin.system.exitProcess
import kotlinx.coroutines.*
import kotlinx.serialization.ExperimentalSerializationApi
@@ -53,6 +54,7 @@ import net.taler.common.errorcodes.TalerErrorCode
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.util.getVersion
import tech.libeufin.util.initializeDatabaseTables
@@ -178,32 +180,43 @@ fun Application.corebankWebApp(db: Database, ctx:
BankConfig) {
)
)
}
- /**
- * This branch triggers when a bank handler throws it, and namely
- * after one logical failure of the request(-handling). This branch
- * should be preferred to catch errors, as it allows to include the
- * Taler specific error detail.
- */
exception<LibeufinBankException> { call, cause ->
logger.error(cause.talerError.hint)
- // Stacktrace if bank's fault
- if (cause.httpStatus.toString().startsWith('5'))
- cause.printStackTrace()
call.respond(
status = cause.httpStatus,
message = cause.talerError
)
}
+ exception<SQLException> { call, cause ->
+ val err = when (cause.sqlState) {
+ PSQLState.SERIALIZATION_FAILURE.state -> libeufinError(
+ HttpStatusCode.InternalServerError,
+ "Transaction serialization failure",
+ TalerErrorCode.BANK_SOFT_EXCEPTION
+ )
+ else -> libeufinError(
+ HttpStatusCode.InternalServerError,
+ "Unexpected sql error with state ${cause.sqlState}",
+ TalerErrorCode.BANK_UNMANAGED_EXCEPTION
+ )
+ }
+ logger.error(err.talerError.hint)
+ call.respond(
+ status = err.httpStatus,
+ message = err.talerError
+ )
+ }
// Catch-all branch to mean that the bank wasn't able to manage one
error.
exception<Exception> { call, cause ->
- cause.printStackTrace()
- logger.error(cause.message)
+ val err = libeufinError(
+ HttpStatusCode.InternalServerError,
+ cause.message,
+ TalerErrorCode.BANK_UNMANAGED_EXCEPTION
+ )
+ logger.error(err.talerError.hint)
call.respond(
- status = HttpStatusCode.InternalServerError,
- message = TalerError(
- code =
TalerErrorCode.GENERIC_INTERNAL_INVARIANT_FAILURE.code,
- hint = cause.message
- )
+ status = err.httpStatus,
+ message = err.talerError
)
}
}
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 892e0602..417d0275 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/db/Database.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/db/Database.kt
@@ -21,6 +21,7 @@ package tech.libeufin.bank
import org.postgresql.jdbc.PgConnection
import org.postgresql.ds.PGSimpleDataSource
+import org.postgresql.util.PSQLState
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import java.io.File
@@ -150,16 +151,16 @@ class Database(dbConfig: String, internal val
bankCurrency: String, internal val
try {
return@conn lambda(conn);
} catch (e: SQLException) {
- logger.error(e.message)
- if (e.sqlState != "40001") // serialization_failure
- throw e // rethrowing, not to hide other types of errors.
+ if (e.sqlState != PSQLState.SERIALIZATION_FAILURE.state)
+ throw e
}
}
- throw libeufinError(
- HttpStatusCode.InternalServerError,
- "Transaction serialization failure",
- TalerErrorCode.BANK_SOFT_EXCEPTION
- )
+ try {
+ return@conn lambda(conn)
+ } catch(e: SQLException) {
+ logger.warn("Serialization failure after $SERIALIZATION_RETRY
retry")
+ throw e
+ }
}
/** Apply paging logic to a sql query */
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Database.kt
b/nexus/src/main/kotlin/tech/libeufin/nexus/Database.kt
index 82df529c..d80fd665 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/Database.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/Database.kt
@@ -3,6 +3,7 @@ package tech.libeufin.nexus
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.postgresql.jdbc.PgConnection
+import org.postgresql.util.PSQLState
import com.zaxxer.hikari.*
import tech.libeufin.util.*
import java.sql.PreparedStatement
@@ -137,7 +138,7 @@ private fun PreparedStatement.maybeUpdate(): Boolean {
this.executeUpdate()
} catch (e: SQLException) {
logger.error(e.message)
- if (e.sqlState == "23505") return false // unique_violation
+ if (e.sqlState == PSQLState.UNIQUE_VIOLATION.state) return false
throw e // rethrowing, not to hide other types of errors.
}
return updateCount > 0
diff --git a/util/src/main/kotlin/DB.kt b/util/src/main/kotlin/DB.kt
index ebc7d7e2..1a7571df 100644
--- a/util/src/main/kotlin/DB.kt
+++ b/util/src/main/kotlin/DB.kt
@@ -25,6 +25,7 @@ import kotlinx.coroutines.coroutineScope
import net.taler.wallet.crypto.Base32Crockford
import org.postgresql.ds.PGSimpleDataSource
import org.postgresql.jdbc.PgConnection
+import org.postgresql.util.PSQLState
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import java.io.File
@@ -171,7 +172,7 @@ fun PreparedStatement.executeUpdateViolation(): Boolean {
executeUpdateCheck()
} catch (e: SQLException) {
logger.error(e.message)
- if (e.sqlState == "23505") return false // unique_violation
+ if (e.sqlState == PSQLState.UNIQUE_VIOLATION.state) return false
throw e // rethrowing, not to hide other types of errors.
}
}
@@ -184,7 +185,7 @@ fun PreparedStatement.executeProcedureViolation(): Boolean {
true
} catch (e: SQLException) {
connection.rollback(savepoint);
- if (e.sqlState == "23505") return false // unique_violation
+ 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/HTTP.kt b/util/src/main/kotlin/HTTP.kt
index 8c639496..d310c9ba 100644
--- a/util/src/main/kotlin/HTTP.kt
+++ b/util/src/main/kotlin/HTTP.kt
@@ -54,8 +54,7 @@ fun ApplicationCall.maybeUriComponent(name: String): String? {
// Extracts the Authorization:-header line, or returns null if not found.
fun getAuthorizationRawHeader(request: ApplicationRequest): String? {
- val authorization = request.headers["Authorization"]
- return authorization ?: run {
+ return request.headers["Authorization"] ?: run {
logger.error("Authorization header not found")
return null
}
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [libeufin] branch master updated (0692f2f2 -> e0f1d57d),
gnunet <=