commit 85a141fba1038430ac7bf23367a56595731740a6
parent 70b95e9aee7d84d835cc25dd512a24d16604f63b
Author: Marcello Stanisci <stanisci.m@gmail.com>
Date: Tue, 10 Mar 2020 18:15:04 +0100
debugging
Diffstat:
4 files changed, 34 insertions(+), 28 deletions(-)
diff --git a/cli/python/libeufin-cli b/cli/python/libeufin-cli
@@ -114,7 +114,7 @@ def hev(obj, account_id, nexus_base_url):
try:
resp = get(url)
except Exception:
- print("Unsuccessful request")
+ print("Could not reach the bank")
return
print(resp.content.decode("utf-8"))
@@ -714,7 +714,7 @@ def fetch_accounts(ctx, account_id, prepare, nexus_base_url):
try:
resp = post(url, json=dict())
except Exception:
- print("Could not reach the bank")
+ print("Could not reach the Nexus")
return
print(resp.content.decode("utf-8"))
@@ -735,7 +735,7 @@ def hia(obj, account_id, nexus_base_url):
try:
resp = post(url)
except Exception:
- print("Could not reach the bank")
+ print("Could not reach the Nexus")
return
print(resp.content.decode("utf-8"))
@@ -756,7 +756,7 @@ def sync(obj, account_id, nexus_base_url):
try:
resp = post(url)
except Exception:
- print("Could not reach the bank")
+ print("Could not reach the Nexus")
return
print(resp.content.decode("utf-8"))
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsClient.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsClient.kt
@@ -8,7 +8,7 @@ import java.util.*
suspend inline fun HttpClient.postToBank(url: String, body: String): String {
logger.debug("Posting: $body")
- val response = try {
+ val response: String = try {
this.post<String>(
urlString = url,
block = {
@@ -18,6 +18,7 @@ suspend inline fun HttpClient.postToBank(url: String, body: String): String {
} catch (e: Exception) {
throw NexusError(HttpStatusCode.InternalServerError, "Cannot reach the bank")
}
+ logger.debug("Receiving: $response")
return response
}
@@ -66,6 +67,7 @@ suspend fun doEbicsDownloadTransaction(
// Success, nothing to do!
}
else -> {
+ logger.warn("Bank return code was: ${initResponse.bankReturnCode}")
return EbicsDownloadBankErrorResult(initResponse.bankReturnCode)
}
}
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt
@@ -49,7 +49,6 @@ import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.slf4j.event.Level
import tech.libeufin.util.*
-import tech.libeufin.util.InvalidSubscriberStateError
import tech.libeufin.util.ebics_h004.EbicsTypes
import tech.libeufin.util.ebics_h004.HTDResponseOrderData
import java.lang.StringBuilder
@@ -58,7 +57,6 @@ import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.*
import javax.crypto.EncryptedPrivateKeyInfo
-import javax.print.attribute.standard.JobStateReason
import javax.sql.rowset.serial.SerialBlob
fun testData() {
@@ -85,7 +83,6 @@ fun testData() {
data class NexusError(val statusCode: HttpStatusCode, val reason: String) : Exception()
-
val logger: Logger = LoggerFactory.getLogger("tech.libeufin.nexus")
fun getSubscriberEntityFromId(id: String): EbicsSubscriberEntity {
@@ -309,11 +306,18 @@ fun main() {
cause.statusCode
)
}
-
+ exception<UtilError> { cause ->
+ logger.error("Exception while handling '${call.request.uri}'", cause)
+ call.respondText(
+ cause.reason,
+ ContentType.Text.Plain,
+ cause.statusCode
+ )
+ }
exception<javax.xml.bind.UnmarshalException> { cause ->
logger.error("Exception while handling '${call.request.uri}'", cause)
call.respondText(
- "Could not convert string into JAXB (either from client or from bank)\n",
+ "Could not convert string into JAXB\n",
ContentType.Text.Plain,
HttpStatusCode.NotFound
)
@@ -500,7 +504,8 @@ fun main() {
call.respondText(
response.orderData.toString(Charsets.UTF_8),
ContentType.Text.Plain,
- HttpStatusCode.OK)
+ HttpStatusCode.OK
+ )
else -> call.respond(NexusErrorJson("Could not download any PAIN.002"))
}
return@post
diff --git a/util/src/main/kotlin/Ebics.kt b/util/src/main/kotlin/Ebics.kt
@@ -24,6 +24,7 @@
package tech.libeufin.util
+import io.ktor.http.HttpStatusCode
import tech.libeufin.util.ebics_h004.*
import tech.libeufin.util.ebics_hev.HEVRequest
import tech.libeufin.util.ebics_hev.HEVResponse
@@ -37,11 +38,7 @@ import java.util.*
import java.util.zip.DeflaterInputStream
import javax.xml.datatype.DatatypeFactory
-class InvalidSubscriberStateError : Exception("Invalid EBICS subscriber state")
-class InvalidXmlError : Exception("Invalid EBICS XML")
-class BadSignatureError : Exception("Invalid EBICS XML Signature")
-class EbicsUnknownReturnCodeError(msg: String) : Exception(msg)
-
+data class UtilError(val statusCode: HttpStatusCode, val reason: String) : Exception()
data class EbicsDateRange(val start: LocalDate, val end: LocalDate)
sealed class EbicsOrderParams
@@ -240,8 +237,8 @@ fun createEbicsRequestForDownloadInitialization(
subscriberDetails.hostId,
getNonce(128),
DatatypeFactory.newInstance().newXMLGregorianCalendar(GregorianCalendar()),
- subscriberDetails.bankEncPub ?: throw InvalidSubscriberStateError(),
- subscriberDetails.bankAuthPub ?: throw InvalidSubscriberStateError(),
+ subscriberDetails.bankEncPub ?: throw UtilError(HttpStatusCode.BadRequest, "Invalid subscriber state 'bankEncPub' missing, please send HPB first"),
+ subscriberDetails.bankAuthPub ?: throw UtilError(HttpStatusCode.BadRequest, "Invalid subscriber state 'bankAuthPub' missing, please send HPB first"),
orderType,
makeOrderParams(orderParams)
)
@@ -308,7 +305,7 @@ enum class EbicsReturnCode(val errorCode: String) {
return x;
}
}
- throw EbicsUnknownReturnCodeError("Unknown return code: $errorCode")
+ throw UtilError(HttpStatusCode.InternalServerError, "Unknown EBICS status code: $errorCode")
}
}
}
@@ -334,14 +331,16 @@ fun parseAndDecryptEbicsKeyManagementResponse(
val resp = try {
XMLUtil.convertStringToJaxb<EbicsKeyManagementResponse>(responseStr)
} catch (e: Exception) {
- throw InvalidXmlError()
+ throw UtilError(HttpStatusCode.InternalServerError, "Invalid XML received from bank")
}
val retCode = EbicsReturnCode.lookup(resp.value.header.mutable.returnCode)
val daeXml = resp.value.body.dataTransfer?.dataEncryptionInfo
val orderData = if (daeXml != null) {
val dae = DataEncryptionInfo(daeXml.transactionKey, daeXml.encryptionPubKeyDigest.value)
- val encOrderData = resp.value.body.dataTransfer?.orderData?.value ?: throw InvalidXmlError()
+ val encOrderData = resp.value.body.dataTransfer?.orderData?.value ?: throw UtilError(
+ HttpStatusCode.InternalServerError, "Invalid XML/orderData received from bank"
+ )
decryptAndDecompressResponse(subscriberDetails, dae, listOf(encOrderData))
} else {
null
@@ -365,7 +364,7 @@ fun parseEbicsHpbOrder(orderDataRaw: ByteArray): HpbResponseData {
val resp = try {
XMLUtil.convertStringToJaxb<HPBResponseOrderData>(orderDataRaw.toString(Charsets.UTF_8))
} catch (e: Exception) {
- throw InvalidXmlError()
+ throw UtilError(HttpStatusCode.InternalServerError, "Invalid XML (as HPB response) received from bank")
}
val encPubKey = CryptoUtil.loadRsaPublicKeyFromComponents(
resp.value.encryptionPubKeyInfo.pubKeyValue.rsaKeyValue.modulus,
@@ -391,20 +390,20 @@ fun parseAndValidateEbicsResponse(
val responseDocument = try {
XMLUtil.parseStringIntoDom(responseStr)
} catch (e: Exception) {
- throw InvalidXmlError()
+ throw UtilError(HttpStatusCode.InternalServerError, "Invalid XML (as EbicsResponse) received from bank")
}
if (!XMLUtil.verifyEbicsDocument(
responseDocument,
- subscriberDetails.bankAuthPub ?: throw InvalidSubscriberStateError()
+ subscriberDetails.bankAuthPub ?: throw UtilError(HttpStatusCode.BadRequest, "Invalid subscriber state: bankAuthPub missing, please send HPB first")
)
) {
- throw BadSignatureError()
+ throw UtilError(HttpStatusCode.InternalServerError, "Bank's signature validation failed")
}
val resp = try {
XMLUtil.convertStringToJaxb<EbicsResponse>(responseStr)
} catch (e: Exception) {
- throw InvalidXmlError()
+ throw UtilError(HttpStatusCode.InternalServerError, "Could not transform string-response from bank into JAXB")
}
val bankReturnCodeStr = resp.value.body.returnCode.value
@@ -443,7 +442,7 @@ fun getDecryptionKey(subscriberDetails: EbicsClientSubscriberDetails, pubDigest:
if (pubDigest.contentEquals(encPubDigest)) {
return subscriberDetails.customerEncPriv
}
- throw Exception("no matching private key to decrypt response")
+ throw UtilError(HttpStatusCode.NotFound,"Could not find customer's public key")
}
/**
@@ -494,7 +493,7 @@ fun parseEbicsHEVResponse(respStr: String): EbicsHevDetails {
XMLUtil.convertStringToJaxb<HEVResponse>(respStr)
} catch (e: Exception) {
logger.error("Exception while parsing HEV response", e)
- throw InvalidXmlError()
+ throw UtilError(HttpStatusCode.InternalServerError, "Invalid HEV received from bank")
}
val versions = resp.value.versionNumber.map { versionNumber ->
EbicsVersionSpec(versionNumber.protocolVersion, versionNumber.value)