From 506dd987d6ef2cb7b500b523822cbc484d52982f Mon Sep 17 00:00:00 2001 From: Nia Calia-Bogan Date: Wed, 3 Nov 2021 12:34:11 -0400 Subject: [PATCH] Kick deleted accounts from RCOS Discord. --- src/api/discord/mod.rs | 3 +- src/env.rs | 7 ++-- src/web/services/auth/mod.rs | 3 +- src/web/services/user/delete.rs | 58 +++++++++++++++++++++----------- src/web/services/user/profile.rs | 6 +--- 5 files changed, 46 insertions(+), 31 deletions(-) diff --git a/src/api/discord/mod.rs b/src/api/discord/mod.rs index 9d1dfcb8..260925f7 100644 --- a/src/api/discord/mod.rs +++ b/src/api/discord/mod.rs @@ -20,8 +20,7 @@ pub async fn rcos_discord_verified_role_id() -> Result, Telescope // Get the RCOS Guild ID. let rcos_discord: u64 = global_config() .discord_config - .rcos_guild_id() - .ok_or(TelescopeError::ise("Malformed RCOS Guild ID."))?; + .rcos_guild_id(); // Get role Ok(global_discord_client() diff --git a/src/env.rs b/src/env.rs index e365fb8e..deeabfbc 100644 --- a/src/env.rs +++ b/src/env.rs @@ -36,8 +36,11 @@ pub struct DiscordConfig { impl DiscordConfig { /// Get the RCOS Discord Guild ID as a `u64`. - pub fn rcos_guild_id(&self) -> Option { - self.rcos_guild_id.as_str().parse::().ok() + pub fn rcos_guild_id(&self) -> u64 { + self.rcos_guild_id + .as_str() + .parse::() + .expect("Malformed RCOS Guild ID") } } diff --git a/src/web/services/auth/mod.rs b/src/web/services/auth/mod.rs index 8882117e..12166648 100644 --- a/src/web/services/auth/mod.rs +++ b/src/web/services/auth/mod.rs @@ -241,8 +241,7 @@ pub trait IdentityProvider: 'static { // Get RCOS Discord ID. let rcos_discord = global_config() .discord_config - .rcos_guild_id() - .expect("Malformed RCOS Discord Guild ID"); + .rcos_guild_id(); // Kick user from RCOS Discord. global_discord_client() diff --git a/src/web/services/user/delete.rs b/src/web/services/user/delete.rs index 7bce5053..181f76d3 100644 --- a/src/web/services/user/delete.rs +++ b/src/web/services/user/delete.rs @@ -1,39 +1,57 @@ -use crate::api::rcos::users::{delete::DeleteUser, profile::Profile}; +use crate::api::rcos::users::{delete::DeleteUser, profile::Profile, UserAccountType}; use crate::error::TelescopeError; use crate::templates::{forms::FormTemplate, jumbotron, Template}; use crate::web::services::auth::identity::{AuthenticationCookie, Identity}; use actix_web::{http::header::LOCATION, web::Form, HttpRequest, HttpResponse}; +use crate::api::discord::global_discord_client; +use crate::api::rcos::users::accounts::lookup::AccountLookup; +use crate::env::global_config; -// Confirmation form to delete the profile +/// Confirmation form to delete the profile #[get("/profile_delete")] pub async fn confirm_delete(auth: AuthenticationCookie) -> Result { let username = auth.get_rcos_username_or_error().await?; - let profiledata = dbg!(Profile::for_user(username.clone(), Some(username)).await?); + let profiledata = Profile::for_user(username.clone(), Some(username)).await?; let mut form = FormTemplate::new("user/delete", "Delete confirmation"); form.template = json!(profiledata); - dbg!(form.template.to_string()); Ok(form) } #[post("/profile_delete")] -pub async fn profile_delete( - req: HttpRequest, - identity: Identity, -) -> Result { - DeleteUser::execute(identity.get_rcos_username().await.map( - |x| -> Result { - x.ok_or(TelescopeError::InternalServerError( - "Missing username".to_string(), - )) - }, - )??) - .await?; +pub async fn profile_delete(req: HttpRequest, identity: Identity) -> Result { + // Get the viewer's RCOS username. + let rcos_username: String = identity + .get_rcos_username() + .await? + .ok_or(TelescopeError::NotAuthenticated)?; + + // Check if the viewer has a discord account linked. + let discord_id: Option = AccountLookup::send(rcos_username.clone(), UserAccountType::Discord) + .await? + .and_then(|string| string.as_str().parse::().ok()); + + // If there is one, kick it from the RCOS Discord. + if let Some(discord_id) = discord_id { + // Get the RCOS Discord Guild ID. + let rcos_guild = global_config().discord_config.rcos_guild_id(); + + // Kick the user from the RCOS guild. + global_discord_client() + .kick_member(rcos_guild, discord_id) + .await + .map_err(TelescopeError::serenity_error)?; + } + + // Execute the user deletion. + DeleteUser::execute(rcos_username).await?; + + // Clear the user's cookies. identity.forget(); - return Ok( - jumbotron::new("Account deletion", "Your account was deleted successfully.") + + // Show the user a jumbotron indicating account deletion. + jumbotron::new("Account deletion", "Your account was deleted successfully.") .render_into_page(&req, "Account deletion") - .await?, - ); + .await } diff --git a/src/web/services/user/profile.rs b/src/web/services/user/profile.rs index 4c50fdb5..72b3ba0a 100644 --- a/src/web/services/user/profile.rs +++ b/src/web/services/user/profile.rs @@ -114,11 +114,7 @@ async fn profile( let rcos_discord: u64 = global_config() .discord_config - .rcos_guild_id() - .ok_or_else(|| { - error!("Could not parse RCOS Discord Guild ID."); - TelescopeError::ise("Bad RCOS Discord Guild ID.") - })?; + .rcos_guild_id(); // Target user as member of RCOS discord. let membership: Option = global_discord_client()