libeufin

Integration and sandbox testing for FinTech APIs and data formats
Log | Files | Refs | Submodules | README | LICENSE

SecurityTest.kt (3309B)


      1 /*
      2  * This file is part of LibEuFin.
      3  * Copyright (C) 2023-2024 Taler Systems S.A.
      4 
      5  * LibEuFin is free software; you can redistribute it and/or modify
      6  * it under the terms of the GNU Affero General Public License as
      7  * published by the Free Software Foundation; either version 3, or
      8  * (at your option) any later version.
      9 
     10  * LibEuFin is distributed in the hope that it will be useful, but
     11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General
     13  * Public License for more details.
     14 
     15  * You should have received a copy of the GNU Affero General Public
     16  * License along with LibEuFin; see the file COPYING.  If not, see
     17  * <http://www.gnu.org/licenses/>
     18  */
     19 
     20 import io.ktor.client.request.*
     21 import io.ktor.http.*
     22 import io.ktor.http.content.*
     23 import kotlinx.serialization.json.Json
     24 import org.junit.Test
     25 import tech.libeufin.common.*
     26 import tech.libeufin.common.test.*
     27 
     28 inline fun <reified B> HttpRequestBuilder.jsonDeflate(b: B) {
     29     val json = Json.encodeToString(kotlinx.serialization.serializer<B>(), b)
     30     contentType(ContentType.Application.Json)
     31     headers[HttpHeaders.ContentEncoding] = "deflate"
     32     setBody(json.toByteArray().inputStream().deflate().readBytes())
     33 }
     34 
     35 inline fun <reified B> HttpRequestBuilder.jsonStreamDeflate(b: B) {
     36     val json = Json.encodeToString(kotlinx.serialization.serializer<B>(), b)
     37     headers[HttpHeaders.ContentEncoding] = "deflate"
     38     setBody(OutputStreamContent({
     39         write(json.toByteArray().inputStream().deflate().readBytes())
     40     }, ContentType.Application.Json))
     41 }
     42 
     43 inline fun <reified B> HttpRequestBuilder.jsonStream(b: B) {
     44     val json = Json.encodeToString(kotlinx.serialization.serializer<B>(), b)
     45     setBody(OutputStreamContent({
     46         write(json.toByteArray())
     47     }, ContentType.Application.Json))
     48 }
     49 
     50 class SecurityTest {
     51     @Test
     52     fun bodySizeLimit() = bankSetup {
     53         val valid_req = obj {
     54             "payto_uri" to "$exchangePayto?message=payout"
     55             "amount" to "KUDOS:0.3"
     56         }
     57         val too_big = obj(valid_req) {
     58             "payto_uri" to "$exchangePayto?message=payout${"A".repeat(MAX_BODY_LENGTH+1)}"
     59         }
     60 
     61         client.postA("/accounts/merchant/transactions") {
     62             json(valid_req)
     63         }.assertOk()
     64         
     65         // Check body too big
     66         client.postA("/accounts/merchant/transactions") {
     67             json(too_big)
     68         }.assertPayloadTooLarge()
     69 
     70         // Check body too big even after compression
     71         client.postA("/accounts/merchant/transactions") {
     72             jsonDeflate(too_big)
     73         }.assertPayloadTooLarge()
     74 
     75         // Check streaming body too big
     76         client.postA("/accounts/merchant/transactions") {
     77             jsonStream(too_big)
     78         }.assertPayloadTooLarge()     
     79 
     80         // Check streaming body too big even after compression
     81         client.postA("/accounts/merchant/transactions") {
     82             jsonStreamDeflate(too_big)
     83         }.assertPayloadTooLarge()
     84 
     85         // Check unknown encoding
     86         client.postA("/accounts/merchant/transactions") {
     87             headers[HttpHeaders.ContentEncoding] = "unknown"
     88             json(valid_req)
     89         }.assertStatus(HttpStatusCode.UnsupportedMediaType, TalerErrorCode.GENERIC_COMPRESSION_INVALID)
     90     }
     91 }
     92 
     93 
     94