commit 292879869ae9396a3ce4a5a162178c6ff1381362 parent a00d4d1d9daeafe47baba0e0f04a9b65ebe9ab26 Author: Antoine A <> Date: Thu, 18 Dec 2025 17:51:57 +0100 ebisync: submit deb and fixes Diffstat:
18 files changed, 97 insertions(+), 23 deletions(-)
diff --git a/contrib/ci/deb-test.sh b/contrib/ci/deb-test.sh @@ -5,7 +5,7 @@ function step { echo -e "\n$@" >&2 } -ITEMS="libeufin-bank libeufin-nexus" +ITEMS="libeufin-bank libeufin-nexus libeufin-ebisync" step "Install libeufin" dpkg -i ../libeufin*.deb @@ -28,6 +28,7 @@ done step "Run dbconfig" libeufin-dbconfig -r -b testbench/conf/mini.conf -n testbench/conf/mini.conf +libeufin-ebisync-dbconfig -r -c testbench/conf/mini.conf for USER in $ITEMS; do step "Check $USER db access" diff --git a/contrib/libeufin-ebisync-dbconfig b/contrib/libeufin-ebisync-dbconfig @@ -91,11 +91,11 @@ if ! sudo -i -u postgres createuser "$DBUSER" 2>/dev/null; then fi # Check database name -DBPATH=$(libeufin-ebisync config -c "$CFGFILE" get ebisyncdb-postgres CONFIG) -if ! echo "$DBPATH" | grep "postgres://" >/dev/null; then - exit_fail "Invalid database configuration value '$DBPATH'." 1>&2 +DBPATH=$(libeufin-ebisync config get -c "$CFGFILE" ebisyncdb-postgres CONFIG) +if ! echo "$DBPATH" | grep "\(postgres\|postgresql\)://" >/dev/null; then + exit_fail "Invalid database configuration value '$DBPATH'." fi -DBNAME=$(echo "$DBPATH" | sed -e "s/postgres:\/\/.*\///" -e "s/?.*//") +DBNAME=$(echo "$DBPATH" | sed -e 's|.*://.*/||' -e 's|?.*||') if sudo -i -u postgres psql "$DBNAME" </dev/null 2>/dev/null; then if [ 1 = "$RESET_DB" ]; then @@ -118,6 +118,11 @@ if [ 1 = "$DO_CREATE" ]; then if ! sudo -i -u postgres createdb -O "$DBUSER" "$DBNAME"; then exit_fail "Failed to create database '$DBNAME'" fi +else + if ! echo "GRANT ALL PRIVILEGES ON DATABASE $DBNAME TO \"$DBUSER\"" | + sudo -i -u postgres psql "$DBNAME"; then + exit_fail "Failed to grant access to database '$DBNAME' to '$DBUSER'." + fi fi # Run dbinit diff --git a/debian/etc/apache2/sites-available/libeufin-ebisync.conf b/debian/etc/apache2/sites-available/libeufin-ebisync.conf @@ -0,0 +1,6 @@ +<Location "/libeufin-ebisync/"> +ProxyPass "http://localhost:8080/" +# RequestHeader add "X-Forwarded-Proto" "https" +# RequestHeader add "X-Forwarded-Host" "localhost" +# RequestHeader add "X-Forwarded-Prefix" "/" +</Location> diff --git a/debian/etc/libeufin-ebisync/conf.d/ebisync-submit.conf b/debian/etc/libeufin-ebisync/conf.d/ebisync-submit.conf @@ -0,0 +1,9 @@ +# Configuration for the EbiSync submitter. + +[ebisync-submit] + +# Where does the ebics file come from? This his can either can be ebisync-api or none +# SOURCE = ebisync-api + +@inline-secret@ ebisync-submit ../secrets/ebisync-submit.secret.conf + diff --git a/debian/etc/libeufin-ebisync/secrets/ebisync-submit.secret.conf b/debian/etc/libeufin-ebisync/secrets/ebisync-submit.secret.conf @@ -0,0 +1,10 @@ +[ebisync-submit] + +# Authentication scheme used by the API, this can either can be basic, bearer or none. +# AUTH_METHOD = basic + +# User name for basic authentication scheme +# USERNAME = username + +# Password for basic authentication scheme +# PASSWORD = password +\ No newline at end of file diff --git a/debian/etc/nginx/sites-available/libeufin-ebisync b/debian/etc/nginx/sites-available/libeufin-ebisync @@ -0,0 +1,30 @@ +server { + include /etc/nginx/mime.types; + + # NOTE: + # - urgently consider configuring TLS instead + # - maybe keep a forwarder from HTTP to HTTPS + listen 80; + + # NOTE: + # - Comment out this line if you have no IPv6 + listen [::]:80; + + # NOTE: + # - replace with your actual server name. + server_name localhost; + + access_log /var/log/nginx/libeufin-ebisync.log; + error_log /var/log/nginx/libeufin-ebisync.err; + + location / { + # NOTE: urgently change to 'https' once TLS has been configured. + proxy_set_header X-Forwarded-Proto "$scheme"; + proxy_set_header X-Forwarded-Host "localhost"; + proxy_set_header X-Forwarded-Prefix /; + # FIXME: should use UNIX domain socket once + # supported by libeufin-ebisync! + proxy_pass http://localhost:8080; + } + +} diff --git a/debian/libeufin-ebisync.install b/debian/libeufin-ebisync.install @@ -1,4 +1,6 @@ debian/etc/libeufin-ebisync/* etc/libeufin-ebisync/ +debian/etc/nginx/sites-available/libeufin-ebisync etc/nginx/sites-available/ +debian/etc/apache2/sites-available/libeufin-ebisync.conf etc/apache2/sites-available/ libeufin-ebisync/build/install/libeufin-ebisync-shadow/bin/libeufin-ebisync usr/bin/ contrib/libeufin-ebisync-dbconfig usr/bin/ diff --git a/debian/libeufin-ebisync.libeufin-ebisync-ebics-fetch.service b/debian/libeufin-ebisync.libeufin-ebisync-fetch.service diff --git a/debian/libeufin-ebisync.tmpfiles b/debian/libeufin-ebisync.tmpfiles @@ -4,3 +4,4 @@ d$ /var/lib/libeufin-ebisync 0700 libeufin-ebisync libeufin-ebisync - - # Update secret files permissions z /etc/libeufin-ebisync/secrets/libeufin-ebisync-db.secret.conf 0640 libeufin-ebisync libeufin-ebisync - - z /etc/libeufin-ebisync/secrets/libeufin-ebisync-fetch.secret.conf 0640 libeufin-ebisync libeufin-ebisync - - +z /etc/libeufin-ebisync/secrets/libeufin-ebisync-submit.secret.conf 0640 libeufin-ebisync libeufin-ebisync - - diff --git a/libeufin-ebisync/conf/test.conf b/libeufin-ebisync/conf/test.conf @@ -10,5 +10,5 @@ PARTNER_ID = PFC00563 CONFIG = postgresql:///libeufincheck [ebisync-submit] -SOURCE = sync-api +SOURCE = ebisync-api AUTH_METHOD = none \ No newline at end of file diff --git a/libeufin-ebisync/ebisync.conf b/libeufin-ebisync/ebisync.conf @@ -53,7 +53,7 @@ DESTINATION = none # AZURE_COUNTAINER = mycontainer [ebisync-submit] -# Where does the ebics file come from? This his can either can be sync-api or none +# Where does the ebics file come from? This his can either can be ebisync-api or none SOURCE = none # Authentication scheme used by the API, this can either can be basic, bearer or none. diff --git a/libeufin-ebisync/src/main/kotlin/tech/libeufin/ebisync/api/SyncApi.kt b/libeufin-ebisync/src/main/kotlin/tech/libeufin/ebisync/api/SyncApi.kt @@ -38,13 +38,18 @@ import tech.libeufin.common.VERSION @Serializable class TalerEbiSyncConfig() { - val name: String = "taler-observability" + val name: String = "taler-ebisync" val version: String = "0:0:0" - val spaVersion: String = VERSION + val spa_version: String = VERSION } @Serializable -data class SyncOrder( +data class ListSubmitOrders( + val orders: List<SubmitOrder> +) + +@Serializable +data class SubmitOrder( val id: String, val description: String ) @@ -70,7 +75,7 @@ fun Routing.syncApi(auth: AuthMethod, client: EbicsClient, spa: Path) { } staticFiles("/webui/", spa.toFile()) get("/submit") { - call.respond(orders().map { SyncOrder(it.order.description(), it.description) }) + call.respond(ListSubmitOrders(orders().map { SubmitOrder(it.order.description(), it.description) })) } post("/submit") { call.attributes.set(BODY_LIMIT, 10 * 1024 * 1024) diff --git a/libeufin-ebisync/src/main/kotlin/tech/libeufin/ebisync/cli/Serve.kt b/libeufin-ebisync/src/main/kotlin/tech/libeufin/ebisync/cli/Serve.kt @@ -37,12 +37,13 @@ import com.github.ajalt.clikt.parameters.options.option import java.nio.file.Path -class Serve : EbicsCmd() { +class Serve : TalerCmd() { override fun help(context: Context) = "Run libeufin-ebisync HTTP server" private val check by option( help = "Check whether an API is in use (if it's useful to start the HTTP server). Exit with 0 if at least one API is enabled, otherwise 1" ).flag() + val ebicsLog by ebicsLogOption() override fun run() = cliCmd(logger) { val cfg = ebisyncConfig(config) diff --git a/libeufin-ebisync/src/main/kotlin/tech/libeufin/ebisync/config.kt b/libeufin-ebisync/src/main/kotlin/tech/libeufin/ebisync/config.kt @@ -95,7 +95,7 @@ class EbisyncSubmitConfig(cfg: TalerConfig) { val source = sect.mapLambda("source", "ebics file source", mapOf( "none" to { Source.None }, - "sync-api" to { Source.SyncAPI(sect.requireAuthMethod()) } + "ebisync-api" to { Source.SyncAPI(sect.requireAuthMethod()) } )).require() } diff --git a/libeufin-ebisync/src/spa/index.html b/libeufin-ebisync/src/spa/index.html @@ -360,7 +360,7 @@ try { const response = await fetch('/config'); const data = await response.json(); - document.getElementById('versionText').textContent = `${data.spaVersion} (${data.version})`; + document.getElementById('versionText').textContent = `${data.spa_version} (${data.version})`; } catch (error) { document.getElementById('versionText').textContent = 'Error'; showMessage('Unable to connect to backend server', 'error'); @@ -370,12 +370,12 @@ async function loadOrders() { try { const response = await fetch('/submit'); - const orders = await response.json(); + const data = await response.json(); const ordersList = document.getElementById('ordersList'); ordersList.innerHTML = ''; - orders.forEach(order => { + data.orders.forEach(order => { const orderCard = document.createElement('div'); orderCard.className = 'order-card'; orderCard.innerHTML = ` diff --git a/libeufin-ebisync/src/test/kotlin/SyncApiTest.kt b/libeufin-ebisync/src/test/kotlin/SyncApiTest.kt @@ -43,10 +43,10 @@ class SynApiTest { yield(bank::hkd) yield(bank::receiptOk) }) - val orders = client.get("/submit").assertOkJson<List<SyncOrder>>() - assertContentEquals(orders, listOf( - SyncOrder("BTU-SCT-pain.001", "Direct Debit"), - SyncOrder("BTU-SCI-DE-pain.001", "Instant Direct Debit"), + val date = client.get("/submit").assertOkJson<ListSubmitOrders>() + assertContentEquals(date.orders, listOf( + SubmitOrder("BTU-SCT-pain.001", "Direct Debit"), + SubmitOrder("BTU-SCI-DE-pain.001", "Instant Direct Debit"), )) } diff --git a/testbench/conf/mini.conf b/testbench/conf/mini.conf @@ -23,4 +23,7 @@ NAME = myname CONFIG = postgresql:///libeufincheck [libeufin-nexusdb-postgres] -CONFIG = postgresql:///libeufincheck -\ No newline at end of file +CONFIG = postgres:///libeufincheck + +[ebisyncdb-postgres] +CONFIG = postgres:///libeufincheck +\ No newline at end of file diff --git a/testbench/src/main/kotlin/Main.kt b/testbench/src/main/kotlin/Main.kt @@ -140,7 +140,7 @@ class Cli : CliktCommand() { AZURE_CONTAINER = test [ebisync-submit] - SOURCE = sync-api + SOURCE = ebisync-api AUTH_METHOD = none [libeufin-nexusdb-postgres]