[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libeufin] branch master updated: demobank notes and skeleton
From: |
gnunet |
Subject: |
[libeufin] branch master updated: demobank notes and skeleton |
Date: |
Tue, 05 Oct 2021 16:55:20 +0200 |
This is an automated email from the git hooks/post-receive script.
dold pushed a commit to branch master
in repository libeufin.
The following commit(s) were added to refs/heads/master by this push:
new fe31400 demobank notes and skeleton
fe31400 is described below
commit fe314003549494e604685b37d6d1d92cb959ad7e
Author: Florian Dold <florian@dold.me>
AuthorDate: Tue Oct 5 16:55:13 2021 +0200
demobank notes and skeleton
---
.../src/main/kotlin/tech/libeufin/sandbox/DB.kt | 20 ++++
.../src/main/kotlin/tech/libeufin/sandbox/Main.kt | 105 ++++++++++++++++++---
2 files changed, 113 insertions(+), 12 deletions(-)
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
index ef6d370..65b9533 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
@@ -87,6 +87,7 @@ enum class KeyState {
RELEASED
}
+// FIXME: This should be DemobankConfigTable!
object SandboxConfigsTable : LongIdTable() {
val currency = text("currency")
val allowRegistrations = bool("allowRegistrations")
@@ -109,6 +110,11 @@ class SandboxConfigEntity(id: EntityID<Long>) :
LongEntity(id) {
* as those get only paired with Ebics subscribers! Eventually, a
* Ebics subscriber should map to a SandboxUserEntity that in turn
* will own bank accounts.
+ *
+ * FIXME: Do we really need normal users and superusers for the sandbox?
+ * => Nope, we don't even want user management for the sandbox!
+ * => This table must be killed, instead we just read the admin token via env
variable
+ * and use a fixed "admin" user name.
*/
object SandboxUsersTable : LongIdTable() {
val username = text("username")
@@ -130,6 +136,19 @@ class SandboxUserEntity(id: EntityID<Long>) :
LongEntity(id) {
}
+/**
+ * Users who are allowed to log into the demo bank.
+ * Created via the /demobanks/{demobankname}/register endpoint.
+ */
+object DemobankUsersTable : LongIdTable() {
+ // FIXME: ...
+ // var isPublic = ...
+ // var demobankConfig (=> which demobank is this user part of)
+ // ...
+ // FIXME: Must have a mandatory foreign key reference into
BankAccountTransactionsTable
+}
+
+
/**
* This table stores RSA public keys of subscribers.
*/
@@ -284,6 +303,7 @@ object EbicsUploadTransactionChunksTable :
IdTable<String>() {
val chunkContent = blob("chunkContent")
}
+// FIXME: Is upload chunking not implemented somewhere?!
class EbicsUploadTransactionChunkEntity(id: EntityID<String>) :
Entity<String>(id) {
companion object : EntityClass<String,
EbicsUploadTransactionChunkEntity>(EbicsUploadTransactionChunksTable)
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
index 5848d44..f70f7ed 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
@@ -17,11 +17,27 @@
* <http://www.gnu.org/licenses/>
*/
+
+/*
+General thoughts:
+
+ - since sandbox will run on the public internet for the demobank, all
endpoints except
+ explicitly public ones should use authentication (basic auth)
+ - the authentication should be *very* simple and *not* be part of the
database state.
+ instead, a LIBEUFIN_SANDBOX_ADMIN_TOKEN environment variable will be used to
+ set the authentication.
+
+ - All sandbox will require the ADMIN_TOKEN, except:
+ - the /ebicsweb endpoint, because EBICS handles authentication here
+ (EBICS subscribers are checked)
+ - the /demobank(/...) endpoints (except registration and public accounts),
+ because authentication is handled by checking the demobank user
credentials
+ */
+
package tech.libeufin.sandbox
import UtilError
import com.fasterxml.jackson.core.JsonParseException
-import com.fasterxml.jackson.core.JsonParser
import io.ktor.application.ApplicationCallPipeline
import io.ktor.application.call
import io.ktor.application.install
@@ -30,9 +46,6 @@ import io.ktor.features.ContentNegotiation
import io.ktor.features.StatusPages
import io.ktor.response.respond
import io.ktor.response.respondText
-import io.ktor.routing.get
-import io.ktor.routing.post
-import io.ktor.routing.routing
import io.ktor.server.engine.embeddedServer
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.transactions.transaction
@@ -66,8 +79,8 @@ import execThrowableOrTerminate
import io.ktor.application.ApplicationCall
import io.ktor.auth.*
import io.ktor.http.*
-import io.ktor.http.content.*
import io.ktor.request.*
+import io.ktor.routing.*
import io.ktor.server.netty.*
import io.ktor.util.date.*
import kotlinx.coroutines.newSingleThreadContext
@@ -90,7 +103,8 @@ const val SANDBOX_DB_ENV_VAR_NAME =
"LIBEUFIN_SANDBOX_DB_CONNECTION"
data class SandboxError(
val statusCode: HttpStatusCode,
val reason: String,
- val errorCode: LibeufinErrorCode? = null) : Exception()
+ val errorCode: LibeufinErrorCode? = null
+) : Exception()
data class SandboxErrorJson(val error: SandboxErrorDetailJson)
data class SandboxErrorDetailJson(val type: String, val description: String)
@@ -181,7 +195,7 @@ class Camt053Tick : CliktCommand(
Database.connect(dbConnString)
dbCreateTables(dbConnString)
transaction {
- BankAccountEntity.all().forEach { accountIter->
+ BankAccountEntity.all().forEach { accountIter ->
/**
* Map of 'account name' -> fresh history
*/
@@ -222,12 +236,14 @@ class Camt053Tick : CliktCommand(
}
}
}
+
class MakeTransaction : CliktCommand("Wire-transfer money between Sandbox bank
accounts") {
init {
context {
helpFormatter = CliktHelpFormatter(showDefaultValues = true)
}
}
+
private val creditAccount by option(help = "Label of the bank account
receiving the payment").required()
private val debitAccount by option(help = "Label of the bank account
issuing the payment").required()
private val amount by argument(help = "Amount, in the \$currency:x.y
format")
@@ -350,7 +366,8 @@ fun main(args: Array<String>) {
ResetTables(),
Config(),
MakeTransaction(),
- Camt053Tick()).main(args)
+ Camt053Tick()
+ ).main(args)
}
suspend inline fun <reified T : Any> ApplicationCall.receiveJson(): T {
@@ -493,7 +510,7 @@ fun serverMain(dbName: String, port: Int) {
requireSuperuser(call.request)
val body = call.receiveJson<CamtParams>()
val bankaccount = getAccountFromLabel(body.bankaccount)
- if(body.type != 53) throw SandboxError(
+ if (body.type != 53) throw SandboxError(
HttpStatusCode.NotFound,
"Only Camt.053 documents can be generated."
)
@@ -589,7 +606,7 @@ fun serverMain(dbName: String, port: Int) {
}
call.respond(object {})
}
-
+
/**
* Associates a new bank account with an existing Ebics subscriber.
*/
@@ -606,7 +623,7 @@ fun serverMain(dbName: String, port: Int) {
body.subscriber.hostID
)
val check = BankAccountEntity.find {
- BankAccountsTable.iban eq body.iban
or(BankAccountsTable.label eq body.label)
+ BankAccountsTable.iban eq body.iban or
(BankAccountsTable.label eq body.label)
}.count()
if (check > 0) throw SandboxError(
HttpStatusCode.BadRequest,
@@ -845,7 +862,7 @@ fun serverMain(dbName: String, port: Int) {
*/
catch (e: SandboxError) {
// Should translate to EBICS error code.
- when(e.errorCode) {
+ when (e.errorCode) {
LibeufinErrorCode.LIBEUFIN_EC_INVALID_STATE -> throw
EbicsProcessingError("Invalid bank state.")
LibeufinErrorCode.LIBEUFIN_EC_INCONSISTENT_STATE ->
throw EbicsProcessingError("Inconsistent bank state.")
else -> throw EbicsProcessingError("Unknown LibEuFin
error code: ${e.errorCode}.")
@@ -909,6 +926,7 @@ fun serverMain(dbName: String, port: Int) {
)
call.respond(object {
val name = "taler-bank-integration"
+
// FIXME: use actual version here!
val version = "0:0:0"
val currency = currencyEnv
@@ -998,6 +1016,69 @@ fun serverMain(dbName: String, port: Int) {
})
return@post
}
+
+ // Create a new demobank instance with a particular currency,
+ // debt limit and possibly other configuration
+ // (could also be a CLI command for now)
+ post("/demobanks") {
+
+ }
+
+ // List configured demobanks
+ get("/demobanks") {
+
+ }
+
+ delete("/demobank/{demobankid") {
+
+ }
+
+ get("/demobank/{demobankid") {
+
+ }
+
+ route("/demobank/{demobankid}") {
+ // Note: Unlike the old pybank, the sandbox does *not*
actually expose the
+ // taler wire gateway API, because the exchange uses the nexus.
+
+ // Endpoint(s) for making arbitrary payments in the sandbox
for integration tests
+ // FIXME: Do we actually need this, or can we just use the
sandbox admin APIs?
+ route("/testing-api") {
+
+ }
+
+ route("/access-api") {
+ get("/accounts/{account_name}") {
+ // Authenticated. Accesses basic information (balance)
+ // about an account. (see docs)
+
+ // FIXME: Since we now use IBANs everywhere, maybe the
account should also be assigned an IBAN
+ }
+
+ get("/accounts/{account_name}/history") {
+ // New endpoint, access account history to display in
the SPA
+ // (could be merged with GET /accounts/{account_name}
+ }
+
+ // [...]
+
+ get("/public-accounts") {
+ // List public accounts. Does not require any
authentication.
+ // XXX: New!
+ }
+
+ get("/public-accounts/{account_name}/history") {
+ // Get transaction history of a public account
+ }
+
+ post("/testing/register") {
+ // Register a new account.
+ // No authentication is required to register a new
user.
+ // FIXME: Should probably not use "testing" as the
prefix, since it's used "in production" in the demobank SPA
+ }
+ }
+
+ }
}
}
logger.info("LibEuFin Sandbox running on port $port")
--
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: demobank notes and skeleton,
gnunet <=