summaryrefslogtreecommitdiff
path: root/nexus/src/main
diff options
context:
space:
mode:
authorMarcello Stanisci <ms@taler.net>2020-05-12 16:15:55 +0200
committerMarcello Stanisci <ms@taler.net>2020-05-12 16:15:55 +0200
commit2d656c1d85ac443519b7f07c11b6b52744146838 (patch)
treebb1db280696560424976653080663d397e5790cc /nexus/src/main
parent85ffd4121387669dc5570231d2adb6ff40124eee (diff)
downloadlibeufin-2d656c1d85ac443519b7f07c11b6b52744146838.tar.gz
libeufin-2d656c1d85ac443519b7f07c11b6b52744146838.tar.bz2
libeufin-2d656c1d85ac443519b7f07c11b6b52744146838.zip
implement /sync{MSG}
Diffstat (limited to 'nexus/src/main')
-rw-r--r--nexus/src/main/kotlin/tech/libeufin/nexus/Helpers.kt26
-rw-r--r--nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt67
-rw-r--r--nexus/src/main/kotlin/tech/libeufin/nexus/MainDeprecated.kt26
-rw-r--r--nexus/src/main/kotlin/tech/libeufin/nexus/taler.kt2
4 files changed, 85 insertions, 36 deletions
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Helpers.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/Helpers.kt
index 1826ae33..4258b844 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/Helpers.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/Helpers.kt
@@ -1,6 +1,5 @@
package tech.libeufin.nexus
-import io.ktor.application.ApplicationCall
import io.ktor.client.HttpClient
import io.ktor.http.HttpStatusCode
import org.jetbrains.exposed.sql.and
@@ -101,7 +100,7 @@ fun getBankAccountsFromNexusUserId(id: String): MutableList<BankAccountEntity> {
return ret
}
-fun getSubscriberDetails(subscriber: EbicsSubscriberEntity): EbicsClientSubscriberDetails {
+fun getEbicsSubscriberDetailsInternal(subscriber: EbicsSubscriberEntity): EbicsClientSubscriberDetails {
var bankAuthPubValue: RSAPublicKey? = null
if (subscriber.bankAuthenticationPublicKey != null) {
bankAuthPubValue = CryptoUtil.loadRsaPublicKey(
@@ -129,11 +128,7 @@ fun getSubscriberDetails(subscriber: EbicsSubscriberEntity): EbicsClientSubscrib
)
}
-/**
- * Retrieve Ebics subscriber details given a Transport
- * object and handling the default case.
- */
-fun getEbicsSubscriberDetails(userId: String, transportId: String?): EbicsClientSubscriberDetails {
+fun getEbicsTransport(userId: String, transportId: String?): EbicsSubscriberEntity {
val transport = transaction {
if (transportId == null) {
return@transaction EbicsSubscriberEntity.all().first()
@@ -150,8 +145,17 @@ fun getEbicsSubscriberDetails(userId: String, transportId: String?): EbicsClient
"No rights over transport $transportId"
)
}
+ return transport
+}
+
+/**
+ * Retrieve Ebics subscriber details given a Transport
+ * object and handling the default case.
+ */
+fun getEbicsSubscriberDetails(userId: String, transportId: String?): EbicsClientSubscriberDetails {
+ val transport = getEbicsTransport(userId, transportId)
// transport exists and belongs to caller.
- return getSubscriberDetails(transport)
+ return getEbicsSubscriberDetailsInternal(transport)
}
suspend fun downloadAndPersistC5xEbics(
@@ -394,8 +398,10 @@ fun addPreparedPayment(paymentData: Pain001Data, nexusUser: NexusUserEntity): Pr
}
}
-fun expectId(param: String?): String {
- return param ?: throw NexusError(HttpStatusCode.BadRequest, "Bad ID given")
+fun ensureNonNull(param: String?): String {
+ return param ?: throw NexusError(
+ HttpStatusCode.BadRequest, "Bad ID given"
+ )
}
/* Needs a transaction{} block to be called */
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt
index 234d239a..793ba532 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt
@@ -50,7 +50,6 @@ import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.slf4j.event.Level
import tech.libeufin.util.*
-import tech.libeufin.util.ebics_h004.EbicsResponse
import java.text.DateFormat
import java.util.zip.InflaterInputStream
import javax.crypto.EncryptedPrivateKeyInfo
@@ -59,18 +58,25 @@ import javax.sql.rowset.serial.SerialBlob
data class NexusError(val statusCode: HttpStatusCode, val reason: String) : Exception()
val logger: Logger = LoggerFactory.getLogger("tech.libeufin.nexus")
-suspend fun handleEbicsSendMSG(client: HttpClient, subscriber: EbicsClientSubscriberDetails, msg: String): String {
- when (msg.toUpperCase()) {
+suspend fun handleEbicsSendMSG(
+ httpClient: HttpClient,
+ userId: String,
+ transportId: String?,
+ msg: String,
+ sync: Boolean
+): String {
+ val subscriber = getEbicsSubscriberDetails(userId, transportId)
+ val response = when (msg.toUpperCase()) {
"HIA" -> {
val request = makeEbicsHiaRequest(subscriber)
- return client.postToBank(
+ httpClient.postToBank(
subscriber.ebicsUrl,
request
)
}
"INI" -> {
val request = makeEbicsIniRequest(subscriber)
- return client.postToBank(
+ httpClient.postToBank(
subscriber.ebicsUrl,
request
)
@@ -78,20 +84,35 @@ suspend fun handleEbicsSendMSG(client: HttpClient, subscriber: EbicsClientSubscr
"HPB" -> {
/** should NOT put bank's keys into any table. */
val request = makeEbicsHpbRequest(subscriber)
- return client.postToBank(
+ val response = httpClient.postToBank(
subscriber.ebicsUrl,
request
)
+ if (sync) {
+ val parsedResponse = parseAndDecryptEbicsKeyManagementResponse(subscriber, response)
+ val orderData = parsedResponse.orderData ?: throw NexusError(
+ HttpStatusCode.InternalServerError,
+ "Cannot find data in a HPB response"
+ )
+ val hpbData = parseEbicsHpbOrder(orderData)
+ transaction {
+ val transport = getEbicsTransport(userId, transportId)
+ transport.bankAuthenticationPublicKey = SerialBlob(hpbData.authenticationPubKey.encoded)
+ transport.bankEncryptionPublicKey = SerialBlob(hpbData.encryptionPubKey.encoded)
+ }
+ }
+ return response
}
"HEV" -> {
val request = makeEbicsHEVRequest(subscriber)
- return client.postToBank(subscriber.ebicsUrl, request)
+ httpClient.postToBank(subscriber.ebicsUrl, request)
}
else -> throw NexusError(
HttpStatusCode.NotFound,
"Message $msg not found"
)
}
+ return response
}
@ExperimentalIoApi
@@ -260,7 +281,7 @@ fun main() {
*/
get("/bank-accounts/{accountid}/prepared-payments/{uuid}") {
val userId = authenticateRequest(call.request.headers["Authorization"])
- val preparedPayment = getPreparedPayment(expectId(call.parameters["uuid"]))
+ val preparedPayment = getPreparedPayment(ensureNonNull(call.parameters["uuid"]))
if (preparedPayment.nexusUser.id.value != userId) throw NexusError(
HttpStatusCode.Forbidden,
"No rights over such payment"
@@ -285,7 +306,7 @@ fun main() {
*/
post("/bank-accounts/{accountid}/prepared-payments") {
val userId = authenticateRequest(call.request.headers["Authorization"])
- val bankAccount = getBankAccount(userId, expectId(call.parameters["accountid"]))
+ val bankAccount = getBankAccount(userId, ensureNonNull(call.parameters["accountid"]))
val body = call.receive<PreparedPaymentRequest>()
val amount = parseAmount(body.amount)
val paymentEntity = addPreparedPayment(
@@ -474,9 +495,12 @@ fun main() {
when (body.type) {
"ebics" -> {
val response = handleEbicsSendMSG(
- client,
- getEbicsSubscriberDetails(userId, body.name),
- expectId(call.parameters["MSG"]))
+ httpClient = client,
+ userId = userId,
+ transportId = body.name,
+ msg = ensureNonNull(call.parameters["MSG"]),
+ sync = true
+ )
call.respondText(response)
}
else -> throw NexusError(
@@ -491,6 +515,25 @@ fun main() {
* "transportName". DOES alterate DB tables.
*/
post("/bank-transports/{transportName}/sync{MSG}") {
+ val userId = authenticateRequest(call.request.headers["Authorization"])
+ val body = call.receive<Transport>()
+ when (body.type) {
+ "ebics" -> {
+ val response = handleEbicsSendMSG(
+ httpClient = client,
+ userId = userId,
+ transportId = body.name,
+ msg = ensureNonNull(call.parameters["MSG"]),
+ sync = true
+ )
+ call.respondText(response)
+ }
+ else -> throw NexusError(
+ HttpStatusCode.NotImplemented,
+ "Transport '${body.type}' not implemented. Use 'ebics'"
+ )
+ }
+
return@post
}
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/MainDeprecated.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/MainDeprecated.kt
index df00d65c..d730001a 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/MainDeprecated.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/MainDeprecated.kt
@@ -202,7 +202,7 @@ fun main() {
}
/** Make a new NEXUS user in the system */
post("/users/{id}") {
- val newUserId = expectId(call.parameters["id"])
+ val newUserId = ensureNonNull(call.parameters["id"])
val body = call.receive<NexusUserRequest>()
transaction {
NexusUserEntity.new(id = newUserId) {
@@ -224,7 +224,7 @@ fun main() {
/** Show bank accounts associated with a given NEXUS user */
get("/users/{id}/accounts") {
// this information is only avaiable *after* HTD or HKD has been called
- val id = expectId(call.parameters["id"])
+ val id = ensureNonNull(call.parameters["id"])
val ret = BankAccountsInfoResponse()
transaction {
BankAccountMapEntity.find {
@@ -248,7 +248,7 @@ fun main() {
}
/** Show PREPARED payments */
get("/users/{id}/payments") {
- val nexusUserId = expectId(call.parameters["id"])
+ val nexusUserId = ensureNonNull(call.parameters["id"])
val ret = RawPayments()
transaction {
val nexusUser = extractNexusUser(nexusUserId)
@@ -345,7 +345,7 @@ fun main() {
}
post("/ebics/subscribers/{id}/restoreBackup") {
val body = call.receive<EbicsKeysBackupJson>()
- val nexusId = expectId(call.parameters["id"])
+ val nexusId = ensureNonNull(call.parameters["id"])
val subscriber = transaction {
NexusUserEntity.findById(nexusId)
}
@@ -425,7 +425,7 @@ fun main() {
)
}
get("/ebics/subscribers/{id}/keyletter") {
- val nexusUserId = expectId(call.parameters["id"])
+ val nexusUserId = ensureNonNull(call.parameters["id"])
var usernameLine = "TODO"
var recipientLine = "TODO"
val customerIdLine = "TODO"
@@ -572,7 +572,7 @@ fun main() {
logger.debug("Uploading PAIN.001: ${painDoc}")
doEbicsUploadTransaction(
client,
- getSubscriberDetails(subscriber),
+ getEbicsSubscriberDetailsInternal(subscriber),
"CCT",
painDoc.toByteArray(Charsets.UTF_8),
EbicsStandardOrderParams()
@@ -651,7 +651,7 @@ fun main() {
return@post
}
post("/ebics/subscribers/{id}/fetch-payment-status") {
- val id = expectId(call.parameters["id"])
+ val id = ensureNonNull(call.parameters["id"])
val paramsJson = call.receive<EbicsStandardOrderParamsJson>()
val orderParams = paramsJson.toOrderParams()
val subscriberData = getSubscriberDetailsFromNexusUserId(id)
@@ -677,7 +677,7 @@ fun main() {
return@post
}
post("/ebics/subscribers/{id}/collect-transactions-c53") {
- val id = expectId(call.parameters["id"])
+ val id = ensureNonNull(call.parameters["id"])
val paramsJson = call.receive<EbicsStandardOrderParamsJson>()
val orderParams = paramsJson.toOrderParams()
val subscriberData = getSubscriberDetailsFromNexusUserId(id)
@@ -778,8 +778,8 @@ fun main() {
// FIXME: some messages include a ZIPped payload.
post("/ebics/subscribers/{id}/send{MSG}") {
- val id = expectId(call.parameters["id"])
- val MSG = expectId(call.parameters["MSG"])
+ val id = ensureNonNull(call.parameters["id"])
+ val MSG = ensureNonNull(call.parameters["MSG"])
val paramsJson = call.receive<EbicsStandardOrderParamsJson>()
val orderParams = paramsJson.toOrderParams()
println("$MSG order params: $orderParams")
@@ -808,7 +808,7 @@ fun main() {
return@post
}
get("/ebics/{id}/sendHEV") {
- val id = expectId(call.parameters["id"])
+ val id = ensureNonNull(call.parameters["id"])
val subscriberData = getSubscriberDetailsFromNexusUserId(id)
val request = makeEbicsHEVRequest(subscriberData)
val response = client.postToBank(subscriberData.ebicsUrl, request)
@@ -825,7 +825,7 @@ fun main() {
return@get
}
post("/ebics/subscribers/{id}/sendINI") {
- val id = expectId(call.parameters["id"])
+ val id = ensureNonNull(call.parameters["id"])
val subscriberData = getSubscriberDetailsFromNexusUserId(id)
val iniRequest = makeEbicsIniRequest(subscriberData)
val responseStr = client.postToBank(
@@ -844,7 +844,7 @@ fun main() {
}
post("/ebics/subscribers/{id}/sendHIA") {
- val id = expectId(call.parameters["id"])
+ val id = ensureNonNull(call.parameters["id"])
val subscriberData = getSubscriberDetailsFromNexusUserId(id)
val hiaRequest = makeEbicsHiaRequest(subscriberData)
val responseStr = client.postToBank(
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/taler.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/taler.kt
index 8a97107d..b259bb51 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/taler.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/taler.kt
@@ -395,7 +395,7 @@ class Taler(app: Route) {
* payment was added as well.
*/
app.post("/ebics/taler/{id}/crunch-raw-transactions") {
- val id = expectId(call.parameters["id"])
+ val id = ensureNonNull(call.parameters["id"])
// first find highest ID value of already processed rows.
transaction {
val subscriberAccount = getBankAccountFromNexusUserId(id)