From 6a608343965559f6d7b1a1ddf0df302e315b33b6 Mon Sep 17 00:00:00 2001 From: Radical Date: Thu, 8 May 2025 22:16:21 +0200 Subject: [PATCH] feat: add role creation/lookup --- src/api/v1/servers/uuid/mod.rs | 5 ++ src/api/v1/servers/uuid/roles/mod.rs | 99 +++++++++++++++++++++++++++ src/api/v1/servers/uuid/roles/uuid.rs | 54 +++++++++++++++ 3 files changed, 158 insertions(+) create mode 100644 src/api/v1/servers/uuid/roles/mod.rs create mode 100644 src/api/v1/servers/uuid/roles/uuid.rs diff --git a/src/api/v1/servers/uuid/mod.rs b/src/api/v1/servers/uuid/mod.rs index 2c6ebc7..ffa1ae7 100644 --- a/src/api/v1/servers/uuid/mod.rs +++ b/src/api/v1/servers/uuid/mod.rs @@ -2,6 +2,7 @@ use actix_web::{get, web, Error, HttpRequest, HttpResponse, Scope}; use uuid::Uuid; mod channels; +mod roles; use crate::{api::v1::auth::check_access_token, structs::{Guild, Member}, utils::get_auth_header, Data}; @@ -9,8 +10,12 @@ pub fn web() -> Scope { web::scope("") .service(res) .service(channels::response) + .service(channels::response_post) .service(channels::uuid::res) .service(channels::uuid::messages::res) + .service(roles::response) + .service(roles::response_post) + .service(roles::uuid::res) } #[get("/{uuid}")] diff --git a/src/api/v1/servers/uuid/roles/mod.rs b/src/api/v1/servers/uuid/roles/mod.rs new file mode 100644 index 0000000..23499de --- /dev/null +++ b/src/api/v1/servers/uuid/roles/mod.rs @@ -0,0 +1,99 @@ +use actix_web::{get, post, web, Error, HttpRequest, HttpResponse}; +use serde::Deserialize; +use crate::{api::v1::auth::check_access_token, structs::{Member, Role}, utils::get_auth_header, Data}; +use ::uuid::Uuid; +use log::error; + +pub mod uuid; + +#[derive(Deserialize)] +struct RoleInfo { + name: String, +} + +#[get("{uuid}/roles")] +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 member = Member::fetch_one(&data.pool, uuid, guild_uuid).await; + + if let Err(error) = member { + return Ok(error); + } + + let cache_result = data.get_cache_key(format!("{}_roles", guild_uuid)).await; + + if let Ok(cache_hit) = cache_result { + return Ok(HttpResponse::Ok().content_type("application/json").body(cache_hit)) + } + + let roles_result = Role::fetch_all(&data.pool, guild_uuid).await; + + if let Err(error) = roles_result { + return Ok(error) + } + + let roles = roles_result.unwrap(); + + let cache_result = data.set_cache_key(format!("{}_roles", guild_uuid), roles.clone(), 1800).await; + + if let Err(error) = cache_result { + error!("{}", error); + return Ok(HttpResponse::InternalServerError().finish()); + } + + Ok(HttpResponse::Ok().json(roles)) +} + +#[post("{uuid}/roles")] +pub async fn response_post(req: HttpRequest, role_info: web::Json, 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 member = Member::fetch_one(&data.pool, uuid, guild_uuid).await; + + if let Err(error) = member { + return Ok(error); + } + + // FIXME: Logic to check permissions, should probably be done in utils.rs + + let role = Role::new(&data.pool, guild_uuid, role_info.name.clone()).await; + + if let Err(error) = role { + return Ok(error); + } + + Ok(HttpResponse::Ok().json(role.unwrap())) +} diff --git a/src/api/v1/servers/uuid/roles/uuid.rs b/src/api/v1/servers/uuid/roles/uuid.rs new file mode 100644 index 0000000..3e55d5a --- /dev/null +++ b/src/api/v1/servers/uuid/roles/uuid.rs @@ -0,0 +1,54 @@ +use actix_web::{get, web, Error, HttpRequest, HttpResponse}; +use crate::{api::v1::auth::check_access_token, structs::{Member, Role}, utils::get_auth_header, Data}; +use ::uuid::Uuid; +use log::error; + +#[get("{uuid}/roles/{role_uuid}")] +pub async fn res(req: HttpRequest, path: web::Path<(Uuid, 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, role_uuid) = path.into_inner(); + + let authorized = check_access_token(auth_header.unwrap(), &data.pool).await; + + if let Err(error) = authorized { + return Ok(error) + } + + let uuid = authorized.unwrap(); + + let member = Member::fetch_one(&data.pool, uuid, guild_uuid).await; + + if let Err(error) = member { + return Ok(error); + } + + let cache_result = data.get_cache_key(format!("{}", role_uuid)).await; + + if let Ok(cache_hit) = cache_result { + return Ok(HttpResponse::Ok().content_type("application/json").body(cache_hit)) + } + + let role_result = Role::fetch_one(&data.pool, guild_uuid, role_uuid).await; + + if let Err(error) = role_result { + return Ok(error) + } + + let role = role_result.unwrap(); + + let cache_result = data.set_cache_key(format!("{}", role_uuid), role.clone(), 60).await; + + if let Err(error) = cache_result { + error!("{}", error); + return Ok(HttpResponse::InternalServerError().finish()); + } + + Ok(HttpResponse::Ok().json(role)) +}