security.rs (3572B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2025, 2026 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or modify it under the 6 terms of the GNU Affero General Public License as published by the Free Software 7 Foundation; either version 3, or (at your option) any later version. 8 9 TALER is distributed in the hope that it will be useful, but WITHOUT ANY 10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 12 13 You should have received a copy of the GNU Affero General Public License along with 14 TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 17 use axum::http::{StatusCode, header}; 18 use common::setup; 19 use taler_api::constants::MAX_BODY_LENGTH; 20 use taler_common::{ 21 api_wire::{TransferRequest, TransferResponse}, 22 error_code::ErrorCode, 23 types::{ 24 amount::{Amount, Currency}, 25 base32::Base32, 26 payto::payto, 27 url, 28 }, 29 }; 30 use taler_test_utils::server::TestServer as _; 31 32 mod common; 33 34 #[tokio::test] 35 async fn body_parsing() { 36 let (server, _) = setup().await; 37 let eur: Currency = "EUR".parse().unwrap(); 38 let normal_body = TransferRequest { 39 request_uid: Base32::rand(), 40 amount: Amount::zero(&eur), 41 exchange_base_url: url("https://test.com"), 42 wtid: Base32::rand(), 43 credit_account: payto("payto:://test"), 44 metadata: None, 45 }; 46 47 // Check OK 48 server 49 .post("/taler-wire-gateway/transfer") 50 .json(&normal_body) 51 .deflate() 52 .await 53 .assert_ok_json::<TransferResponse>(); 54 55 // Headers check 56 server 57 .post("/taler-wire-gateway/transfer") 58 .json(&normal_body) 59 .remove(header::CONTENT_TYPE) 60 .await 61 .assert_error_status( 62 ErrorCode::GENERIC_HTTP_HEADERS_MALFORMED, 63 StatusCode::UNSUPPORTED_MEDIA_TYPE, 64 ); 65 server 66 .post("/taler-wire-gateway/transfer") 67 .json(&normal_body) 68 .deflate() 69 .remove(header::CONTENT_ENCODING) 70 .await 71 .assert_error(ErrorCode::GENERIC_JSON_INVALID); 72 server 73 .post("/taler-wire-gateway/transfer") 74 .json(&normal_body) 75 .header(header::CONTENT_TYPE, "invalid") 76 .await 77 .assert_error_status( 78 ErrorCode::GENERIC_HTTP_HEADERS_MALFORMED, 79 StatusCode::UNSUPPORTED_MEDIA_TYPE, 80 ); 81 server 82 .post("/taler-wire-gateway/transfer") 83 .json(&normal_body) 84 .header(header::CONTENT_ENCODING, "deflate") 85 .await 86 .assert_error(ErrorCode::GENERIC_COMPRESSION_INVALID); 87 server 88 .post("/taler-wire-gateway/transfer") 89 .json(&normal_body) 90 .header(header::CONTENT_ENCODING, "invalid") 91 .await 92 .assert_error_status( 93 ErrorCode::GENERIC_HTTP_HEADERS_MALFORMED, 94 StatusCode::UNSUPPORTED_MEDIA_TYPE, 95 ); 96 97 // Body size limit 98 let huge_body = TransferRequest { 99 credit_account: payto(format!( 100 "payto:://test?message={:A<1$}", 101 "payout", MAX_BODY_LENGTH 102 )), 103 ..normal_body 104 }; 105 server 106 .post("/taler-wire-gateway/transfer") 107 .json(&huge_body) 108 .await 109 .assert_error(ErrorCode::GENERIC_UPLOAD_EXCEEDS_LIMIT); 110 server 111 .post("/taler-wire-gateway/transfer") 112 .json(&huge_body) 113 .deflate() 114 .await 115 .assert_error(ErrorCode::GENERIC_UPLOAD_EXCEEDS_LIMIT); 116 }