avam-client and oauth2

This commit is contained in:
2024-10-17 00:56:02 +02:00
parent bfc5cbf624
commit f93eb3c429
50 changed files with 5674 additions and 277 deletions

180
avam-client/src/main.rs Normal file
View File

@@ -0,0 +1,180 @@
#![allow(clippy::needless_return)]
mod app;
mod config;
mod dirs;
mod icon;
mod lock;
mod models;
mod oauth;
mod pipe;
mod state_machine;
use crate::config::Config;
use clap::Parser;
use lock::Lock;
use oauth::{start_code_listener, start_code_to_token};
use pipe::Pipe;
use state_machine::Event;
use tokio::task::JoinSet;
pub static BASE_URL: &str = "https://avam.avii.nl";
pub static PROJECT_NAME: &str = "Avii's Virtual Airline Manager";
pub static COPYRIGHT: &str = "Avii's Virtual Airline Manager © 2024";
pub static CLIENT_ID: uuid::Uuid = uuid::uuid!("f9525060-0a34-4233-87e2-0f9990b7c6db");
pub static REDIRECT_URI: &str = "avam:token";
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
pub struct Arguments {
#[arg(short, long)]
code: Option<String>,
#[arg(short, long, action)]
force: bool,
}
#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
let (event_sender, event_receiver) = tokio::sync::broadcast::channel(1);
let args = Arguments::parse();
if handle_single_instance(&args).await? {
return Ok(());
}
register_url_scheme()?;
let config = Config::new()?;
let mut futures = JoinSet::new();
// Register Quit handler
let sender = event_sender.clone();
let mut ctrl_c_counter = 0;
ctrlc::set_handler(move || {
println!("CTRL_C: Quit singal sent");
ctrl_c_counter += 1;
if ctrl_c_counter >= 3 {
let _ = unregister_url_scheme();
Lock::unlock();
std::process::exit(1);
}
if let Err(e) = sender.send(Event::Quit) {
println!("{:#?}", e)
};
})?;
// Start the State Machine
let c = config.clone();
let sender = event_sender.clone();
let receiver = event_receiver.resubscribe();
futures.spawn(state_machine::start(c, sender, receiver));
// // Start the code listener
let receiver = event_receiver.resubscribe();
let (pipe_sender, pipe_receiver) = tokio::sync::broadcast::channel(100);
futures.spawn(start_code_listener(pipe_sender, receiver));
// Start token listener
let c = config.clone();
let sender = event_sender.clone();
let receiver = event_receiver.resubscribe();
futures.spawn(start_code_to_token(c, pipe_receiver, sender, receiver));
// Start the Tray Icon
let c = config.clone();
let sender = event_sender.clone();
let receiver = event_receiver.resubscribe();
start_tray_icon(c, sender, receiver).await?;
// Wait for everything to finish
while let Some(result) = futures.join_next().await {
if let Ok(Err(e)) = result {
panic!("{:#?}", e);
}
}
// Cleanup
unregister_url_scheme()?;
Lock::unlock();
Ok(())
}
use app::App;
use tokio::sync::broadcast::{Receiver, Sender};
use winit::event_loop::EventLoop;
async fn start_tray_icon(
config: Config,
sender: Sender<Event>,
receiver: Receiver<Event>,
) -> Result<(), anyhow::Error> {
let mut app = App::new(config, sender, receiver)?;
let event_loop = EventLoop::new()?;
event_loop.run_app(&mut app)?;
println!("EventLoop Shutdonw");
Ok(())
}
//
//
//
//
//
//
//
//
//
//
//
//
/// returns `Ok(true)` if we need to quit gracefully
/// returns `Err(e)` if we're already running
async fn handle_single_instance(args: &Arguments) -> Result<bool, anyhow::Error> {
let lock = Lock::new(args.force)?;
if lock.is_locked() && args.code.is_none() {
return Err(anyhow::anyhow!("Lockfile exists, exiting."));
}
if let Some(code) = &args.code {
Pipe::send(code).await?;
return Ok(true);
}
Lock::lock();
Ok(false)
}
fn register_url_scheme() -> Result<(), anyhow::Error> {
use winreg::enums::*;
use winreg::RegKey;
let hkcu = RegKey::predef(HKEY_CURRENT_USER);
let avam_schema_root = hkcu.create_subkey("Software\\Classes\\avam")?;
avam_schema_root.0.set_value("URL Protocol", &"")?;
let command = avam_schema_root.0.create_subkey("shell\\open\\command")?;
let current_exec = std::env::current_exe()?;
command.0.set_value(
"",
&format!("\"{}\" -c \"%1\"", current_exec.to_str().unwrap()),
)?;
Ok(())
}
fn unregister_url_scheme() -> Result<(), anyhow::Error> {
use winreg::enums::*;
use winreg::RegKey;
let hkcu = RegKey::predef(HKEY_CURRENT_USER);
hkcu.delete_subkey_all("Software\\Classes\\avam").ok();
Ok(())
}