use revolt_database::{ util::{permissions::DatabasePermissionQuery, reference::Reference}, Database, User, }; use revolt_models::v0; use revolt_permissions::{calculate_channel_permissions, ChannelPermission, PermissionQuery}; use revolt_result::{create_error, Result}; use rocket::{serde::json::Json, State}; /// Fetch Server /// /// Fetch a server by its id. #[utoipa::path( tag = "Server Information", security(("Session-Token" = []), ("Bot-Token" = [])), params( ("target" = Reference, Path), v0::OptionsFetchServer ), responses( (status = 200, body = v0::Server), ), )] #[get("/?")] pub async fn fetch( db: &State, user: User, target: Reference<'_>, options: v0::OptionsFetchServer, ) -> Result> { let server = target.as_server(db).await?; let mut query = DatabasePermissionQuery::new(db, &user).server(&server); if !query.are_we_a_member().await { return Err(create_error!(NotFound)); } if let Some(true) = options.include_channels { let all_channels = db.fetch_channels(&server.channels).await?; let mut visible_channels: Vec = vec![]; for channel in all_channels { let mut channel_query = query.clone().channel(&channel); if calculate_channel_permissions(&mut channel_query) .await .has_channel_permission(ChannelPermission::ViewChannel) { visible_channels.push(channel.into()); } } Ok(Json(v0::FetchServerResponse::ServerWithChannels { server: server.into(), channels: visible_channels, })) } else { Ok(Json(v0::FetchServerResponse::JustServer(server.into()))) } }