diff --git a/admin-cli/Cargo.toml b/admin-cli/Cargo.toml index af7ec70..f0dcf16 100644 --- a/admin-cli/Cargo.toml +++ b/admin-cli/Cargo.toml @@ -7,5 +7,5 @@ edition = "2021" clap = { version = "4.5.20", features = ["derive"] } postgres = "0.19.9" base64 = "0.22.1" -serde = "1.0.215" +serde = { version = "1.0.215", features = ["derive"] } serde_json = "1.0.133" diff --git a/admin-cli/src/main.rs b/admin-cli/src/main.rs index bf754ad..5dcce2c 100644 --- a/admin-cli/src/main.rs +++ b/admin-cli/src/main.rs @@ -6,6 +6,9 @@ use postgres::{Client, NoTls}; use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine as _}; use serde::Serialize; + +const PASSWORD_LENGTH: usize = 64; + #[derive(Parser, Debug)] #[command(version, about, long_about = None)] struct Args { @@ -14,10 +17,16 @@ struct Args { setup: bool, } +#[derive(Serialize)] +struct Admin { + username: String, + password: String, +} + #[derive(Serialize)] struct Config { - postgres_user: String, - postgres_pass: String, + postgres: Admin, + bubble: Admin } fn random_string(size: usize) -> String { @@ -28,6 +37,13 @@ fn random_string(size: usize) -> String { URL_SAFE_NO_PAD.encode(buffer) } +fn admin(username: &str, password_size: usize) -> Admin { + Admin { + username: format!("admin-{}", username), + password: random_string(password_size) + } +} + fn full_setup() -> Result { // Check to make sure we have the DB url set to connect const KEY: &'static str = "DB_CONNECTION_STRING" ; @@ -36,7 +52,11 @@ fn full_setup() -> Result { ); let setup_tables_script = fs::read_to_string("db/setup-tables.sql") .expect("Failed to load file: db/setup-tables.sql"); - let bubble_admin_password = random_string(32); + let postgres_admin = admin("bubble_admin", PASSWORD_LENGTH); + let bubble_admin = admin( + &format!("admin-{}", random_string(8)), + PASSWORD_LENGTH + ); let mut client = Client::connect(&connection_string, NoTls)?; // Preliminary bs @@ -44,16 +64,24 @@ fn full_setup() -> Result { client.execute("CREATE DATABASE bubble;", &[])?; client.execute("DROP USER IF EXISTS bubble_admin;", &[])?; client.execute( - &format!("CREATE USER bubble_admin WITH ENCRYPTED PASSWORD '{}';", bubble_admin_password), + &format!("CREATE USER bubble_admin WITH ENCRYPTED PASSWORD '{}';", postgres_admin.password), &[] )?; // Ensure the admin has ownership of the db we created client.execute("ALTER DATABASE bubble OWNER TO bubble_admin", &[])?; // Service table creation client.batch_execute(&setup_tables_script)?; + client.execute( + &format!( + "INSERT INTO users (name, password) VALUES '{}', '{}'", + bubble_admin.username, + bubble_admin.password + ), + &[] + )?; Ok(Config { - postgres_user: "bubble_admin".into(), - postgres_pass: bubble_admin_password + postgres: postgres_admin, + bubble: bubble_admin }) } diff --git a/db/setup-tables.sql b/db/setup-tables.sql index 338c52a..e4c7dec 100644 --- a/db/setup-tables.sql +++ b/db/setup-tables.sql @@ -1,6 +1,10 @@ CREATE TABLE IF NOT EXISTS users ( - id INTEGER, - name VARCHAR(256), + /* */ + id UUID, + /* Acts as a kind of nick name per instance as it assumes no uniqueness */ + username VARCHAR(256), + /* Basic salted+hashed password */ + password VARCHAR(256), PRIMARY KEY (id) );