config.rs (3392B)
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 std::net::{IpAddr, SocketAddr}; 18 19 use sqlx::postgres::PgConnectOptions; 20 use taler_common::{ 21 config::{Section, ValueErr}, 22 encoding::base64, 23 map_config, 24 }; 25 26 use crate::{Serve, auth::AuthMethod}; 27 28 /// Basic database config 29 pub struct DbCfg { 30 pub cfg: PgConnectOptions, 31 pub sql_dir: String, 32 } 33 34 impl DbCfg { 35 pub fn parse(sect: Section) -> Result<Self, ValueErr> { 36 Ok(Self { 37 cfg: sect.postgres("CONFIG").require()?, 38 sql_dir: sect.path("SQL_DIR").require()?, 39 }) 40 } 41 } 42 43 pub enum AuthCfg { 44 None, 45 Bearer(String), 46 Basic { username: String, password: String }, 47 } 48 49 impl AuthCfg { 50 pub fn method(&self) -> AuthMethod { 51 match self { 52 AuthCfg::None => AuthMethod::None, 53 AuthCfg::Bearer(token) => AuthMethod::Bearer(token.clone()), 54 AuthCfg::Basic { username, password } => { 55 AuthMethod::Basic(base64::encode(format!("{username}:{password}").as_bytes())) 56 } 57 } 58 } 59 } 60 61 /// Basic api config 62 pub struct ApiCfg { 63 pub auth: AuthCfg, 64 } 65 66 impl ApiCfg { 67 pub fn parse(sect: Section) -> Result<Option<Self>, ValueErr> { 68 Ok(if sect.boolean("ENABLED").require()? { 69 let auth = map_config!(sect, "auth_method", "AUTH_METHOD", 70 "none" => { AuthCfg::None }, 71 "basic" => { 72 AuthCfg::Basic { 73 username: sect.str("USERNAME").require()?, 74 password: sect.str("PASSWORD").require()? 75 } 76 }, 77 "bearer" => { 78 let token = sect.str("AUTH_TOKEN").opt()?; 79 if let Some(token) = token { 80 AuthCfg::Bearer(token) 81 } else { 82 AuthCfg::Bearer(sect.str("TOKEN").require()?) 83 } 84 } 85 ) 86 .require()?; 87 Some(Self { auth }) 88 } else { 89 None 90 }) 91 } 92 } 93 94 impl Serve { 95 pub fn parse(sect: Section) -> Result<Self, ValueErr> { 96 map_config!(sect, "serve", "SERVE", 97 "tcp" => { 98 let port = sect.number("PORT").require()?; 99 let ip: IpAddr = sect.parse("IP addr", "BIND_TO").require()?; 100 Serve::Tcp(SocketAddr::new(ip, port)) 101 }, 102 "unix" => { 103 let path = sect.path("UNIXPATH").require()?; 104 let permission = sect.unix_mode("UNIXPATH_MODE").require()?; 105 Serve::Unix { path, permission } 106 }, 107 "systemd" => { Serve::Systemd } 108 ) 109 .require() 110 } 111 }