diff --git a/backend/src/api.rs b/backend/src/api.rs index 17608fd..3f2a1a5 100644 --- a/backend/src/api.rs +++ b/backend/src/api.rs @@ -1,21 +1,16 @@ -use crate::schema::users::*; use crate::schema::gamenight::*; +use crate::schema::users::*; use crate::schema::DbConn; use crate::AppConfig; -use uuid::Uuid; use chrono::Utc; -use jsonwebtoken::decode; -use jsonwebtoken::encode; -use jsonwebtoken::DecodingKey; -use jsonwebtoken::Validation; -use jsonwebtoken::{EncodingKey, Header}; +use jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, Validation}; use rocket::http::Status; -use rocket::request::Outcome; -use rocket::request::{FromRequest, Request}; +use rocket::request::{FromRequest, Outcome, Request}; use rocket::serde::json::{json, Json, Value}; use rocket::State; use serde::{Deserialize, Serialize}; use std::borrow::Cow; +use uuid::Uuid; use validator::ValidateArgs; #[derive(Debug, Responder)] @@ -65,7 +60,7 @@ impl ApiResponse { message: None, user: Some(UserWithToken { user: user, - jwt: jwt + jwt: jwt, }), gamenights: None, games: None, @@ -108,9 +103,7 @@ impl<'r> FromRequest<'r> for User { async fn from_request(req: &'r Request<'_>) -> Outcome { let header = match req.headers().get_one(AUTH_HEADER) { Some(header) => header, - None => { - return Outcome::Forward(()) - } + None => return Outcome::Forward(()), }; if !header.starts_with(BEARER) { @@ -125,25 +118,25 @@ impl<'r> FromRequest<'r> for User { &Validation::default(), ) { Ok(token) => token, - Err(_) => { - return Outcome::Forward(()) - } + Err(_) => return Outcome::Forward(()), }; let id = token.claims.uid; let conn = req.guard::().await.unwrap(); return match get_user(conn, id).await { Ok(o) => Outcome::Success(o), - Err(_) => Outcome::Forward(()) - } + Err(_) => Outcome::Forward(()), + }; } } #[get("/gamenights")] pub async fn gamenights(conn: DbConn, _user: User) -> ApiResponseVariant { match get_all_gamenights(conn).await { - Ok(gamenights) => ApiResponseVariant::Value(json!(ApiResponse::gamenight_response(gamenights))), - Err(error) => ApiResponseVariant::Value(json!(ApiResponse::error(error.to_string()))) + Ok(gamenights) => { + ApiResponseVariant::Value(json!(ApiResponse::gamenight_response(gamenights))) + } + Err(error) => ApiResponseVariant::Value(json!(ApiResponse::error(error.to_string()))), } } @@ -161,13 +154,12 @@ pub struct GameNightInput { } impl Into for GameNightInput { - - fn into(self) -> GameNight { + fn into(self) -> GameNight { GameNight { id: Uuid::new_v4(), name: self.name, datetime: self.datetime, - owner_id: self.owner_id.unwrap() + owner_id: self.owner_id.unwrap(), } } } @@ -185,12 +177,12 @@ pub async fn gamenights_post_json( match add_unknown_games(&conn, &mut mutable_game_list).await { Ok(_) => (), - Err(err) => return ApiResponseVariant::Value(json!(ApiResponse::error(err.to_string()))) + Err(err) => return ApiResponseVariant::Value(json!(ApiResponse::error(err.to_string()))), }; match insert_gamenight(conn, gamenight.clone().into(), mutable_game_list).await { Ok(_) => ApiResponseVariant::Value(json!(ApiResponse::SUCCES)), - Err(err) => ApiResponseVariant::Value(json!(ApiResponse::error(err.to_string()))) + Err(err) => ApiResponseVariant::Value(json!(ApiResponse::error(err.to_string()))), } } @@ -199,44 +191,46 @@ pub async fn gamenights_post_json_unauthorized() -> ApiResponseVariant { ApiResponseVariant::Status(Status::Unauthorized) } -#[delete("/gamenights", format = "application/json", data = "")] +#[delete( + "/gamenights", + format = "application/json", + data = "" +)] pub async fn gamenights_delete_json( conn: DbConn, user: User, - delete_gamenight_json: Json + delete_gamenight_json: Json, ) -> ApiResponseVariant { if user.role == Role::Admin { if let Err(error) = delete_gamenight(&conn, delete_gamenight_json.game_id).await { - return ApiResponseVariant::Value(json!(ApiResponse::error(error.to_string()))) + return ApiResponseVariant::Value(json!(ApiResponse::error(error.to_string()))); } - return ApiResponseVariant::Value(json!(ApiResponse::SUCCES)) + return ApiResponseVariant::Value(json!(ApiResponse::SUCCES)); } - + match get_gamenight(&conn, delete_gamenight_json.game_id).await { Ok(gamenight) => { if user.id == gamenight.owner_id { if let Err(error) = delete_gamenight(&conn, delete_gamenight_json.game_id).await { - return ApiResponseVariant::Value(json!(ApiResponse::error(error.to_string()))) + return ApiResponseVariant::Value(json!(ApiResponse::error(error.to_string()))); } - return ApiResponseVariant::Value(json!(ApiResponse::SUCCES)) + return ApiResponseVariant::Value(json!(ApiResponse::SUCCES)); } - }, - Err(error) => return ApiResponseVariant::Value(json!(ApiResponse::error(error.to_string()))) + } + Err(error) => { + return ApiResponseVariant::Value(json!(ApiResponse::error(error.to_string()))) + } } ApiResponseVariant::Status(Status::Unauthorized) } - #[delete("/gamenights", rank = 2)] pub async fn gamenights_delete_json_unauthorized() -> ApiResponseVariant { ApiResponseVariant::Status(Status::Unauthorized) } #[post("/register", format = "application/json", data = "")] -pub async fn register_post_json( - conn: DbConn, - register_json: Json, -) -> ApiResponseVariant { +pub async fn register_post_json(conn: DbConn, register_json: Json) -> ApiResponseVariant { let register = register_json.into_inner(); let register_clone = register.clone(); match conn @@ -290,7 +284,9 @@ pub async fn login_post_json( &my_claims, &EncodingKey::from_secret(secret.as_bytes()), ) { - Ok(token) => ApiResponseVariant::Value(json!(ApiResponse::login_response(user, token))), + Ok(token) => { + ApiResponseVariant::Value(json!(ApiResponse::login_response(user, token))) + } Err(error) => { ApiResponseVariant::Value(json!(ApiResponse::error(error.to_string()))) } @@ -303,7 +299,7 @@ pub async fn login_post_json( pub async fn games(conn: DbConn, _user: User) -> ApiResponseVariant { match get_all_known_games(&conn).await { Ok(games) => ApiResponseVariant::Value(json!(ApiResponse::games_response(games))), - Err(error) => ApiResponseVariant::Value(json!(ApiResponse::error(error.to_string()))) + Err(error) => ApiResponseVariant::Value(json!(ApiResponse::error(error.to_string()))), } } @@ -311,4 +307,3 @@ pub async fn games(conn: DbConn, _user: User) -> ApiResponseVariant { pub async fn games_unauthorized() -> ApiResponseVariant { ApiResponseVariant::Status(Status::Unauthorized) } - diff --git a/backend/src/main.rs b/backend/src/main.rs index 3b4215f..cc9989e 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -46,13 +46,7 @@ async fn rocket() -> _ { .attach(AdHoc::on_ignite("Run Migrations", schema::run_migrations)) .attach(AdHoc::config::()) .attach(site::make_cors()) - .mount( - "/", - routes![ - site::index, - site::files - ], - ) + .mount("/", routes![site::index, site::files]) .mount( "/api", routes![ diff --git a/backend/src/schema/gamenight.rs b/backend/src/schema/gamenight.rs index a69d190..ba8b5b3 100644 --- a/backend/src/schema/gamenight.rs +++ b/backend/src/schema/gamenight.rs @@ -1,6 +1,6 @@ use crate::schema::{DatabaseError, DbConn}; +use diesel::{Connection, ExpressionMethods, QueryDsl, RunQueryDsl}; use serde::{Deserialize, Serialize}; -use diesel::{QueryDsl, RunQueryDsl, Connection, ExpressionMethods}; use uuid::Uuid; table! { @@ -50,18 +50,18 @@ pub struct GameNight { } #[derive(Serialize, Deserialize, Debug, Queryable, Insertable)] -#[table_name="gamenight_gamelist"] +#[table_name = "gamenight_gamelist"] pub struct GamenightGameListEntry { pub gamenight_id: Uuid, - pub game_id: Uuid + pub game_id: Uuid, } #[derive(Serialize, Deserialize, Debug, Queryable, Insertable, Identifiable)] -#[table_name="gamenight_participants"] +#[table_name = "gamenight_participants"] #[primary_key(gamenight_id, user_id)] pub struct GamenightParticipantsEntry { pub gamenight_id: Uuid, - pub user_id: Uuid + pub user_id: Uuid, } #[derive(Serialize, Deserialize, Debug, Queryable)] @@ -69,62 +69,62 @@ pub struct DeleteGameNight { pub game_id: Uuid, } - pub async fn get_all_gamenights(conn: DbConn) -> Result, DatabaseError> { - Ok(conn.run(|c| - gamenight::table.load::(c) - ).await?) + Ok(conn.run(|c| gamenight::table.load::(c)).await?) } -pub async fn insert_gamenight(conn: DbConn, new_gamenight: GameNight, game_list: Vec) -> Result { - Ok(conn.run(move |c| - c.transaction(|| { - diesel::insert_into(gamenight::table) - .values(&new_gamenight) - .execute(c)?; +pub async fn insert_gamenight( + conn: DbConn, + new_gamenight: GameNight, + game_list: Vec, +) -> Result { + Ok(conn + .run(move |c| { + c.transaction(|| { + diesel::insert_into(gamenight::table) + .values(&new_gamenight) + .execute(c)?; - let entries: Vec = game_list.iter().map( - |g| GamenightGameListEntry { gamenight_id: new_gamenight.id.clone(), game_id: g.id.clone() } - ).collect(); + let entries: Vec = game_list + .iter() + .map(|g| GamenightGameListEntry { + gamenight_id: new_gamenight.id.clone(), + game_id: g.id.clone(), + }) + .collect(); - diesel::insert_into(gamenight_gamelist::table) - .values(entries) - .execute(c) + diesel::insert_into(gamenight_gamelist::table) + .values(entries) + .execute(c) + }) }) - ).await?) + .await?) } pub async fn get_gamenight(conn: &DbConn, game_id: Uuid) -> Result { - Ok(conn.run(move |c| - gamenight::table.find(game_id).first(c) - ).await?) + Ok(conn + .run(move |c| gamenight::table.find(game_id).first(c)) + .await?) } pub async fn delete_gamenight(conn: &DbConn, game_id: Uuid) -> Result { - Ok(conn.run(move |c| - diesel::delete( - gamenight::table.filter( - gamenight::id.eq(game_id) - ) - ).execute(c) - ).await?) + Ok(conn + .run(move |c| diesel::delete(gamenight::table.filter(gamenight::id.eq(game_id))).execute(c)) + .await?) } - - pub async fn get_all_known_games(conn: &DbConn) -> Result, DatabaseError> { - Ok(conn.run(|c| - known_games::table.load::(c) - ).await?) + Ok(conn.run(|c| known_games::table.load::(c)).await?) } pub async fn add_game(conn: &DbConn, game: Game) -> Result { - Ok(conn.run(|c| - diesel::insert_into(known_games::table) - .values(game) - .execute(c) - - ).await?) + Ok(conn + .run(|c| { + diesel::insert_into(known_games::table) + .values(game) + .execute(c) + }) + .await?) } pub async fn add_unknown_games(conn: &DbConn, games: &mut Vec) -> Result<(), DatabaseError> { @@ -138,24 +138,30 @@ pub async fn add_unknown_games(conn: &DbConn, games: &mut Vec) -> Result<( Ok(()) } -pub async fn insert_participant(conn: &DbConn, participant: GamenightParticipantsEntry) -> Result { - Ok(conn.run(move |c| - diesel::insert_into(gamenight_participants::table) - .values(&participant) - .execute(c) - ).await?) +pub async fn insert_participant( + conn: &DbConn, + participant: GamenightParticipantsEntry, +) -> Result { + Ok(conn + .run(move |c| { + diesel::insert_into(gamenight_participants::table) + .values(&participant) + .execute(c) + }) + .await?) } impl From for (Uuid, Uuid) { - fn from(entry: GamenightParticipantsEntry) -> Self { (entry.gamenight_id, entry.user_id) } } -pub async fn remove_participant(conn: &DbConn, participant: GamenightParticipantsEntry) -> Result { - Ok(conn.run(move |c| - diesel::delete(&participant) - .execute(c) - ).await?) -} \ No newline at end of file +pub async fn remove_participant( + conn: &DbConn, + participant: GamenightParticipantsEntry, +) -> Result { + Ok(conn + .run(move |c| diesel::delete(&participant).execute(c)) + .await?) +} diff --git a/backend/src/schema/mod.rs b/backend/src/schema/mod.rs index c4170da..60598b5 100644 --- a/backend/src/schema/mod.rs +++ b/backend/src/schema/mod.rs @@ -1,5 +1,5 @@ -pub mod users; pub mod gamenight; +pub mod users; use rocket::{Build, Rocket}; use rocket_sync_db_pools::database; @@ -36,7 +36,7 @@ pub async fn run_migrations(rocket: Rocket) -> Rocket { } impl From for DatabaseError { - fn from(error: diesel::result::Error) -> Self { + fn from(error: diesel::result::Error) -> Self { Self::Query(error.to_string()) } } @@ -55,6 +55,3 @@ impl std::fmt::Display for DatabaseError { } } } - - - diff --git a/backend/src/schema/users.rs b/backend/src/schema/users.rs index 4a1a1cd..a29ca50 100644 --- a/backend/src/schema/users.rs +++ b/backend/src/schema/users.rs @@ -1,6 +1,4 @@ -use validator::{Validate, ValidationError}; -use uuid::Uuid; -use diesel::{QueryDsl, RunQueryDsl, Connection, ExpressionMethods}; +use crate::schema::{DatabaseError, DbConn}; use argon2::password_hash::SaltString; use argon2::PasswordHash; use argon2::PasswordVerifier; @@ -8,9 +6,11 @@ use argon2::{ password_hash::{rand_core::OsRng, PasswordHasher}, Argon2, }; +use diesel::{Connection, ExpressionMethods, QueryDsl, RunQueryDsl}; use diesel_derive_enum::DbEnum; use serde::{Deserialize, Serialize}; -use crate::schema::{DbConn, DatabaseError}; +use uuid::Uuid; +use validator::{Validate, ValidationError}; #[derive(Debug, Serialize, Deserialize, DbEnum, Clone, Copy, PartialEq)] pub enum Role { @@ -41,7 +41,6 @@ struct Pwd { password: String, } - #[derive(Serialize, Deserialize, Debug, Insertable, Queryable)] #[table_name = "users"] pub struct User { @@ -92,30 +91,33 @@ pub async fn insert_user(conn: DbConn, new_user: Register) -> Result Result { @@ -141,12 +143,12 @@ pub async fn login(conn: DbConn, login: Login) -> Result Result Result { - Ok(conn.run(move |c| users::table.filter(users::id.eq(id)).first(c)) + Ok(conn + .run(move |c| users::table.filter(users::id.eq(id)).first(c)) .await?) } @@ -173,10 +176,7 @@ pub fn unique_username( } } -pub fn unique_email( - email: &String, - conn: &diesel::PgConnection, -) -> Result<(), ValidationError> { +pub fn unique_email(email: &String, conn: &diesel::PgConnection) -> Result<(), ValidationError> { match users::table .count() .filter(users::email.eq(email)) @@ -188,4 +188,4 @@ pub fn unique_email( "Database error while validating email", )), } -} \ No newline at end of file +} diff --git a/backend/src/site.rs b/backend/src/site.rs index 7f47ca2..0d8193d 100644 --- a/backend/src/site.rs +++ b/backend/src/site.rs @@ -1,20 +1,19 @@ +use local_ip_address::local_ip; use rocket::fs::NamedFile; use rocket::http::Method; use rocket_cors::{AllowedHeaders, AllowedOrigins, Cors, CorsOptions}; use std::io; use std::path::{Path, PathBuf}; -use local_ip_address::local_ip; - pub fn make_cors() -> Cors { let allowed_origins = AllowedOrigins::some_exact(&[ "http://localhost:3000", "http://127.0.0.1:3000", - &format!("http://{}:8000",local_ip().unwrap())[..], + &format!("http://{}:8000", local_ip().unwrap())[..], "http://localhost:8000", "http://0.0.0.0:8000", ]); - + CorsOptions { allowed_origins, allowed_methods: vec![Method::Get].into_iter().map(From::from).collect(), // 1.