diff --git a/src/main.rs b/src/main.rs index 8fe1716..8aec7b1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -107,7 +107,7 @@ async fn handle_download( let store = data.state.read().await; let info = store.0.get(code); let info = if let Some(i) = info { - i.clone() + i.file.clone() } else { return not_found(req, data, true); }; @@ -165,7 +165,7 @@ async fn download_info( let store = data.state.read().await; let info = store.0.get(code); let info = if let Some(i) = info { - i.clone() + i.file.clone() } else { return not_found(req, data, true); }; diff --git a/src/state.rs b/src/state.rs index 3ea75b1..b7e6635 100644 --- a/src/state.rs +++ b/src/state.rs @@ -69,24 +69,32 @@ pub mod v1 { #[serde_as(as = "time::format_description::well_known::Rfc3339")] pub expiry: OffsetDateTime, pub contents: Option, + } + + #[derive(Debug, Clone, Deserialize, Serialize)] + pub struct StoredFileWithPassword { + #[serde(flatten)] + pub file: StoredFile, /// None password means the admin page can't be accessed pub password: Option, } - impl From for StoredFile { + impl From for StoredFileWithPassword { fn from(old: super::v0::StoredFile) -> Self { - StoredFile { - name: old.name, - size: old.size, - modtime: old.modtime, - expiry: old.expiry, - contents: old.contents.map(FileSet::from), + StoredFileWithPassword { + file: StoredFile { + name: old.name, + size: old.size, + modtime: old.modtime, + expiry: old.expiry, + contents: old.contents.map(FileSet::from), + }, password: None, } } } #[derive(Debug, Default, Deserialize, Serialize)] - pub struct StoredFiles(pub HashMap); + pub struct StoredFiles(pub HashMap); pub type State = StoredFiles; @@ -98,7 +106,7 @@ pub mod v1 { StoredFiles( old.0 .into_iter() - .map(|(k, v)| (k, StoredFile::from(v))) + .map(|(k, v)| (k, StoredFileWithPassword::from(v))) .collect(), ) } diff --git a/src/store.rs b/src/store.rs index f7ab3f6..1bd611e 100644 --- a/src/store.rs +++ b/src/store.rs @@ -28,7 +28,7 @@ pub fn is_valid_storage_code(s: &str) -> bool { .all(|c| c.is_ascii_alphanumeric() || c == &b'-') } -pub use crate::state::v1::{StoredFile, StoredFiles}; +pub use crate::state::v1::{StoredFile, StoredFileWithPassword, StoredFiles}; async fn is_valid_entry(key: &str, info: &StoredFile, storage_dir: &Path) -> bool { if info.expiry < OffsetDateTime::now_utc() { @@ -95,7 +95,7 @@ impl crate::AppData { error!("Invalid key in persistent storage: {}", key); continue; } - if is_valid_entry(&key, &info, &self.config.storage_dir).await { + if is_valid_entry(&key, &info.file, &self.config.storage_dir).await { store.0.insert(key, info); } else { info!("Deleting file {}", key); @@ -108,16 +108,16 @@ impl crate::AppData { /// Attempts to add a file to the store. Returns an I/O error if /// something's broken, or a u64 of the maximum allowed file size /// if the file was too big, or a unit if everything worked. - pub async fn add_file(&self, key: String, file: StoredFile) -> Result<(), FileAddError> { + pub async fn add_file(&self, key: String, entry: StoredFileWithPassword) -> Result<(), FileAddError> { let mut store = self.state.write().await; if store.full(self.config.max_storage_size) { return Err(FileAddError::Full); } let available_size = store.available_size(self.config.max_storage_size); - if file.size > available_size { + if entry.file.size > available_size { return Err(FileAddError::TooBig(available_size)); } - store.0.insert(key, file); + store.0.insert(key, entry); Ok(()) } @@ -136,9 +136,9 @@ impl crate::AppData { let now = OffsetDateTime::now_utc(); let mut store = self.state.write().await; let old = std::mem::take(store.deref_mut()); - for (key, file) in old.0.into_iter() { - if file.expiry > now { - store.0.insert(key, file); + for (key, value) in old.0.into_iter() { + if value.file.expiry > now { + store.0.insert(key, value); } else { info!("Deleting expired file {}", key); delete_file_if_exists(&self.config.storage_dir.join(&key)).await?; @@ -150,7 +150,7 @@ impl crate::AppData { impl StoredFiles { fn total_size(&self) -> u64 { - self.0.iter().fold(0, |acc, (_, f)| acc + f.size) + self.0.iter().fold(0, |acc, (_, v)| acc + v.file.size) } pub fn available_size(&self, max_storage_size: u64) -> u64 { diff --git a/src/upload.rs b/src/upload.rs index 4d8185f..94f80b8 100644 --- a/src/upload.rs +++ b/src/upload.rs @@ -13,7 +13,7 @@ use unicode_normalization::UnicodeNormalization; use crate::{ log_auth_failure, - store::{self, FileAddError, StoredFile}, + store::{self, FileAddError, StoredFile, StoredFileWithPassword}, zip::FileSet, AppData, }; @@ -316,12 +316,14 @@ impl Uploader { ) }; self.writer = Some(writer); - let stored_file = StoredFile { - name, - size, - modtime, - expiry: OffsetDateTime::now_utc() + lifetime * time::Duration::DAY, - contents, + let stored_file = StoredFileWithPassword { + file: StoredFile { + name, + size, + modtime, + expiry: OffsetDateTime::now_utc() + lifetime * time::Duration::DAY, + contents, + }, password: None, }; let app_data = self.app_data.clone();