diff --git a/Cargo.toml b/Cargo.toml index 49b1b03..d93740b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,5 +7,9 @@ edition = "2021" [dependencies] rocket = "0.5.0-rc.1" +rocket_dyn_templates = { version = "0.1.0-rc.1", features = ["tera"] } mongodb = "2.0.0" -tokio = "*" \ No newline at end of file +tokio = "*" +serde = { version = "1.0", features = ["derive"] } +tokio-test = "0.4.2" +bcrypt = "0.10.1" \ No newline at end of file diff --git a/Rocket.toml b/Rocket.toml new file mode 100644 index 0000000..1127001 --- /dev/null +++ b/Rocket.toml @@ -0,0 +1,2 @@ +[default] +template_dir = "templates" \ No newline at end of file diff --git a/src/auth/mod.rs b/src/auth/mod.rs new file mode 100644 index 0000000..33e4a9c --- /dev/null +++ b/src/auth/mod.rs @@ -0,0 +1,32 @@ +use bcrypt; +use rocket::form::Form; +use super::db_wrapper; +use db_wrapper::schemas::User; + +#[derive(FromForm)] +pub struct UserAuth<'r> { + username: &'r str, + password: &'r str +} + +#[get("/")] +pub fn index() -> &'static str { + "Auth!" +} + + +#[post("/login", data = "")] +pub async fn login(user: Form>) -> String { + let users = db_wrapper::get_client().await.collection::("users"); + let hashed = bcrypt::hash(&user.password, bcrypt::DEFAULT_COST).unwrap(); + + let insert_user = User { + username: user.username.to_string(), + pwd_hash: hashed.to_string() + }; + + match users.insert_one(insert_user, None).await { + Err(e) => format!("Error encountered while inserting user.\nERROR: {}", e), + Ok(_) => format!("Hello {}! Your password is {}. Your hash is `{}`", user.username, user.password, hashed) + } +} \ No newline at end of file diff --git a/src/db_wrapper/mod.rs b/src/db_wrapper/mod.rs new file mode 100644 index 0000000..c8de019 --- /dev/null +++ b/src/db_wrapper/mod.rs @@ -0,0 +1,55 @@ +use mongodb::{ Client, Database }; + +pub mod schemas; + +pub async fn get_client() -> Database { + match Client::with_uri_str(match std::env::var("MONGODB_URI") { + Err(e) => { + std::process::exit({ + eprintln!("Error: {:?}", e); + 1 + }) + }, + Ok(val) => val + }).await { + Ok(client) => client.database("schoollabs-test"), + Err(e) => { + std::process::exit({ + eprintln!("Error: {:?}", e); + 1 + }) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use tokio_test; + use serde::{Deserialize, Serialize}; + + + async fn check_mongo_works_fn() { + #[derive(Debug, Serialize, Deserialize)] + struct Book { + title: String, + author: String + } + + let db = get_client().await; + + let books = db.collection::("books"); + + let book = vec![Book { title: "1984".to_string(), author: "George Orwell".to_string() }]; + + match books.insert_many(book, None).await { + Ok(_) => assert_eq!(1, 1), + Err(_) => assert_eq!(1, 0) + }; + } + + #[test] + fn check_mongo_works() { + tokio_test::block_on(check_mongo_works_fn()) + } +} \ No newline at end of file diff --git a/src/db_wrapper/schemas.rs b/src/db_wrapper/schemas.rs new file mode 100644 index 0000000..b8235f5 --- /dev/null +++ b/src/db_wrapper/schemas.rs @@ -0,0 +1,7 @@ +use serde::{Serialize, Deserialize}; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct User { + pub username: String, + pub pwd_hash: String +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 7c66f77..48b9090 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,41 +1,23 @@ -#[macro_use] -extern crate rocket; -use mongodb::{bson::doc, options::ClientOptions, Client}; +#[macro_use] extern crate rocket; +mod db_wrapper; +mod auth; #[get("/")] fn index() -> &'static str { "Hello, world!" } -#[launch] -fn rocket() -> _ { - let mongo_result = start_mongo(); - match mongo_result { - Result => println!("Everything is fine!"), - }; - rocket::build().mount("/", routes![index]) -} +#[rocket::main] +async fn main() { + let rocket = rocket::build() + .mount("/", routes![index]) + .mount("/auth", routes![auth::index, auth::login]) + .launch() + .await; -#[tokio::main] -async fn start_mongo() -> mongodb::error::Result<()> { - // Parse your connection string into an options struct - let mut client_options = - ClientOptions::parse(env!("MONGODB_URI")) - .await?; - // Manually set an option - client_options.app_name = Some("Rust Demo".to_string()); - // Get a handle to the cluster - let client = Client::with_options(client_options)?; - // Ping the server to see if you can connect to the cluster - client - .database("admin") - .run_command(doc! {"ping": 1}, None) - .await?; - println!("Connected successfully."); - // List the names of the databases in that cluster - for db_name in client.list_database_names(None, None).await? { - println!("{}", db_name); + match rocket { + Err(e) => println!("There seems to be an error with rocket!\n{:?}", e), + _ => () } - Ok(()) -} \ No newline at end of file +}