From 8da624780549fc9ab3be3d206736730591b822ce Mon Sep 17 00:00:00 2001 From: Patrick Cleavelin Date: Tue, 14 Mar 2023 21:43:21 -0500 Subject: [PATCH] support for deleting intros --- src/auth.rs | 1 + src/main.rs | 7 ++++--- src/routes.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/auth.rs b/src/auth.rs index 5bfaa0d..683d0ad 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -40,6 +40,7 @@ impl Permissions { pub enum Permission { None, UploadSounds, + DeleteSounds, } impl Permission { diff --git a/src/main.rs b/src/main.rs index e8818e9..8709206 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,7 +8,7 @@ mod routes; pub mod settings; use axum::http::{HeaderValue, Method}; -use axum::routing::{get, post}; +use axum::routing::{delete, get, post}; use axum::Router; use futures::StreamExt; use settings::ApiState; @@ -135,9 +135,10 @@ fn spawn_api(settings: Arc>) { let api = Router::new() .route("/health", get(routes::health)) .route("/me", get(routes::me)) + .route("/intros/:guild", get(routes::intros)) .route("/intros/:guild/add", get(routes::add_guild_intro)) .route("/intros/:guild/upload", post(routes::upload_guild_intro)) - .route("/intros/:guild", get(routes::intros)) + .route("/intros/:guild/delete", delete(routes::delete_guild_intro)) .route( "/intros/:guild/:channel/:intro", post(routes::add_intro_to_user), @@ -152,7 +153,7 @@ fn spawn_api(settings: Arc>) { // TODO: move this to env variable .allow_origin([origin.parse().unwrap()]) .allow_headers(Any) - .allow_methods([Method::GET, Method::POST]), + .allow_methods([Method::GET, Method::POST, Method::DELETE]), ) .with_state(Arc::new(state)); let addr = SocketAddr::from(([0, 0, 0, 0], 8100)); diff --git a/src/routes.rs b/src/routes.rs index 69fa37f..224e66d 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -53,6 +53,9 @@ pub(crate) struct MeChannel<'a> { pub(crate) intros: &'a Vec, } +#[derive(Deserialize)] +pub(crate) struct DeleteIntroRequest(Vec); + pub(crate) async fn health() -> &'static str { "Hello!" } @@ -434,3 +437,44 @@ pub(crate) async fn add_guild_intro( Ok(()) } + +pub(crate) async fn delete_guild_intro( + State(state): State>, + Path(guild): Path, + headers: HeaderMap, + Json(body): Json, +) -> Result<(), Error> { + let mut settings = state.settings.lock().await; + // TODO: make this an impl on HeaderMap + let Some(token) = headers.get("token").and_then(|v| v.to_str().ok()) else { return Err(Error::NoUserFound); }; + + { + let Some(guild) = settings.guilds.get(&guild) else { return Err(Error::NoGuildFound); }; + let auth_user = match settings.auth_users.get(token) { + Some(user) => user, + None => return Err(Error::NoUserFound), + }; + let Some(guild_user) = guild.users.get(&auth_user.name) else { return Err(Error::NoUserFound) }; + + if !guild_user.permissions.can(auth::Permission::DeleteSounds) { + return Err(Error::InvalidPermission); + } + } + + let Some(guild) = settings.guilds.get_mut(&guild) else { return Err(Error::NoGuildFound); }; + + // Remove intro from any users + for channel in guild.channels.iter_mut() { + for user in channel.1.users.iter_mut() { + user.1 + .intros + .retain(|user_intro| !body.0.iter().any(|intro| &user_intro.index == intro)); + } + } + + for intro in &body.0 { + guild.intros.remove(intro); + } + + Ok(()) +}