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 }