X-Git-Url: http://git.euphorik.ch/?a=blobdiff_plain;f=src%2Fmain.rs;h=15b9c025f67bb86acb9d93be0d2b1e89c0272c07;hb=331dddcaef970033db01dc9d239818417ed2e750;hp=24cfdbb51886fee26528c4463728abd69ab1fabc;hpb=8834567b2f53bad60b9d77ff7970077f9af0888d;p=rup.git diff --git a/src/main.rs b/src/main.rs index 24cfdbb..15b9c02 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,22 @@ extern crate actix_web; extern crate listenfd; extern crate askama; +extern crate percent_encoding; use listenfd::ListenFd; use actix_files as fs; -use actix_web::{web, middleware, App, HttpServer, HttpResponse, Responder, Result, web::Query}; +use actix_web::{web, middleware, App, HttpServer, HttpResponse, web::Query}; use askama::Template; -use serde::{Deserialize}; + +use std::io::prelude::*; +use ron::de::from_reader; +use serde::Deserialize; +use std::{fs::File, env::args}; + +use itertools::Itertools; + +mod consts; +mod crypto; #[derive(Template)] #[template(path = "main.html")] @@ -19,28 +29,76 @@ pub struct Request { m: Option } -fn main_page(query: Query) -> Result { +fn main_page(query: Query, key: &str) -> HttpResponse { let m = match &query.m { - Some(b) => &b, - None => "Marc, roule un pet'!" + Some(b) => + match crypto::decrypt(key, b) { + Ok(m) => m, + Err(_e) => String::from(consts::DEFAULT_MESSAGE) // TODO: log error. + }, + None => String::from(consts::DEFAULT_MESSAGE) }; - let hello = MainTemplate { sentence: m }; + let hello = MainTemplate { sentence: &m }; let s = hello.render().unwrap(); - Ok(HttpResponse::Ok().content_type("text/html").body(s)) + HttpResponse::Ok().content_type("text/html").body(s) +} + +#[derive(Debug, Deserialize)] +struct Config { + port: u16 +} + +fn get_exe_name() -> String { + let first_arg = std::env::args().nth(0).unwrap(); + let sep: &[_] = &['\\', '/']; + first_arg[first_arg.rfind(sep).unwrap()+1..].to_string() } -fn main() -> std::io::Result<()> { +fn read_key() -> String { + let mut key = String::new(); + File::open(consts::FILE_KEY) + .unwrap_or_else(|_| panic!("Failed to open key file: {}", consts::FILE_KEY)) + .read_to_string(&mut key) + .unwrap_or_else(|_| panic!("Failed to read key file: {}", consts::FILE_KEY)); + + String::from( + percent_encoding::percent_decode(key.replace('\n', "").as_bytes()) + .decode_utf8() + .unwrap_or_else(|_| panic!("Failed to decode key file: {}", consts::FILE_KEY)) + ) +} + +#[actix_rt::main] +async fn main() -> std::io::Result<()> { + let key = read_key(); + + if process_args(&key) { return Ok(()) } + + println!("Starting RUP as web server..."); + + let config: Config = { + let f = File::open(consts::FILE_CONF).unwrap_or_else(|_| panic!("Failed to open configuration file {}", consts::FILE_CONF)); + match from_reader(f) { + Ok(c) => c, + Err(e) => panic!("Failed to load config: {}", e) + } + }; + + println!("Configuration: {:?}", config); + let mut listenfd = ListenFd::from_env(); let mut server = HttpServer::new( - || { + move || { + let key = key.clone(); // Is this neccessary?? + App::new() .wrap(middleware::Compress::default()) .wrap(middleware::Logger::default()) - .service(web::resource("/").to(main_page)) + .service(web::resource("/").to(move |query| main_page(query, &key))) .service(fs::Files::new("/static", "static").show_files_listing()) } ); @@ -49,8 +107,54 @@ fn main() -> std::io::Result<()> { if let Some(l) = listenfd.take_tcp_listener(0).unwrap() { server.listen(l).unwrap() } else { - server.bind("0.0.0.0:8082").unwrap() + server.bind(&format!("0.0.0.0:{}", config.port)).unwrap() }; - server.run() + server.run().await +} + +fn process_args(key: &str) -> bool { + fn print_usage() { + println!("Usage:"); + println!(" {} [--help] [--encrypt |--decrypt ]", get_exe_name()); + } + + let args: Vec = args().collect(); + + if args.iter().any(|arg| arg == "--help") { + print_usage(); + return true + } else if let Some((position_arg_encrypt, _)) = args.iter().find_position(|arg| arg == &"--encrypt") { + match args.get(position_arg_encrypt + 1) { + Some(mess_to_encrypt) => { + match crypto::encrypt(&key, mess_to_encrypt) { + Ok(encrypted_mess) => { + let encrypted_mess_encoded = percent_encoding::utf8_percent_encode(&encrypted_mess, percent_encoding::NON_ALPHANUMERIC).to_string(); + println!("Encrypted message percent-encoded: {}", encrypted_mess_encoded); }, + Err(error) => + println!("Unable to encrypt: {:?}", error) + } + } + None => print_usage() + } + + return true + } else if let Some((position_arg_decrypt, _)) = args.iter().find_position(|arg| arg == &"--decrypt") { + match args.get(position_arg_decrypt + 1) { + Some(cipher_text) => { + let cipher_text_decoded = percent_encoding::percent_decode(cipher_text.as_bytes()).decode_utf8().expect("Unable to decode encoded cipher text"); + match crypto::decrypt(&key, &cipher_text_decoded) { + Ok(plain_text) => + println!("Decrypted message: {}", plain_text), + Err(error) => + println!("Unable to decrypt: {:?}", error) + } + } + None => print_usage() + } + + return true + } + + false }