From b0dd796dfea80794fe486ca346e03005fa0e730e Mon Sep 17 00:00:00 2001 From: Sebastian Pravda Date: Sat, 14 Jan 2023 22:37:07 +0100 Subject: [PATCH] feat: limit application count to 2 per candidate --- core/src/error.rs | 3 +++ core/src/services/application_service.rs | 6 +++++- core/src/services/portfolio_service.rs | 22 ++++++++-------------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/core/src/error.rs b/core/src/error.rs index adecdfb..40303ac 100644 --- a/core/src/error.rs +++ b/core/src/error.rs @@ -20,6 +20,8 @@ pub enum ServiceError { CandidateNotFound, #[error("Resource is locked")] Locked, + #[error("Too many applications")] + TooManyApplications, #[error("Parrent not found")] ParentNotFound, #[error("Database error")] @@ -82,6 +84,7 @@ impl ServiceError { ServiceError::IncompletePortfolio => 406, ServiceError::UserAlreadyExists => 409, ServiceError::Locked => 423, + ServiceError::TooManyApplications => 409, // 500 ServiceError::ParentNotFound => 500, ServiceError::DbError(_) => 500, diff --git a/core/src/services/application_service.rs b/core/src/services/application_service.rs index 3d7bb55..f9f9d1b 100644 --- a/core/src/services/application_service.rs +++ b/core/src/services/application_service.rs @@ -97,12 +97,16 @@ impl ApplicationService { .await? .ok_or(ServiceError::CandidateNotFound)?; - let mut linked_applications_pubkeys = Query::find_applications_by_candidate_id(db, candidate.id) + let mut linked_applications_pubkeys: Vec = Query::find_applications_by_candidate_id(db, candidate.id) .await? .iter() .map(|a| a.public_key.to_owned()) .collect(); + if linked_applications_pubkeys.len() > 1 { + return Err(ServiceError::TooManyApplications); + } + recipients.append(&mut linked_applications_pubkeys); diff --git a/core/src/services/portfolio_service.rs b/core/src/services/portfolio_service.rs index ec0dc05..e03ffcf 100644 --- a/core/src/services/portfolio_service.rs +++ b/core/src/services/portfolio_service.rs @@ -8,7 +8,7 @@ use tokio::io::{AsyncReadExt, AsyncWriteExt}; use crate::{error::ServiceError, Query, crypto}; -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub enum SubmissionProgress { NoneInCache, SomeInCache(Vec), @@ -50,7 +50,7 @@ impl Serialize for SubmissionProgress { } -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, PartialEq, Clone)] pub enum FileType { CoverLetterPdf = 1, PortfolioLetterPdf = 2, @@ -216,17 +216,7 @@ impl PortfolioService { /// Returns true if portfolio is ready to be moved to the final directory async fn is_portfolio_prepared(candidate_id: i32) -> bool { - let cache_path = Self::get_file_store_path().join(&candidate_id.to_string()).join("cache"); - - let filenames = vec![FileType::CoverLetterPdf, FileType::PortfolioLetterPdf, FileType::PortfolioZip]; - for filename in filenames { - if !tokio::fs::metadata( - cache_path.join(filename.as_str()) - ).await.is_ok() { - return false; - } - } - true + Self::get_submission_progress(candidate_id).await.ok() == Some(SubmissionProgress::AllInCache) } // Delete single item from cache @@ -306,10 +296,14 @@ impl PortfolioService { writer.close().await?; archive.shutdown().await?; + let applications_pubkeys: Vec = Query::find_applications_by_candidate_id(db, candidate_id) + .await?.iter().map(|a| a.public_key.to_owned()).collect(); let admin_public_keys = Query::get_all_admin_public_keys(db).await?; let mut admin_public_keys_refrence: Vec<&str> = admin_public_keys.iter().map(|s| &**s).collect(); - let mut recipients = vec![&**public_key]; + + let mut recipients = vec![]; recipients.append(&mut admin_public_keys_refrence); + recipients.append(&mut applications_pubkeys.iter().map(|s| &**s).collect()); let final_path = path.join(FileType::PortfolioZip.as_str());