From b1d3703cf2a77689755e1bfbc3ee235338457a19 Mon Sep 17 00:00:00 2001 From: Kjetil Orbekk Date: Sat, 17 Jun 2017 15:08:42 -0400 Subject: feature: Add user command. * Finish command to create user. * Change sqlite => rusqlite dependency. --- Cargo.lock | 81 +++++++++++++++++++++++++++++++++++---------------------- Cargo.toml | 2 +- src/auth/mod.rs | 4 +-- src/bin/main.rs | 43 +++++++++++++++++------------- src/db.rs | 18 ++++++++++--- src/lib.rs | 2 +- 6 files changed, 93 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 75c52d5..047fded 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12,8 +12,8 @@ dependencies = [ "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "router 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "rpassword 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rusqlite 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", - "sqlite 0.23.4 (registry+https://github.com/rust-lang/crates.io-index)", "staticfile 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -77,6 +77,11 @@ name = "bitflags" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "bitflags" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "byteorder" version = "1.0.0" @@ -286,11 +291,33 @@ name = "libc" version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "libsqlite3-sys" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "linked-hash-map" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "log" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "lru-cache" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "matches" version = "0.1.4" @@ -427,6 +454,17 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rusqlite" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libsqlite3-sys 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rust-crypto" version = "0.2.36" @@ -467,33 +505,6 @@ name = "sequence_trie" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "sqlite" -version = "0.23.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", - "sqlite3-sys 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sqlite3-src" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "sqlite3-sys" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", - "sqlite3-src 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "staticfile" version = "0.4.0" @@ -645,6 +656,11 @@ name = "utf8-ranges" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "vcpkg" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "vec_map" version = "0.8.0" @@ -673,6 +689,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum backtrace-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d192fd129132fbc97497c1f2ec2c2c5174e376b95f535199ef4fe0a293d33842" "checksum base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30e93c03064e7590d0466209155251b90c22e37fab1daf2771582598b5827557" "checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4" +"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" "checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8" "checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c" "checksum clap 2.24.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b8f69e518f967224e628896b54e41ff6acfb4dcfefc5076325c36525dac900f" @@ -698,7 +715,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf" "checksum libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)" = "e7eb6b826bfc1fdea7935d46556250d1799b7fe2d9f7951071f4291710665e3e" +"checksum libsqlite3-sys 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "370090ad578ba845a3ad4f383ceb3deba7abd51ab1915ad1f2c982cc6035e31c" +"checksum linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7860ec297f7008ff7a1e3382d7f7e1dcd69efc94751a2284bafc3d013c2aa939" "checksum log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "5141eca02775a762cc6cd564d8d2c50f67c0ea3a372cbf1c51592b3e029e10ad" +"checksum lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d06ff7ff06f729ce5f4e227876cb88d10bc59cd4ae1e09fbb2bde15c850dc21" "checksum matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efd7622e3022e1a6eaa602c4cea8912254e5582c9c692e9167714182244801b1" "checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4" "checksum mime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9d69889cdc6336ed56b174514ce876c4c3dc564cc23dd872e7bca589bb2a36c8" @@ -716,15 +736,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum route-recognizer 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3255338088df8146ba63d60a9b8e3556f1146ce2973bc05a75181a42ce2256" "checksum router 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9b1797ff166029cb632237bb5542696e54961b4cf75a324c6f05c9cf0584e4e" "checksum rpassword 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "72556b202b5b38d0b69b0fdced60cf92dec7e37640c98eb9d7baf5bd86dc8e1a" +"checksum rusqlite 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffaf393ccdac5580092a4d8eb2edffbffe9a8c4484c62d8a0fcac99bc3718566" "checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" "checksum rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3058a43ada2c2d0b92b3ae38007a2d0fa5e9db971be260e0171408a4ff471c95" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" "checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" "checksum sequence_trie 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c915714ca833b1d4d6b8f6a9d72a3ff632fe45b40a8d184ef79c81bec6327eed" -"checksum sqlite 0.23.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a3cd27f80d9229b15313403f73d9180f2368f181a870be51f07e8f7f41d7a264" -"checksum sqlite3-src 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "52f02ac7a64c3446581ee43758075d9f1cdced596d70ffe28bf02979a719dbed" -"checksum sqlite3-sys 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71fec807a1534bd13eeaaec396175d67c79bdc68df55e18a452726ec62a8fb08" "checksum staticfile 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "31493480e073d52522a94cdf56269dd8eb05f99549effd1826b0271690608878" "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" "checksum term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2b6b55df3198cc93372e85dd2ed817f0e38ce8cc0f22eb32391bfad9c4bf209" @@ -745,6 +763,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5ba8a749fb4479b043733416c244fa9d1d3af3d7c23804944651c8a448cb87e" "checksum user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ef4711d107b21b410a3a974b1204d9accc8b10dad75d8324b5d755de1617d47" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" +"checksum vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b" "checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" diff --git a/Cargo.toml b/Cargo.toml index 10e98fd..4a212c5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ router = "*" horrorshow = "*" staticfile = "*" regex = "*" -sqlite = "*" +rusqlite = "*" rust-crypto = "*" base64 = "*" clap = "*" diff --git a/src/auth/mod.rs b/src/auth/mod.rs index 728c246..7f995f8 100644 --- a/src/auth/mod.rs +++ b/src/auth/mod.rs @@ -4,8 +4,8 @@ use crypto::bcrypt_pbkdf::bcrypt_pbkdf; #[derive(Debug, PartialEq, Eq)] pub struct HashedPassword { - salt: String, - enc: String, + pub salt: String, + pub enc: String, } // TODO: Configurable number of iterations. diff --git a/src/bin/main.rs b/src/bin/main.rs index a4d489d..e57ea6a 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -6,7 +6,7 @@ extern crate systemhttp; extern crate env_logger; #[macro_use] extern crate clap; -extern crate sqlite; +extern crate rusqlite; extern crate rpassword; use rpassword::read_password; @@ -15,6 +15,22 @@ 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, password)) +} + fn main() { let matches = App::new("systemhttpd") .version("0.1") @@ -42,7 +58,7 @@ fn main() { let db_file = matches.value_of("db_file").unwrap(); env_logger::init().unwrap(); - let mut conn = sqlite::Connection::open(db_file) + let mut conn = rusqlite::Connection::open(db_file) .expect(format!("opening sqlite database at {}", db_file).as_str()); systemhttp::db::init(&mut conn); @@ -51,22 +67,14 @@ fn main() { println!("Serving on {}", port); }; - let create_admin_user = || { - println!("Create admin user"); - 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 { - println!("\nPasswords don't match"); - return + let mut create_admin_user = || { + 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( + &mut conn, user.as_str(), + &enc).expect("create user"); } - println!("\nCreating user {} with password (hashed) {:?}", - user, auth::encode("test_salt", password.as_str())); }; match matches.subcommand_name() { @@ -74,5 +82,4 @@ fn main() { Some("create_admin_user") => create_admin_user(), x => panic!("Don't know about subcommand: {:?}", x) } - } diff --git a/src/db.rs b/src/db.rs index dea9924..e9a5d1f 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,5 +1,6 @@ -use sqlite::{Connection}; +use rusqlite::{Connection}; use std; +use auth::HashedPassword; type Result = std::result::Result; @@ -10,12 +11,21 @@ fn is_initialized(conn: &mut Connection) -> Result { pub fn init(conn: &mut Connection) -> Result<()> { if !is_initialized(conn)? { info!("Initializing db..."); - conn.execute(" + conn.execute_batch(" BEGIN; CREATE TABLE IF NOT EXISTS users - (username TEXT, salt TEXT, passwd TEXT); + (username TEXT PRIMARY KEY, salt TEXT, passwd TEXT); COMMIT; - ").unwrap(); + ").unwrap(); } Ok(()) } + +pub fn insert_user(conn: &mut Connection, + username: &str, + password: &HashedPassword) -> Result<()> { + conn.execute("INSERT INTO users (username, salt, passwd) + VALUES (?1, ?2, ?3)", + &[&username, &password.salt, &password.enc]).unwrap(); + Ok(()) +} diff --git a/src/lib.rs b/src/lib.rs index eaa1956..e165a1e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,6 @@ #[macro_use] extern crate horrorshow; -extern crate sqlite; +extern crate rusqlite; extern crate crypto; extern crate base64; #[macro_use] -- cgit v1.2.3