diff --git a/src/confirmation.rs b/src/confirmation.rs index 59da817..620693a 100644 --- a/src/confirmation.rs +++ b/src/confirmation.rs @@ -9,7 +9,7 @@ use std::path::Path; pub fn confirm_action(token: &str) -> Result<(), Error> { let pending_path = pending_path!().join(token); - let content = if pending_path.exists() { + let content = if pending_path.is_file() { match fs::read_to_string(&pending_path) { Ok(content) => content, Err(_) => return Err(Error::Inaccessible), diff --git a/src/errors.rs b/src/errors.rs index 8c1b1c9..6cc1dcc 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -19,6 +19,8 @@ pub enum Error { DeserializeData, #[error("File or directory does not exist")] MissingPath, + #[error("Requested key does not exist")] + MissingKey, #[error("The file is inaccessible")] Inaccessible, #[error("Error while adding a key to the wkd")] @@ -29,6 +31,7 @@ impl actix_web::ResponseError for Error { fn status_code(&self) -> actix_web::http::StatusCode { match self { Self::MissingPath => StatusCode::from_u16(404).unwrap(), + Self::MissingKey => StatusCode::from_u16(404).unwrap(), _ => StatusCode::from_u16(500).unwrap(), } } diff --git a/src/main.rs b/src/main.rs index c7fee8d..ab701c2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,8 @@ mod errors; mod management; mod utils; +use crate::utils::key_exists; + use self::confirmation::{confirm_action, send_confirmation_email}; use self::management::{clean_stale, store_pending_addition, store_pending_deletion, Action}; use self::utils::{gen_random_token, get_email_from_cert, parse_pem}; @@ -69,6 +71,7 @@ async fn confirm(token: web::Path) -> Result { #[get("/api/delete/{address}")] async fn delete(email: web::Path) -> Result { + key_exists(&email.address)?; let token = gen_random_token(); store_pending_deletion(email.address.clone(), &token)?; send_confirmation_email(&email.address, &Action::Delete, &token); diff --git a/src/management.rs b/src/management.rs index 5dfd5d3..e3a9b86 100644 --- a/src/management.rs +++ b/src/management.rs @@ -73,7 +73,7 @@ pub fn store_pending_deletion(email: String, token: &str) -> Result<(), Error> { pub fn clean_stale(max_age: i64) -> Result<(), Error> { for path in fs::read_dir(pending_path!()).unwrap().flatten() { let file_path = path.path(); - if file_path.exists() { + if file_path.is_file() { let content = match fs::read_to_string(&file_path) { Ok(content) => content, Err(_) => return Err(Error::Inaccessible), diff --git a/src/utils.rs b/src/utils.rs index f8c2e5f..22c53b5 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,10 +1,10 @@ use crate::errors::Error; -use crate::VARIANT; +use crate::{PATH, PENDING, VARIANT}; use rand::{distributions::Alphanumeric, thread_rng, Rng}; use sequoia_net::wkd::Url; use sequoia_openpgp::{parse::Parse, Cert}; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; #[macro_export] macro_rules! pending_path { @@ -50,3 +50,11 @@ pub fn get_user_file_path(email: &str) -> Result { Err(_) => Err(Error::ParseMail), } } + +pub fn key_exists(email: &str) -> Result { + let path = get_user_file_path(email)?; + if !pending_path!().join(path).is_file() { + return Err(Error::MissingKey); + } + Ok(true) +}