taler-rust

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

main.rs (5002B)


      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 anyhow::bail;
     18 use clap::Parser;
     19 use taler_api::config::{ApiCfg, AuthCfg};
     20 use taler_build::long_version;
     21 use taler_common::{CommonArgs, cli::ConfigCmd, config::Config, taler_main};
     22 use taler_magnet_bank::{
     23     config::{ServeCfg, WorkerCfg, parse_account_payto},
     24     constants::CONFIG_SOURCE,
     25     db::{dbinit, pool},
     26     dev::{self, DevCmd},
     27     run_serve, setup,
     28     worker::run_worker,
     29 };
     30 
     31 #[derive(clap::Parser, Debug)]
     32 #[command(long_version = long_version(), about, long_about = None)]
     33 struct Args {
     34     #[clap(flatten)]
     35     common: CommonArgs,
     36 
     37     #[command(subcommand)]
     38     cmd: Command,
     39 }
     40 
     41 #[derive(clap::Subcommand, Debug)]
     42 enum Command {
     43     /// Initialize taler-magnet-bank database
     44     Dbinit {
     45         /// Reset database (DANGEROUS: All existing data is lost)
     46         #[clap(long, short)]
     47         reset: bool,
     48     },
     49     /// Setup taler-magnet-bank auth token and account settings for Wire Gateway use
     50     Setup {
     51         /// Reset connection info and overwrite keys file
     52         #[clap(long, short)]
     53         reset: bool,
     54     },
     55     /// Run taler-magnet-bank worker
     56     Worker {
     57         /// Execute once and return
     58         #[clap(long, short)]
     59         transient: bool,
     60     },
     61     /// Run taler-magnet-bank HTTP server
     62     Serve {
     63         /// Check whether an API is in use (if it's useful to start the HTTP
     64         /// server). Exit with 0 if at least one API is enabled, otherwise 1
     65         #[clap(long)]
     66         check: bool,
     67     },
     68     #[command(subcommand)]
     69     TalerDeployment(TalerDeployment),
     70     /// Hidden dev commands
     71     #[command(subcommand, hide(true))]
     72     Dev(DevCmd),
     73     #[command(subcommand)]
     74     Config(ConfigCmd),
     75 }
     76 
     77 /// Helpers to integrate taler-magnet-bank with taler-exchange
     78 #[derive(clap::Subcommand, Debug)]
     79 enum TalerDeployment {
     80     /// Output the exchange payto
     81     ExchangePayto,
     82     /// Output the wire gateway credentials configuration
     83     WireGatewayCredentials,
     84 }
     85 
     86 async fn run(cmd: Command, cfg: &Config) -> anyhow::Result<()> {
     87     match cmd {
     88         Command::Dbinit { reset } => {
     89             dbinit(cfg, reset).await?;
     90         }
     91         Command::Setup { reset } => {
     92             let cfg = WorkerCfg::parse(cfg)?;
     93             setup::setup(cfg, reset).await?
     94         }
     95         Command::Serve { check } => {
     96             if check {
     97                 let cfg = ServeCfg::parse(cfg)?;
     98                 if cfg.revenue.is_none() && cfg.wire_gateway.is_none() {
     99                     std::process::exit(1);
    100                 }
    101             } else {
    102                 let pool = pool(cfg).await?;
    103                 run_serve(cfg, pool).await?;
    104             }
    105         }
    106         Command::Worker { transient } => {
    107             let pool = pool(cfg).await?;
    108             let client = http_client::client()?;
    109             run_worker(cfg, &pool, &client, transient).await?;
    110         }
    111         Command::Config(cmd) => cmd.run(cfg)?,
    112         Command::Dev(cmd) => dev::dev(cfg, cmd).await?,
    113         Command::TalerDeployment(cmd) => match cmd {
    114             TalerDeployment::ExchangePayto => {
    115                 let payto = parse_account_payto(cfg)?;
    116                 println!("{payto}");
    117             }
    118             TalerDeployment::WireGatewayCredentials => {
    119                 let wire_gateway =
    120                     ApiCfg::parse(cfg.section("magnet-bank-httpd-wire-gateway-api"))?;
    121                 let Some(wire_gateway) = wire_gateway else {
    122                     bail!("Wire Gateway API is disabled");
    123                 };
    124 
    125                 match wire_gateway.auth {
    126                     AuthCfg::Basic { username, password } => {
    127                         println!("WIRE_GATEWAY_AUTH_METHOD = basic");
    128                         println!("USERNAME = {username}");
    129                         println!("PASSWORD = {password}");
    130                     }
    131                     AuthCfg::Bearer(token) => {
    132                         println!("WIRE_GATEWAY_AUTH_METHOD = bearer");
    133                         println!("TOKEN = {token}");
    134                     }
    135                     AuthCfg::None => {
    136                         println!("WIRE_GATEWAY_AUTH_METHOD = none");
    137                     }
    138                 }
    139             }
    140         },
    141     }
    142     Ok(())
    143 }
    144 
    145 fn main() {
    146     let args = Args::parse();
    147     taler_main(CONFIG_SOURCE, args.common, |cfg| async move {
    148         run(args.cmd, &cfg).await
    149     });
    150 }