gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libeufin] branch master updated: add --no-auth possibility to facilitat


From: gnunet
Subject: [libeufin] branch master updated: add --no-auth possibility to facilitate tests
Date: Thu, 14 Oct 2021 14:25:00 +0200

This is an automated email from the git hooks/post-receive script.

ms pushed a commit to branch master
in repository libeufin.

The following commit(s) were added to refs/heads/master by this push:
     new 5e8e7f7  add --no-auth possibility to facilitate tests
5e8e7f7 is described below

commit 5e8e7f7fd216a7d9c7f52bca8d53b93d96c29706
Author: ms <ms@taler.net>
AuthorDate: Thu Oct 14 14:24:28 2021 +0200

    add --no-auth possibility to facilitate tests
---
 .../src/main/kotlin/tech/libeufin/sandbox/Main.kt  | 54 ++++++++++++++--------
 util/src/main/kotlin/Config.kt                     |  9 ++++
 util/src/main/kotlin/HTTP.kt                       | 27 +++++++----
 util/src/main/kotlin/UnixDomainSocket.kt           |  5 +-
 4 files changed, 67 insertions(+), 28 deletions(-)

diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt 
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
index 559e7eb..d3ec449 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
@@ -82,11 +82,11 @@ import javax.xml.bind.JAXBContext
 import kotlin.system.exitProcess
 
 private val logger: Logger = LoggerFactory.getLogger("tech.libeufin.sandbox")
-private val currencyEnv: String? = getValueFromEnv("LIBEUFIN_SANDBOX_CURRENCY")
-private val envName: String? = getValueFromEnv("TALER_ENV_NAME")
+private val currencyEnv: String? = System.getenv("LIBEUFIN_SANDBOX_CURRENCY")
+private val envName: String? = System.getenv("TALER_ENV_NAME")
 const val SANDBOX_DB_ENV_VAR_NAME = "LIBEUFIN_SANDBOX_DB_CONNECTION"
-// when null, privileged operations turn impossible
-private val sandboxToken: String? = getValueFromEnv("LIBEUFIN_SANDBOX_TOKEN")
+private val adminPassword: String? = 
System.getenv("LIBEUFIN_SANDBOX_ADMIN_PASSWORD")
+private var WITH_AUTH = true
 
 data class SandboxError(
     val statusCode: HttpStatusCode,
@@ -240,6 +240,10 @@ class Serve : CliktCommand("Run sandbox HTTP server") {
         }
     }
 
