// 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, port: u16) { let _server = systemhttp::server::serve(context, 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")) .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::() .expect("port number"); let db_file = matches.value_of("db_file").unwrap(); 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 mut context = systemhttp::server::Context { base_url: "http://localhost:8080".to_string(), conn: conn, }; match matches.subcommand_name() { Some("serve") => serve(context, port), Some("create_admin_user") => create_admin_user(&context.conn), x => panic!("Don't know about subcommand: {:?}", x), } }