From 284703134dd834970d1c5ddca1251bd6d3da4754 Mon Sep 17 00:00:00 2001 From: c0repwn3r Date: Sun, 26 Mar 2023 09:32:23 -0400 Subject: [PATCH] pg --- .env | 1 + .idea/dataSources.xml | 12 ++ .idea/sqldialects.xml | 6 + Cargo.lock | 204 ++++++++++++------ Cargo.toml | 21 +- build.rs | 3 + diesel.toml | 8 + migrations/.keep | 0 .../down.sql | 6 + .../up.sql | 36 ++++ .../2023-03-26-024321_create_users/down.sql | 1 + .../2023-03-26-024321_create_users/up.sql | 5 + .../down.sql | 1 + .../2023-03-26-024710_create_3fa_codes/up.sql | 6 + src/main.rs | 46 +++- src/models.rs | 19 ++ src/schema.rs | 25 +++ 17 files changed, 331 insertions(+), 69 deletions(-) create mode 100644 .env create mode 100644 .idea/dataSources.xml create mode 100644 .idea/sqldialects.xml create mode 100644 build.rs create mode 100644 diesel.toml create mode 100644 migrations/.keep create mode 100644 migrations/00000000000000_diesel_initial_setup/down.sql create mode 100644 migrations/00000000000000_diesel_initial_setup/up.sql create mode 100644 migrations/2023-03-26-024321_create_users/down.sql create mode 100644 migrations/2023-03-26-024321_create_users/up.sql create mode 100644 migrations/2023-03-26-024710_create_3fa_codes/down.sql create mode 100644 migrations/2023-03-26-024710_create_3fa_codes/up.sql create mode 100644 src/models.rs create mode 100644 src/schema.rs diff --git a/.env b/.env new file mode 100644 index 0000000..ebec27a --- /dev/null +++ b/.env @@ -0,0 +1 @@ +DATABASE_URL=postgres://postgres:postgres@localhost/hotel diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 0000000..a03d898 --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,12 @@ + + + + + postgresql + true + org.postgresql.Driver + jdbc:postgresql://localhost:5432/hotel + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml new file mode 100644 index 0000000..6df4889 --- /dev/null +++ b/.idea/sqldialects.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index e94041a..1bc0094 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -295,6 +295,12 @@ dependencies = [ "alloc-stdlib", ] +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + [[package]] name = "bytes" version = "1.4.0" @@ -394,6 +400,43 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "diesel" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4391a22b19c916e50bec4d6140f29bdda3e3bb187223fe6e3ea0b6e4d1021c04" +dependencies = [ + "bitflags", + "byteorder", + "diesel_derives", + "itoa", + "pq-sys", + "r2d2", +] + +[[package]] +name = "diesel_derives" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ad74fdcf086be3d4fdd142f67937678fe60ed431c3b2f08599e7687269410c4" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "diesel_migrations" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9ae22beef5e9d6fab9225ddb073c1c6c1a7a6ded5019d5da11d1e5c5adc34e2" +dependencies = [ + "diesel", + "migrations_internals", + "migrations_macros", +] + [[package]] name = "digest" version = "0.10.6" @@ -404,6 +447,12 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + [[package]] name = "encoding_rs" version = "0.8.32" @@ -438,65 +487,12 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "futures" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "531ac96c6ff5fd7c62263c5e3c67a603af4fcaee2e1a0ae5565ba3a11e69e549" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "164713a5a0dcc3e7b4b1ed7d3b433cabc18025386f9339346e8daf15963cf7ac" -dependencies = [ - "futures-core", - "futures-sink", -] - [[package]] name = "futures-core" version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86d7a0c1aa76363dac491de0ee99faf6941128376f1cf96f07db7603b7de69dd" -[[package]] -name = "futures-executor" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1997dd9df74cdac935c76252744c1ed5794fac083242ea4fe77ef3ed60ba0f83" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d422fa3cbe3b40dca574ab087abb5bc98258ea57eea3fd6f1fa7162c778b91" - -[[package]] -name = "futures-macro" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb14ed937631bd8b8b8977f2c198443447a8355b6e3ca599f38c975e5a963b6" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "futures-sink" version = "0.3.27" @@ -515,16 +511,10 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ef6b17e481503ec85211fed8f39d1970f128935ca1f814cd32ac4a6842e84ab" dependencies = [ - "futures-channel", "futures-core", - "futures-io", - "futures-macro", - "futures-sink", "futures-task", - "memchr", "pin-project-lite", "pin-utils", - "slab", ] [[package]] @@ -596,12 +586,15 @@ name = "hotel" version = "0.1.0" dependencies = [ "actix-web", - "futures", + "diesel", + "diesel_migrations", + "dotenvy", "log", "once_cell", + "r2d2", "serde", "simple_logger", - "toml", + "toml 0.7.3", ] [[package]] @@ -723,6 +716,27 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "migrations_internals" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c493c09323068c01e54c685f7da41a9ccf9219735c3766fbfd6099806ea08fbc" +dependencies = [ + "serde", + "toml 0.5.11", +] + +[[package]] +name = "migrations_macros" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a8ff27a350511de30cdabb77147501c36ef02e0451d957abea2f30caffb2b58" +dependencies = [ + "migrations_internals", + "proc-macro2", + "quote", +] + [[package]] name = "mime" version = "0.3.17" @@ -834,6 +848,39 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "pq-sys" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b845d6d8ec554f972a2c5298aad68953fd64e7441e846075450b44656a016d1" +dependencies = [ + "vcpkg", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.53" @@ -852,6 +899,17 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r2d2" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93" +dependencies = [ + "log", + "parking_lot", + "scheduled-thread-pool", +] + [[package]] name = "rand" version = "0.8.5" @@ -923,6 +981,15 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +[[package]] +name = "scheduled-thread-pool" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" +dependencies = [ + "parking_lot", +] + [[package]] name = "scopeguard" version = "1.1.0" @@ -1143,6 +1210,15 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + [[package]] name = "toml" version = "0.7.3" @@ -1236,6 +1312,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" diff --git a/Cargo.toml b/Cargo.toml index 3e156cd..1f06a5a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,10 +6,17 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -actix-web = "4" -serde = { version = "1.0.158", features = ["derive"] } -futures = "0.3.27" -once_cell = "1.17.1" -toml = "0.7.3" -log = "0.4.17" -simple_logger = "4.1.0" \ No newline at end of file +actix-web = "4" # Web framework + +serde = { version = "1.0.158", features = ["derive"] } # Serialization and deserialization + +once_cell = "1.17.1" # Config +toml = "0.7.3" # Config + +log = "0.4.17" # Logging +simple_logger = "4.1.0" # Logging + +diesel = { version = "2.0.0", features = ["postgres", "r2d2"] } # Database +dotenvy = "0.15" # Database +diesel_migrations = "2.0.0" # Database +r2d2 = "0.8.10" # Database \ No newline at end of file diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..3c284bb --- /dev/null +++ b/build.rs @@ -0,0 +1,3 @@ +fn main() { + println!("cargo:rerun-if-changed=migrations/"); +} \ No newline at end of file diff --git a/diesel.toml b/diesel.toml new file mode 100644 index 0000000..35a12ff --- /dev/null +++ b/diesel.toml @@ -0,0 +1,8 @@ +# For documentation on how to configure this file, +# see https://diesel.rs/guides/configuring-diesel-cli + +[print_schema] +file = "src/schema.rs" + +[migrations_directory] +dir = "migrations" diff --git a/migrations/.keep b/migrations/.keep new file mode 100644 index 0000000..e69de29 diff --git a/migrations/00000000000000_diesel_initial_setup/down.sql b/migrations/00000000000000_diesel_initial_setup/down.sql new file mode 100644 index 0000000..a9f5260 --- /dev/null +++ b/migrations/00000000000000_diesel_initial_setup/down.sql @@ -0,0 +1,6 @@ +-- This file was automatically created by Diesel to setup helper functions +-- and other internal bookkeeping. This file is safe to edit, any future +-- changes will be added to existing projects as new migrations. + +DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass); +DROP FUNCTION IF EXISTS diesel_set_updated_at(); diff --git a/migrations/00000000000000_diesel_initial_setup/up.sql b/migrations/00000000000000_diesel_initial_setup/up.sql new file mode 100644 index 0000000..d68895b --- /dev/null +++ b/migrations/00000000000000_diesel_initial_setup/up.sql @@ -0,0 +1,36 @@ +-- This file was automatically created by Diesel to setup helper functions +-- and other internal bookkeeping. This file is safe to edit, any future +-- changes will be added to existing projects as new migrations. + + + + +-- Sets up a trigger for the given table to automatically set a column called +-- `updated_at` whenever the row is modified (unless `updated_at` was included +-- in the modified columns) +-- +-- # Example +-- +-- ```sql +-- CREATE TABLE users (id SERIAL PRIMARY KEY, updated_at TIMESTAMP NOT NULL DEFAULT NOW()); +-- +-- SELECT diesel_manage_updated_at('users'); +-- ``` +CREATE OR REPLACE FUNCTION diesel_manage_updated_at(_tbl regclass) RETURNS VOID AS $$ +BEGIN + EXECUTE format('CREATE TRIGGER set_updated_at BEFORE UPDATE ON %s + FOR EACH ROW EXECUTE PROCEDURE diesel_set_updated_at()', _tbl); +END; +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION diesel_set_updated_at() RETURNS trigger AS $$ +BEGIN + IF ( + NEW IS DISTINCT FROM OLD AND + NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at + ) THEN + NEW.updated_at := current_timestamp; + END IF; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; diff --git a/migrations/2023-03-26-024321_create_users/down.sql b/migrations/2023-03-26-024321_create_users/down.sql new file mode 100644 index 0000000..441087a --- /dev/null +++ b/migrations/2023-03-26-024321_create_users/down.sql @@ -0,0 +1 @@ +DROP TABLE users; \ No newline at end of file diff --git a/migrations/2023-03-26-024321_create_users/up.sql b/migrations/2023-03-26-024321_create_users/up.sql new file mode 100644 index 0000000..5beeeb9 --- /dev/null +++ b/migrations/2023-03-26-024321_create_users/up.sql @@ -0,0 +1,5 @@ +CREATE TABLE users ( + id SERIAL NOT NULL PRIMARY KEY, + name VARCHAR(128) NOT NULL UNIQUE, + discord_id BIGINT NOT NULL UNIQUE +); \ No newline at end of file diff --git a/migrations/2023-03-26-024710_create_3fa_codes/down.sql b/migrations/2023-03-26-024710_create_3fa_codes/down.sql new file mode 100644 index 0000000..fcf38e1 --- /dev/null +++ b/migrations/2023-03-26-024710_create_3fa_codes/down.sql @@ -0,0 +1 @@ +DROP TABLE codes_3fa; \ No newline at end of file diff --git a/migrations/2023-03-26-024710_create_3fa_codes/up.sql b/migrations/2023-03-26-024710_create_3fa_codes/up.sql new file mode 100644 index 0000000..94a5539 --- /dev/null +++ b/migrations/2023-03-26-024710_create_3fa_codes/up.sql @@ -0,0 +1,6 @@ +CREATE TABLE codes_3fa ( + id SERIAL NOT NULL PRIMARY KEY, + code VARCHAR(10) NOT NULL UNIQUE, + user_id SERIAL NOT NULL REFERENCES users(id), + expires_on BIGINT NOT NULL +); \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 23e91d0..72086cd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,20 @@ use actix_web::{App, HttpResponse, HttpServer, web, get, post, Responder, HttpRequest}; use actix_web::web::{Data, Json, JsonConfig}; -use log::{error, Level}; +use diesel::{Connection, PgConnection}; +use diesel::r2d2::ConnectionManager; +use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness}; +use log::{error, info, Level}; +use r2d2::Pool; use serde::{Serialize, Deserialize}; use crate::config::CONFIG; use crate::error::{APIError, APIErrorResponse}; pub mod config; pub mod error; +pub mod models; +pub mod schema; + +pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!(); #[derive(Serialize, Deserialize)] pub struct CodeRequest3FA { @@ -27,15 +35,51 @@ pub async fn get_3fa_code(req: Json) -> HttpResponse { }) } + + HttpResponse::Ok().body("d") } +pub type PgPool = Pool>; + #[actix_web::main] async fn main() -> std::io::Result<()> { simple_logger::init_with_level(Level::Debug).unwrap(); + info!("Connecting to database..."); + + let mut manager = ConnectionManager::new(&CONFIG.db_uri); + let mut pool: PgPool = match Pool::builder().build(manager) { + Ok(c) => c, + Err(e) => { + error!("Error connecting to database: {}", e); + std::process::exit(1); + } + }; + + let mut conn = match pool.get() { + Ok(c) => c, + Err(e) => { + error!("Error fetching connection: {}", e); + std::process::exit(1); + } + }; + + let data = Data::new(pool); + + info!("Running migrations..."); + + match conn.run_pending_migrations(MIGRATIONS) { + Ok(_) => (), + Err(e) => { + error!("Error running database migrations: {}", e); + std::process::exit(1); + } + }; + HttpServer::new(move || { App::new() + .app_data(data.clone()) .app_data(JsonConfig::default().error_handler(|err, req| { let err2: APIError = (&err).into(); actix_web::error::InternalError::from_response( diff --git a/src/models.rs b/src/models.rs new file mode 100644 index 0000000..85cc434 --- /dev/null +++ b/src/models.rs @@ -0,0 +1,19 @@ +use diesel::prelude::*; + +#[derive(Queryable)] +#[diesel(table_name = users)] +pub struct User { + pub id: i32, + pub name: String, + pub discord_id: i64 +} + +#[derive(Queryable)] +#[diesel(table_name = codes_3fa)] +#[diesel(belongs_to(User))] +pub struct Code3FA { + pub id: i32, + pub code: String, + pub user_id: i32, + pub expires_on: i64 +} \ No newline at end of file diff --git a/src/schema.rs b/src/schema.rs new file mode 100644 index 0000000..d8ee678 --- /dev/null +++ b/src/schema.rs @@ -0,0 +1,25 @@ +// @generated automatically by Diesel CLI. + +diesel::table! { + codes_3fa (id) { + id -> Int4, + code -> Varchar, + user_id -> Int4, + expires_on -> Int8, + } +} + +diesel::table! { + users (id) { + id -> Int4, + name -> Varchar, + discord_id -> Int8, + } +} + +diesel::joinable!(codes_3fa -> users (user_id)); + +diesel::allow_tables_to_appear_in_same_query!( + codes_3fa, + users, +);