diff --git a/src/api/v1/servers/uuid/channels/mod.rs b/src/api/v1/servers/uuid/channels/mod.rs index 1f7e940..3786151 100644 --- a/src/api/v1/servers/uuid/channels/mod.rs +++ b/src/api/v1/servers/uuid/channels/mod.rs @@ -1,7 +1,109 @@ -use actix_web::{web, Scope}; +use std::str::FromStr; + +use actix_web::{get, web, Error, HttpRequest, HttpResponse}; +use serde::Serialize; +use sqlx::{prelude::FromRow, Pool, Postgres}; +use crate::{api::v1::auth::check_access_token, utils::get_auth_header, Data}; +use ::uuid::Uuid; +use log::error; mod uuid; -pub fn web() -> Scope { - web::scope("/channels") -} \ No newline at end of file +#[derive(Serialize, FromRow)] +struct ChannelPermission { + role_uuid: String, + permissions: i32 +} + +#[derive(Serialize)] +struct Channel { + uuid: String, + name: String, + description: Option, + permissions: Vec +} + +impl Channel { + async fn fetch_all(pool: &Pool, guild_uuid: Uuid) -> Result, HttpResponse> { + let row = sqlx::query_as(&format!("SELECT uuid, name, description FROM channels WHERE guild_uuid = '{}'", guild_uuid)) + .fetch_all(pool) + .await; + + if let Err(error) = row { + error!("{}", error); + + return Err(HttpResponse::InternalServerError().finish()) + } + + let channels: Vec<(String, String, Option)> = row.unwrap(); + + let futures = channels.iter().map(async |t| { + let (uuid, name, description) = t.to_owned(); + + let row = sqlx::query_as(&format!("SELECT role_uuid, permissions FROM channel_permissions WHERE channel_uuid = '{}'", uuid)) + .fetch_all(pool) + .await; + + if let Err(error) = row { + error!("{}", error); + + return Err(HttpResponse::InternalServerError().finish()) + } + + Ok(Self { + uuid, + name, + description, + permissions: row.unwrap(), + }) + }); + + let channels = futures::future::join_all(futures).await; + + let channels: Result, HttpResponse> = channels.into_iter().collect(); + + Ok(channels?) + } +} + +#[get("{uuid}/channels")] +pub async fn response(req: HttpRequest, path: web::Path<(Uuid,)>, data: web::Data) -> Result { + let headers = req.headers(); + + let auth_header = get_auth_header(headers); + + if let Err(error) = auth_header { + return Ok(error) + } + + let guild_uuid = path.into_inner().0; + + let authorized = check_access_token(auth_header.unwrap(), &data.pool).await; + + if let Err(error) = authorized { + return Ok(error) + } + + let uuid = authorized.unwrap(); + + let row: Result = sqlx::query_scalar(&format!("SELECT CAST(uuid AS VARCHAR) FROM guild_members WHERE guild_uuid = '{}' AND user_uuid = '{}'", guild_uuid, uuid)) + .fetch_one(&data.pool) + .await; + + if let Err(error) = row { + error!("{}", error); + + return Ok(HttpResponse::InternalServerError().finish()) + } + + let member_uuid = Uuid::from_str(&row.unwrap()).unwrap(); + + + let channels = Channel::fetch_all(&data.pool, guild_uuid).await; + + if let Err(error) = channels { + return Ok(error) + } + + Ok(HttpResponse::Ok().json(channels.unwrap())) +} diff --git a/src/api/v1/servers/uuid/mod.rs b/src/api/v1/servers/uuid/mod.rs index 022f0da..e85016a 100644 --- a/src/api/v1/servers/uuid/mod.rs +++ b/src/api/v1/servers/uuid/mod.rs @@ -32,7 +32,7 @@ struct Role { pub fn web() -> Scope { web::scope("/") .service(res) - .service(channels::web()) + .service(channels::response) } #[get("{uuid}")]