summaryrefslogtreecommitdiff
path: root/src/bin/systemhttpd.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/systemhttpd.rs')
-rw-r--r--src/bin/systemhttpd.rs100
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),
+ }
+}