From a71bfa908cbbbb13bff2fe5a8231c838918205ef Mon Sep 17 00:00:00 2001 From: Paul Date: Thu, 12 Aug 2021 13:40:03 +0100 Subject: [PATCH] Add fetch owned, public and specific bots for #8. --- src/database/entities/user.rs | 2 +- src/database/guards/user.rs | 50 +++++++++++++++---------------- src/routes/bots/fetch.rs | 22 ++++++++++++++ src/routes/bots/fetch_owned.rs | 52 +++++++++++++++++++++++++++++++++ src/routes/bots/fetch_public.rs | 24 +++++++++++++++ src/routes/bots/mod.rs | 8 ++++- 6 files changed, 131 insertions(+), 27 deletions(-) create mode 100644 src/routes/bots/fetch.rs create mode 100644 src/routes/bots/fetch_owned.rs create mode 100644 src/routes/bots/fetch_public.rs diff --git a/src/database/entities/user.rs b/src/database/entities/user.rs index c470635c..ade3cb84 100644 --- a/src/database/entities/user.rs +++ b/src/database/entities/user.rs @@ -214,7 +214,7 @@ impl User { }, FindOptions::builder() .projection( - doc! { "_id": 1, "username": 1, "avatar": 1, "badges": 1, "status": 1 }, + doc! { "_id": 1, "username": 1, "avatar": 1, "badges": 1, "status": 1, "flags": 1, "bot": 1 }, ) .build(), ) diff --git a/src/database/guards/user.rs b/src/database/guards/user.rs index 394c6b84..2f498849 100644 --- a/src/database/guards/user.rs +++ b/src/database/guards/user.rs @@ -63,32 +63,32 @@ impl<'r> FromRequest<'r> for User { }, )) } - } - - let session: Session = request.guard::().await.unwrap(); - - if let Ok(result) = get_collection("users") - .find_one( - doc! { - "_id": &session.user_id - }, - None, - ) - .await - { - if let Some(doc) = result { - Outcome::Success(from_document(doc).unwrap()) - } else { - Outcome::Failure((Status::Forbidden, rauth::util::Error::InvalidSession)) - } } else { - Outcome::Failure(( - Status::InternalServerError, - rauth::util::Error::DatabaseError { - operation: "find_one", - with: "user", - }, - )) + let session: Session = request.guard::().await.unwrap(); + + if let Ok(result) = get_collection("users") + .find_one( + doc! { + "_id": &session.user_id + }, + None, + ) + .await + { + if let Some(doc) = result { + Outcome::Success(from_document(doc).unwrap()) + } else { + Outcome::Failure((Status::Forbidden, rauth::util::Error::InvalidSession)) + } + } else { + Outcome::Failure(( + Status::InternalServerError, + rauth::util::Error::DatabaseError { + operation: "find_one", + with: "user", + }, + )) + } } } } diff --git a/src/routes/bots/fetch.rs b/src/routes/bots/fetch.rs new file mode 100644 index 00000000..2820bef5 --- /dev/null +++ b/src/routes/bots/fetch.rs @@ -0,0 +1,22 @@ +use crate::database::*; +use crate::util::result::{Error, Result}; + +use serde_json::Value; + +#[get("/")] +pub async fn fetch_bot(user: User, target: Ref) -> Result { + let bot = target.fetch_bot().await?; + + if !bot.public { + if bot.owner != user.id { + return Err(Error::BotIsPrivate); + } + } + + let user = Ref::from_unchecked(bot.id.clone()).fetch_user().await?; + + Ok(json!({ + "bot": bot, + "user": user + })) +} diff --git a/src/routes/bots/fetch_owned.rs b/src/routes/bots/fetch_owned.rs new file mode 100644 index 00000000..42f08b15 --- /dev/null +++ b/src/routes/bots/fetch_owned.rs @@ -0,0 +1,52 @@ +use crate::database::*; +use crate::util::result::{Error, Result}; + +use futures::StreamExt; +use mongodb::bson::{Document, doc, from_document}; +use serde_json::Value; + +#[get("/@me")] +pub async fn fetch_owned_bots(user: User) -> Result { + let bots = get_collection("bots") + .find( + doc! { + "owner": &user.id + }, + None + ) + .await + .map_err(|_| Error::DatabaseError { + with: "bots", + operation: "find" + })? + .filter_map(async move |s| s.ok()) + .collect::>() + .await + .into_iter() + .filter_map(|x| from_document(x).ok()) + .collect::>(); + + let users = get_collection("users") + .find( + doc! { + "bot.owner": &user.id + }, + None + ) + .await + .map_err(|_| Error::DatabaseError { + with: "users", + operation: "find" + })? + .filter_map(async move |s| s.ok()) + .collect::>() + .await + .into_iter() + .filter_map(|x| from_document(x).ok()) + .collect::>(); + + Ok(json!({ + "bots": bots, + "users": users + })) +} diff --git a/src/routes/bots/fetch_public.rs b/src/routes/bots/fetch_public.rs new file mode 100644 index 00000000..33bf82f2 --- /dev/null +++ b/src/routes/bots/fetch_public.rs @@ -0,0 +1,24 @@ +use crate::database::*; +use crate::util::result::{Error, Result}; + +use serde_json::Value; + +#[get("//invite")] +pub async fn fetch_public_bot(user: User, target: Ref) -> Result { + let bot = target.fetch_bot().await?; + + if !bot.public { + if bot.owner != user.id { + return Err(Error::BotIsPrivate); + } + } + + let user = Ref::from_unchecked(bot.id.clone()).fetch_user().await?; + + Ok(json!({ + "_id": bot.id, + "username": user.username, + "avatar": user.avatar, + "description": user.profile.map(|p| p.content) + })) +} diff --git a/src/routes/bots/mod.rs b/src/routes/bots/mod.rs index 1606eff2..66a3f40b 100644 --- a/src/routes/bots/mod.rs +++ b/src/routes/bots/mod.rs @@ -2,10 +2,16 @@ use rocket::Route; mod create; mod invite; +mod fetch_public; +mod fetch; +mod fetch_owned; pub fn routes() -> Vec { routes![ create::create_bot, - invite::invite_bot + invite::invite_bot, + fetch_public::fetch_public_bot, + fetch::fetch_bot, + fetch_owned::fetch_owned_bots, ] }