diff options
Diffstat (limited to 'src/bin/systemhttpd.rs')
-rw-r--r-- | src/bin/systemhttpd.rs | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/src/bin/systemhttpd.rs b/src/bin/systemhttpd.rs new file mode 100644 index 0000000..506eba4 --- /dev/null +++ b/src/bin/systemhttpd.rs @@ -0,0 +1,100 @@ +// CSRF protection +// https://github.com/heartsucker/iron-csrf +#[macro_use] +extern crate log; +extern crate systemhttp; +extern crate env_logger; +#[macro_use] +extern crate clap; +extern crate rusqlite; +extern crate rpassword; + +use rpassword::read_password; +use std::io::{self, Write}; +use systemhttp::auth; + +use clap::{App, AppSettings, Arg, SubCommand}; + +fn create_user_prompt() -> Option<(String, String)> { + print!("Username: "); + io::stdout().flush(); + let mut user = String::new(); + io::stdin().read_line(&mut user).unwrap(); + let password = rpassword::prompt_password_stdout("Password: ").unwrap(); + let confirmation = rpassword::prompt_password_stdout("Repeat password: ").unwrap(); + + if password != confirmation { + error!("Passwords don't match"); + return None; + } + Some((user.trim().to_string(), password)) +} + +fn create_admin_user(conn: &rusqlite::Connection) { + info!("Create admin user"); + if let Some((user, password)) = create_user_prompt() { + let enc = auth::encode("test_salt", password.as_str()); + systemhttp::db::insert_user(&conn, user.as_str(), &enc).expect("create user"); + } +} + +fn serve(context: systemhttp::server::Context, state: systemhttp::server::State, port: u16) { + let _server = systemhttp::server::serve(context, state, port).unwrap(); + println!("Serving on {}", port); +} + +fn main() { + let matches = App::new("systemhttpd") + .version("0.1") + .author("Kjetil Ørbekk") + .about("Systemd web frontend") + .setting(AppSettings::SubcommandRequired) + .arg(Arg::with_name("port") + .short("p") + .long("port") + .takes_value(true) + .help("Port to serve on")) + .arg(Arg::with_name("db_file") + .long("db_file") + .takes_value(true) + .help("Path to sqlite database")) + .arg(Arg::with_name("base_url") + .long("base_url") + .takes_value(true) + .help("URL to prepend to links (useful with proxies)")) + .subcommand(SubCommand::with_name("serve") + .about("Start the systemhttpd server")) + .subcommand(SubCommand::with_name("create_admin_user") + .about("Add an admin user to the db")) + .get_matches(); + + let port = matches + .value_of("port") + .unwrap_or("8080") + .parse::<u16>() + .expect("port number"); + + let db_file = matches.value_of("db_file").unwrap(); + + let base_url = matches.value_of("base_url").unwrap_or("").to_string(); + + env_logger::init().unwrap(); + let mut conn = rusqlite::Connection::open(db_file) + .expect(format!("opening sqlite database at {}", db_file).as_str()); + systemhttp::db::init(&mut conn); + + let context = systemhttp::server::Context { + base_url: base_url, + }; + info!("{:?}", context); + let state = systemhttp::server::State { + conn: conn, + }; + info!("{:?}", state); + + match matches.subcommand_name() { + Some("serve") => serve(context, state, port), + Some("create_admin_user") => create_admin_user(&state.conn), + x => panic!("Don't know about subcommand: {:?}", x), + } +} |