1
0
mirror of https://gitlab.com/comunic/comunicapiv3 synced 2024-11-26 07:19:22 +00:00
comunicapiv3/src/main.rs

174 lines
4.8 KiB
Rust
Raw Normal View History

2021-02-13 15:36:39 +00:00
use comunic_server::{cleanup_thread, server};
use comunic_server::data::admin::NewAdmin;
2020-05-20 17:05:59 +00:00
use comunic_server::data::config::{conf, Config};
use comunic_server::data::error::Res;
use comunic_server::data::user::UserID;
use comunic_server::helpers::{account_helper, admin_account_helper, database};
2021-05-04 17:36:31 +00:00
use comunic_server::utils::date_utils::current_year;
2020-05-22 06:51:15 +00:00
type MainActionFunction = Res;
2021-05-04 17:18:47 +00:00
struct Action {
name: String,
description: String,
arguments: Vec<String>,
function: Box<dyn Fn(Vec<String>) -> MainActionFunction>,
2021-05-04 17:36:31 +00:00
}
fn get_actions() -> Vec<Action> {
vec![
// Start server
Action {
name: "serve".to_string(),
description: "Start the Comunic Server (default action)".to_string(),
arguments: vec![],
function: Box::new(serve),
},
// Show help
Action {
name: "help".to_string(),
description: "Show this help".to_string(),
arguments: vec![],
function: Box::new(help),
},
// Reset password
Action {
name: "reset_password".to_string(),
description: "Create a password reset URL for a user".to_string(),
arguments: vec!["user_id".to_string()],
function: Box::new(reset_password),
},
// Create a new administrator
Action {
name: "create_admin".to_string(),
description: "Create a new administrator account".to_string(),
arguments: vec!["name".to_string(), "email".to_string()],
function: Box::new(create_admin),
},
2021-05-04 17:36:31 +00:00
]
2021-05-04 17:18:47 +00:00
}
2020-05-21 13:28:07 +00:00
#[actix_rt::main]
async fn main() -> std::io::Result<()> {
2021-05-04 17:18:47 +00:00
let args: Vec<String> = std::env::args().collect();
let conf_file = match args.get(1) {
Some(el) => el.to_string(),
None => {
eprintln!("Please specify configuration file as first argument!");
std::process::exit(-3);
}
2021-02-12 16:35:26 +00:00
};
2020-05-20 17:05:59 +00:00
// Load configuration
2021-02-12 16:35:26 +00:00
Config::load(&conf_file).expect("Could not load configuration!");
2020-05-20 17:05:59 +00:00
2020-05-21 07:21:58 +00:00
// Connect to the database
database::connect(&conf().database).expect("Could not connect to database!");
2020-05-20 17:05:59 +00:00
2021-05-04 17:18:47 +00:00
// Get selected action
let action = args
.get(2)
.map(|a| a.as_str())
.unwrap_or("serve")
.to_string();
2021-05-04 17:36:31 +00:00
let actions = get_actions();
let selected_action = actions
.iter()
.filter(|p| p.name.eq(&action))
.next();
let selected_action = match selected_action {
None => {
eprintln!("Action {} invalid! For more information try 'help'!", action);
std::process::exit(-1);
}
Some(a) => a
};
if !selected_action.arguments.is_empty() && selected_action.arguments.len() + 3 != args.len() {
2021-05-04 17:36:31 +00:00
eprintln!("Invalid number of arguments!");
std::process::exit(-2);
}
2021-05-05 05:38:40 +00:00
let args = match args.len() {
0 | 1 | 2 => vec![],
_ => (&args[3..]).to_vec()
};
let res = (selected_action.function)(args.to_vec());
res.expect("Failed to execute action!");
2021-05-04 17:36:31 +00:00
Ok(())
2020-05-20 15:46:05 +00:00
}
2021-05-04 17:18:47 +00:00
/// Start Comunic Server (main action)
fn serve(_a: Vec<String>) -> Res {
2021-05-04 17:18:47 +00:00
let t = std::thread::spawn(|| {
let sys = actix::System::new("sys");
let promise = async {
// Start cleanup thread
cleanup_thread::start().expect("Failed to start cleanup thread!");
// Start the server
server::start_server(conf()).await
};
tokio::runtime::Runtime::new().unwrap().block_on(promise)
.expect("Failed to start server!");
let _ = sys.run();
});
t.join().unwrap();
2021-05-04 17:36:31 +00:00
Ok(())
}
fn help(_a: Vec<String>) -> Res {
2021-05-04 17:36:31 +00:00
println!("Comunic API v3 Server - (c) Pierre HUBERT 2012 - {}", current_year());
println!("Usage: {} [conf-file] [action] [args...]", std::env::args().next().unwrap());
2021-05-04 17:36:31 +00:00
println!("Available actions:");
for action in get_actions() {
println!("\t{}\t{} - {}",
action.name,
action.arguments.iter().map(|s| format!("[{}]", s)).collect::<Vec<String>>().join(" "),
action.description
);
}
Ok(())
}
fn reset_password(args: Vec<String>) -> Res {
let user_id = UserID::new(args[0].parse::<u64>()?);
let token = account_helper::generate_password_reset_token(&user_id)?;
println!("{}", conf().password_reset_url.replace("{TOKEN}", &token));
Ok(())
}
fn create_admin(args: Vec<String>) -> Res {
let new_admin = NewAdmin {
name: args[0].to_string(),
email: args[1].to_string(),
};
if !mailchecker::is_valid(&new_admin.email) {
eprintln!("Specified email address is not valid!");
std::process::exit(-1);
}
let id = admin_account_helper::create(&new_admin)
.expect("Failed to create account!");
println!("* New admin ID: {}", id.id());
2021-05-04 17:18:47 +00:00
Ok(())
}