From de72a44ab5621bef7177e9f7db4b8adf904ce81f Mon Sep 17 00:00:00 2001 From: Daan Vanoverloop Date: Sun, 4 Sep 2022 10:08:18 +0200 Subject: [PATCH] Use name as identifier instead of uuid --- Cargo.lock | 47 +++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/api/event.rs | 73 ++++++++++++++++++++++-------------------------- src/api/user.rs | 44 +++++++++++++---------------- src/main.rs | 7 +++++ 5 files changed, 107 insertions(+), 65 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 272279a..1922cd2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -48,6 +48,15 @@ dependencies = [ "version_check", ] +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + [[package]] name = "android_system_properties" version = "0.1.4" @@ -939,6 +948,7 @@ dependencies = [ "okapi", "paste", "rocket", + "rocket_cors", "rocket_db_pools", "rocket_okapi", "schemars", @@ -1478,6 +1488,8 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" dependencies = [ + "aho-corasick", + "memchr", "regex-syntax", ] @@ -1585,6 +1597,22 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "rocket_cors" +version = "0.6.0-alpha1" +source = "git+https://github.com/lawliet89/rocket_cors#54fae0701dffbe5df686465780218644ee3fae5f" +dependencies = [ + "http", + "log", + "regex", + "rocket", + "serde", + "serde_derive", + "unicase", + "unicase_serde", + "url", +] + [[package]] name = "rocket_db_pools" version = "0.1.0-rc.2" @@ -2442,6 +2470,25 @@ dependencies = [ "version_check", ] +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicase_serde" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ef53697679d874d69f3160af80bc28de12730a985d57bdf2b47456ccb8b11f1" +dependencies = [ + "serde", + "unicase", +] + [[package]] name = "unicode-bidi" version = "0.3.8" diff --git a/Cargo.toml b/Cargo.toml index cddaefc..7873229 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ futures = "0.3" lazy_static = "1.4" serde_json = "1" paste = "1" +rocket_cors = { git = "https://github.com/lawliet89/rocket_cors" } [dependencies.sqlx] version = "*" diff --git a/src/api/event.rs b/src/api/event.rs index 8b11482..2cafb25 100644 --- a/src/api/event.rs +++ b/src/api/event.rs @@ -42,9 +42,6 @@ impl EventOutcome { #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] #[serde(crate = "rocket::serde")] pub struct Event { - /// Unique identifier of the event. This will be randomly generated and cannot be modified. - #[serde(default = "uuid")] - id: String, /// Has this event concluded? #[serde(default)] concluded: bool, @@ -70,10 +67,6 @@ impl Event { } } -fn uuid() -> String { - uuid::Uuid::new_v4().to_string() -} - /// # EventSpec /// /// A specification of an event @@ -124,7 +117,6 @@ macro_rules! events { }; let event = Event { - id: uuid(), name: self.name, description: self.description, concluded: false, @@ -359,7 +351,7 @@ mod free_for_all_game { #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] #[serde(crate = "rocket::serde")] pub enum FreeForAllGameRanking { - /// Ranking of participants by user id or team name (first element is first place, second element is second + /// Ranking of participants by user name or team name (first element is first place, second element is second /// place, etc.) Ranking(Vec), /// Score based ranking of participants/teams @@ -378,7 +370,7 @@ mod free_for_all_game { #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] #[serde(crate = "rocket::serde")] pub struct FreeForAllGame { - /// Ranking of participants by user id or team name (first element is first place, second element is second + /// Ranking of participants by user name or team name (first element is first place, second element is second /// place, etc.) ranking: Option, @@ -437,10 +429,10 @@ mod free_for_all_game { /// Set list of participants participating in the game SetParticipants(HashSet), - /// Add participant by id + /// Add participant by name AddParticipant(String), - /// Remove participant by id + /// Remove participant by name RemoveParticipant(String), } @@ -490,11 +482,11 @@ mod free_for_all_game { }, }, FreeForAllGameUpdate::Participants(update) => match update { - FreeForAllGameUpdateParticipants::AddParticipant(id) => { - self.spec.participants.insert(id); + FreeForAllGameUpdateParticipants::AddParticipant(name) => { + self.spec.participants.insert(name); } - FreeForAllGameUpdateParticipants::RemoveParticipant(id) => { - self.spec.participants.remove(&id); + FreeForAllGameUpdateParticipants::RemoveParticipant(name) => { + self.spec.participants.remove(&name); if !self .ranking @@ -502,7 +494,7 @@ mod free_for_all_game { .map(|r| r.is_valid(&self.spec.participants)) .unwrap_or(true) { - self.spec.participants.insert(id); + self.spec.participants.insert(name); return Err(PartyError::Unknown("cannot remove participant, all participants mentioned in ranking must be participating".into())); } } @@ -562,9 +554,6 @@ events!(test => Test, team_game => TeamGame, free_for_all_game => FreeForAllGame /// # Create event /// -/// If an `id` is supplied, it will be replaced by a randomly generated -/// one. -/// /// Returns the created event. #[openapi(tag = "Event")] #[post("/", data = "")] @@ -580,26 +569,30 @@ pub async fn create_event( /// # Update event /// -/// Update the supplied values in the event with the given id. The `id` of an event cannot be +/// Update the supplied values in the event with the given name. The `name` of an event cannot be /// changed and `concluded` will always be false. #[openapi(tag = "Event")] -#[post("/", data = "")] +#[post("/", data = "")] pub async fn update_event( _api_key: ApiKey, db: Connection, - id: String, + name: String, update: Json, ) -> Result { let mut event = db .events() - .find_one(doc! { "id": &id }, None) + .find_one(doc! { "name": &name }, None) .await? - .ok_or(PartyError::EventNotFound(id.clone()))?; + .ok_or(PartyError::EventNotFound(name.clone()))?; event.apply_update(update.into_inner())?; db.events() - .update_one(doc! { "id": &id }, doc! { "$set": to_bson(&event)? }, None) + .update_one( + doc! { "name": &name }, + doc! { "$set": to_bson(&event)? }, + None, + ) .await?; Ok(Status::Ok) @@ -607,19 +600,19 @@ pub async fn update_event( /// # Get event /// -/// Returns the event with the given id +/// Returns the event with the given name #[openapi(tag = "Event")] -#[get("/")] +#[get("/")] pub async fn get_event( _api_key: ApiKey, db: Connection, - id: String, + name: String, ) -> Result, PartyError> { Ok(Json( db.events() - .find_one(doc! { "id": &id }, None) + .find_one(doc! { "name": &name }, None) .await? - .ok_or(PartyError::EventNotFound(id))?, + .ok_or(PartyError::EventNotFound(name))?, )) } @@ -652,17 +645,17 @@ pub async fn get_all_events( /// /// Returns the outcome of an event. #[openapi(tag = "Event")] -#[get("//outcome")] +#[get("//outcome")] pub async fn event_outcome( _api_key: ApiKey, db: Connection, - id: String, + name: String, ) -> Result, PartyError> { let event = db .events() - .find_one(doc! { "id": &id }, None) + .find_one(doc! { "name": &name }, None) .await? - .ok_or(PartyError::EventNotFound(id.clone()))?; + .ok_or(PartyError::EventNotFound(name.clone()))?; Ok(Json(event.outcome())) } @@ -670,21 +663,21 @@ pub async fn event_outcome( /// /// This will conclude the event, apply the outcome to the users and return the outcome. #[openapi(tag = "Event")] -#[post("//stop")] +#[post("//stop")] pub async fn stop_event( _api_key: ApiKey, db: Connection, - id: String, + name: String, ) -> Result, PartyError> { let event = db .events() - .find_one(doc! { "id": &id }, None) + .find_one(doc! { "name": &name }, None) .await? - .ok_or(PartyError::EventNotFound(id.clone()))?; + .ok_or(PartyError::EventNotFound(name.clone()))?; event.conclude(); db.events() .update_one( - doc! { "id": &id }, + doc! { "name": &name }, doc! { "$set": { "concluded": true } }, None, ) diff --git a/src/api/user.rs b/src/api/user.rs index daf3662..0ce7c9f 100644 --- a/src/api/user.rs +++ b/src/api/user.rs @@ -22,8 +22,6 @@ pub struct User { name: String, /// Score of the user score: i64, - /// Unique identifier of the user - id: String, } /// # Create new user with the give name @@ -37,7 +35,6 @@ pub async fn add_user( name: Json<&str>, ) -> Result>, PartyError> { let user = User { - id: uuid::Uuid::new_v4().to_string(), score: 0, name: name.to_string(), }; @@ -47,34 +44,34 @@ pub async fn add_user( Ok(status::Created::new("/").body(Json(user))) } -/// # Delete user by id +/// # Delete user by name #[openapi(tag = "User")] -#[delete("/")] +#[delete("/")] pub async fn delete_user( _api_key: ApiKey, db: Connection, - id: String, + name: String, ) -> Result { - db.users().delete_one(doc! { "id": id }, None).await?; + db.users().delete_one(doc! { "name": name }, None).await?; Ok(Status::Ok) } /// # Get user by id /// -/// Returns a single user by id +/// Returns a single user by name #[openapi(tag = "User")] -#[get("/")] +#[get("/")] pub async fn get_user( _api_key: ApiKey, db: Connection, - id: String, + name: String, ) -> Result, PartyError> { let user = db .users() - .find_one(doc! { "id": &id }, None) + .find_one(doc! { "name": &name }, None) .await? - .ok_or(PartyError::UserNotFound(id))?; + .ok_or(PartyError::UserNotFound(name))?; Ok(Json(user)) } @@ -88,8 +85,6 @@ pub enum UserSort { Score, #[field(value = "name")] Name, - #[field(value = "id")] - Id, } impl ToString for UserSort { @@ -97,7 +92,6 @@ impl ToString for UserSort { match self { Self::Score => "score", Self::Name => "name", - Self::Id => "id", } .into() } @@ -139,18 +133,18 @@ pub async fn get_all_users( Ok(Json(users)) } -/// # Set score of user by id +/// # Set score of user by name #[openapi(tag = "User")] -#[post("//score", data = "")] +#[post("//score", data = "")] pub async fn set_score( _api_key: ApiKey, db: Connection, - id: String, + name: String, score: Json, ) -> Result { db.users() .update_one( - doc! { "id": id }, + doc! { "name": name }, doc! { "$set": { "score": *score } }, None, ) @@ -159,21 +153,21 @@ pub async fn set_score( Ok(Status::Ok) } -/// # Get score of user by id +/// # Get score of user by name /// -/// Returns the score of a single user by id +/// Returns the score of a single user by name #[openapi(tag = "User")] -#[get("//score")] +#[get("//score")] pub async fn get_score( _api_key: ApiKey, db: Connection, - id: String, + name: String, ) -> Result, PartyError> { Ok(Json( db.users() - .find_one(doc! { "id": &id }, None) + .find_one(doc! { "name": &name }, None) .await? - .ok_or(PartyError::UserNotFound(id))? + .ok_or(PartyError::UserNotFound(name))? .score, )) } diff --git a/src/main.rs b/src/main.rs index c467229..fc220d2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ mod api; +use rocket_cors::CorsOptions; use rocket_db_pools::{mongodb, Database}; use rocket_okapi::{ openapi, @@ -23,8 +24,14 @@ fn index() -> String { #[launch] fn rocket() -> _ { + let cors = CorsOptions::default() + .allowed_origins(rocket_cors::AllOrSome::All) + .to_cors() + .unwrap(); + let building_rocket = rocket::build() .attach(Db::init()) + .attach(cors) .mount("/", routes![index]) .mount( "/swagger",