diff --git a/crates/delta/src/routes/servers/server_fetch.rs b/crates/delta/src/routes/servers/server_fetch.rs index db17fd05..ded1b756 100644 --- a/crates/delta/src/routes/servers/server_fetch.rs +++ b/crates/delta/src/routes/servers/server_fetch.rs @@ -1,17 +1,65 @@ use revolt_quark::{ - models::{Server, User}, + models::{Channel, Server, User}, perms, Db, Ref, Result, }; use rocket::serde::json::Json; +use serde::{Deserialize, Serialize}; + +/// # Query Parameters +#[derive(Deserialize, JsonSchema, FromForm)] +pub struct OptionsFetchServer { + /// Whether to include channels + include_channels: Option, +} + +/// # Fetch server route response +#[derive(Serialize, JsonSchema)] +#[serde(untagged)] +pub enum FetchServerResponse { + JustServer(Server), + ServerWithChannels { + #[serde(flatten)] + server: Server, + channels: Vec, + }, +} /// # Fetch Server /// /// Fetch a server by its id. #[openapi(tag = "Server Information")] -#[get("/")] -pub async fn req(db: &Db, user: User, target: Ref) -> Result> { +#[get("/?")] +pub async fn req( + db: &Db, + user: User, + target: Ref, + options: OptionsFetchServer, +) -> Result> { let server = target.as_server(db).await?; - perms(&user).server(&server).calc(db).await?; + let mut perms = perms(&user).server(&server); + perms.calc(db).await?; - Ok(Json(server)) + if let Some(true) = options.include_channels { + let all_channels = db.fetch_channels(&server.channels).await?; + let mut visible_channels = vec![]; + + for channel in all_channels { + if perms + .clone() + .channel(&channel) + .calc(db) + .await? + .can_view_channel() + { + visible_channels.push(channel); + } + } + + Ok(Json(FetchServerResponse::ServerWithChannels { + server, + channels: visible_channels, + })) + } else { + Ok(Json(FetchServerResponse::JustServer(server))) + } }