taler-rust

GNU Taler code in Rust. Largely core banking integrations.
Log | Files | Refs | Submodules | README | LICENSE

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 }