config.rs (3458B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2025 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 base64::{Engine, prelude::BASE64_STANDARD}; 20 use sqlx::postgres::PgConnectOptions; 21 use taler_common::{ 22 config::{Section, ValueErr}, 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_STANDARD.encode(format!("{username}:{password}"))) 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" => { 71 Ok(AuthCfg::None) 72 }, 73 "basic" => { 74 Ok(AuthCfg::Basic { 75 username: sect.str("USERNAME").require()?, 76 password: sect.str("PASSWORD").require()? 77 }) 78 }, 79 "bearer" => { 80 let token = sect.str("AUTH_TOKEN").opt()?; 81 if let Some(token) = token { 82 Ok(AuthCfg::Bearer(token)) 83 } else { 84 Ok(AuthCfg::Bearer(sect.str("TOKEN").require()?)) 85 } 86 } 87 ) 88 .require()?; 89 Some(Self { auth }) 90 } else { 91 None 92 }) 93 } 94 } 95 96 impl Serve { 97 pub fn parse(sect: Section) -> Result<Self, ValueErr> { 98 map_config!(sect, "serve", "SERVE", 99 "tcp" => { 100 let port = sect.number("PORT").require()?; 101 let ip: IpAddr = sect.parse("IP addr", "BIND_TO").require()?; 102 Ok::<Serve, ValueErr>(Serve::Tcp(SocketAddr::new(ip, port))) 103 }, 104 "unix" => { 105 let path = sect.path("UNIXPATH").require()?; 106 let permission = sect.unix_mode("UNIXPATH_MODE").require()?; 107 Ok::<Serve, ValueErr>(Serve::Unix { path, permission }) 108 } 109 ) 110 .require() 111 } 112 }