+    private val auth by option(
+        "--auth",
+        help = "Disable authentication."
+    ).flag("--no-auth", default = true)
     private val logLevel by option()
     private val port by option().int().default(5000)
     private val withUnixSocket by option(
@@ -248,6 +252,7 @@ class Serve : CliktCommand("Run sandbox HTTP server") {
     )
 
     override fun run() {
+        WITH_AUTH = auth
         setLogLevel(logLevel)
         execThrowableOrTerminate { 
dbCreateTables(getDbConnFromEnv(SANDBOX_DB_ENV_VAR_NAME)) }
         if (withUnixSocket != null) {
@@ -448,6 +453,19 @@ val sandboxApp: Application.() -> Unit = {
             )
         }
     }
+    intercept(ApplicationCallPipeline.Setup) {
+        /**
+         * Allows disabling authentication during tests.
+         */
+        call.application.apply {
+            attributes.put(AttributeKey("withAuth"), WITH_AUTH)
+        }
+        call.application.apply {
+            if (adminPassword != null) {
+                call.attributes.put(AttributeKey("adminPassword"), 
adminPassword)
+            }
+        }
+    }
     intercept(ApplicationCallPipeline.Fallback) {
         if (this.call.response.status() == null) {
             call.respondText(
@@ -467,7 +485,7 @@ val sandboxApp: Application.() -> Unit = {
         // Respond with the last statement of the requesting account.
         // Query details in the body.
         post("/admin/payments/camt") {
-            call.request.authWithToken(sandboxToken)
+            call.request.basicAuth()
             val body = call.receiveJson<CamtParams>()
             val bankaccount = getAccountFromLabel(body.bankaccount)
             if (body.type != 53) throw SandboxError(
@@ -490,7 +508,7 @@ val sandboxApp: Application.() -> Unit = {
 
         // create a new bank account, no EBICS relation.
         post("/admin/bank-accounts/{label}") {
-            call.request.authWithToken(sandboxToken)
+            call.request.basicAuth()
             val body = call.receiveJson<BankAccountInfo>()
             transaction {
                 BankAccountEntity.new {
@@ -507,7 +525,7 @@ val sandboxApp: Application.() -> Unit = {
 
         // Information about one bank account.
         get("/admin/bank-accounts/{label}") {
-            call.request.authWithToken(sandboxToken)
+            call.request.basicAuth()
             val label = ensureNonNull(call.parameters["label"])
             val ret = transaction {
                 val bankAccount = tech.libeufin.sandbox.BankAccountEntity.find 
{
@@ -532,7 +550,7 @@ val sandboxApp: Application.() -> Unit = {
         // Book one incoming payment for the requesting account.
         // The debtor is not required to have an account at this Sandbox.
         post("/admin/bank-accounts/{label}/simulate-incoming-transaction") {
-            call.request.authWithToken(sandboxToken)
+            call.request.basicAuth()
             val body = call.receiveJson<IncomingPaymentInfo>()
             // FIXME: generate nicer UUID!
             val accountLabel = ensureNonNull(call.parameters["label"])
@@ -574,7 +592,7 @@ val sandboxApp: Application.() -> Unit = {
 
         // Associates a new bank account with an existing Ebics subscriber.
         post("/admin/ebics/bank-accounts") {
-            call.request.authWithToken(sandboxToken)
+            call.request.basicAuth()
             val body = call.receiveJson<BankAccountRequest>()
             if (!validateBic(body.bic)) {
                 throw SandboxError(io.ktor.http.HttpStatusCode.BadRequest, 
"invalid BIC (${body.bic})")
@@ -606,7 +624,7 @@ val sandboxApp: Application.() -> Unit = {
 
         // Information about all the bank accounts.
         get("/admin/bank-accounts") {
-            call.request.authWithToken(sandboxToken)
+            call.request.basicAuth()
             val accounts = mutableListOf<BankAccountInfo>()
             transaction {
                 tech.libeufin.sandbox.BankAccountEntity.all().forEach {
@@ -626,7 +644,7 @@ val sandboxApp: Application.() -> Unit = {
 
         // Details of all the transactions of one bank account.
         get("/admin/bank-accounts/{label}/transactions") {
-            call.request.authWithToken(sandboxToken)
+            call.request.basicAuth()
             val ret = AccountTransactions()
             transaction {
                 val accountLabel = ensureNonNull(call.parameters["label"])
@@ -669,7 +687,7 @@ val sandboxApp: Application.() -> Unit = {
         // one bank account.  Counterparts do not need to have an account
         // at this Sandbox.
         post("/admin/bank-accounts/{label}/generate-transactions") {
-            call.request.authWithToken(sandboxToken)
+            call.request.basicAuth()
             transaction {
                 val accountLabel = ensureNonNull(call.parameters["label"])
                 val account = getBankAccountFromLabel(accountLabel)
@@ -720,7 +738,7 @@ val sandboxApp: Application.() -> Unit = {
 
         // Creates a new Ebics subscriber.
         post("/admin/ebics/subscribers") {
-            call.request.authWithToken(sandboxToken)
+            call.request.basicAuth()
             val body = call.receiveJson<EbicsSubscriberElement>()
             transaction {
                 tech.libeufin.sandbox.EbicsSubscriberEntity.new {
@@ -741,7 +759,7 @@ val sandboxApp: Application.() -> Unit = {
 
         // Shows details of all the EBICS subscribers of this Sandbox.
         get("/admin/ebics/subscribers") {
-            call.request.authWithToken(sandboxToken)
+            call.request.basicAuth()
             val ret = AdminGetSubscribers()
             transaction {
                 tech.libeufin.sandbox.EbicsSubscriberEntity.all().forEach {
@@ -760,7 +778,7 @@ val sandboxApp: Application.() -> Unit = {
 
         // Change keys used in the EBICS communications.
         post("/admin/ebics/hosts/{hostID}/rotate-keys") {
-            call.request.authWithToken(sandboxToken)
+            call.request.basicAuth()
             val hostID: String = call.parameters["hostID"] ?: throw 
SandboxError(
                 io.ktor.http.HttpStatusCode.BadRequest, "host ID missing in 
URL"
             )
@@ -787,7 +805,7 @@ val sandboxApp: Application.() -> Unit = {
 
         // Create a new EBICS host
         post("/admin/ebics/hosts") {
-            call.request.authWithToken(sandboxToken)
+            call.request.basicAuth()
             val req = call.receiveJson<EbicsHostCreateRequest>()
             val pairA = tech.libeufin.util.CryptoUtil.generateRsaKeyPair(2048)
             val pairB = tech.libeufin.util.CryptoUtil.generateRsaKeyPair(2048)
@@ -811,7 +829,7 @@ val sandboxApp: Application.() -> Unit = {
 
         // Show the names of all the Ebics hosts
         get("/admin/ebics/hosts") {
-            call.request.authWithToken(sandboxToken)
+            call.request.basicAuth()
             val ebicsHosts = transaction {
                 tech.libeufin.sandbox.EbicsHostEntity.all().map { it.hostId }
             }
@@ -849,7 +867,7 @@ val sandboxApp: Application.() -> Unit = {
          * the default exchange, from a designated/constant customer.
          */
         get("/taler") {
-            call.request.authWithToken(sandboxToken)
+            call.request.basicAuth()
             SandboxAssert(
                 currencyEnv != null,
                 "Currency not found.  Logs should have warned"
diff --git a/util/src/main/kotlin/Config.kt b/util/src/main/kotlin/Config.kt
index 8a9aa43..de47466 100644
--- a/util/src/main/kotlin/Config.kt
+++ b/util/src/main/kotlin/Config.kt
@@ -4,6 +4,8 @@ import ch.qos.logback.classic.Level
 import ch.qos.logback.classic.LoggerContext
 import ch.qos.logback.classic.util.ContextInitializer
 import ch.qos.logback.core.util.Loader
+import io.ktor.application.*
+import io.ktor.util.*
 import org.slf4j.LoggerFactory
 import printLnErr
 import kotlin.system.exitProcess
@@ -50,6 +52,13 @@ fun setLogLevel(logLevel: String?) {
     }
 }
 
+internal fun <T : Any>ApplicationCall.getAttribute(name: String): T {
+    val key = AttributeKey<T>("name")
+    if (!this.attributes.contains(key))
+        throw internalServerError("Attribute $name not found along the call.")
+    return this.attributes[key]
+}
+
 fun getValueFromEnv(varName: String): String? {
     val ret = System.getenv(varName)
     if (ret.isNullOrBlank() or ret.isNullOrEmpty()) {
diff --git a/util/src/main/kotlin/HTTP.kt b/util/src/main/kotlin/HTTP.kt
index 78b9e04..a91c380 100644
--- a/util/src/main/kotlin/HTTP.kt
+++ b/util/src/main/kotlin/HTTP.kt
@@ -16,6 +16,8 @@ private fun unauthorized(msg: String): UtilError {
     )
 }
 
+
+
 /**
  * Returns the token (including the 'secret-token:' prefix)
  * from a Authorization header.  Throws exception on malformations
@@ -35,7 +37,7 @@ fun extractToken(authHeader: String): String {
     return "${tokenSplit[0]}:${URLDecoder.decode(tokenSplit[1], 
Charsets.UTF_8)}"
 }
 
-private fun internalServerError(
+internal fun internalServerError(
     reason: String,
     libeufinErrorCode: LibeufinErrorCode? = LibeufinErrorCode.LIBEUFIN_EC_NONE
 ): UtilError {
@@ -86,15 +88,22 @@ fun ApplicationRequest.getBaseUrl(): String {
  * @param tokenEnv is the authorization token that was found in the
  * environment.
  */
-fun ApplicationRequest.authWithToken(tokenEnv: String?) {
-    if (tokenEnv == null) {
-        logger.info("Authenticating operation without any env token!")
-        throw unauthorized("Authentication is not available now")
+fun ApplicationRequest.basicAuth() {
+    val withAuth = this.call.getAttribute<Boolean>("withAuth")
+    if (!withAuth) {
+        logger.info("Authentication is disabled - assuming tests currently 
running.")
+        return
+    }
+    val credentials = getHTTPBasicAuthCredentials(this)
+    if (credentials.first == "admin") {
+        val adminPassword = this.call.getAttribute<String>("adminPassword")
+        if (credentials.second != adminPassword) throw unauthorized(
+            "Admin authentication failed"
+        )
     }
-    val auth = this.headers[HttpHeaders.Authorization] ?:
-    throw unauthorized("Authorization header was not found in the request")
-    val tokenReq = extractToken(auth)
-    if (tokenEnv != tokenReq) throw unauthorized("Authentication failed, token 
did not match")
+    /**
+     * TODO: extract customer hashed password from the database and check.
+     */
 }
 
 fun getHTTPBasicAuthCredentials(request: ApplicationRequest): Pair<String, 
String> {
diff --git a/util/src/main/kotlin/UnixDomainSocket.kt 
b/util/src/main/kotlin/UnixDomainSocket.kt
index 448f1d5..aaea0a8 100644
--- a/util/src/main/kotlin/UnixDomainSocket.kt
+++ b/util/src/main/kotlin/UnixDomainSocket.kt
@@ -31,7 +31,10 @@ import java.io.ByteArrayInputStream
 import java.io.InputStream
 import java.nio.charset.Charset
 
-fun startServer(unixSocketPath: String, app: Application.() -> Unit) {
+fun startServer(
+    unixSocketPath: String,
+    app: Application.() -> Unit
+) {
     val boss = EpollEventLoopGroup()
     val worker = EpollEventLoopGroup()
     try {

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]