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