2022-08-16 04:54:18 -04:00
|
|
|
use jsondb::JsonDb;
|
|
|
|
|
2022-11-10 12:41:51 -05:00
|
|
|
pub mod prelude {
|
2022-08-16 06:16:00 -04:00
|
|
|
pub use std::collections::HashMap;
|
2022-08-16 04:54:18 -04:00
|
|
|
|
2022-08-16 06:16:00 -04:00
|
|
|
pub use jsondb::Schema;
|
|
|
|
pub use serde::{Deserialize, Serialize};
|
|
|
|
pub use serde_with::serde_as;
|
|
|
|
pub use serde_with::skip_serializing_none;
|
|
|
|
pub use time::OffsetDateTime;
|
2022-11-10 12:41:51 -05:00
|
|
|
|
|
|
|
pub trait SizedFile {
|
|
|
|
fn size(&self) -> u64;
|
|
|
|
|
|
|
|
fn formatted_size(&self) -> String {
|
2023-09-09 17:04:45 -04:00
|
|
|
bytesize::to_string(self.size(), false).replace(' ', "")
|
2022-11-10 12:41:51 -05:00
|
|
|
}
|
|
|
|
}
|
2022-08-16 06:16:00 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
mod v0;
|
|
|
|
|
|
|
|
pub mod v1 {
|
|
|
|
//! Schema version 1
|
|
|
|
//!
|
|
|
|
//! Changes:
|
|
|
|
//!
|
|
|
|
//! * Represent times in RFC3339 format instead of epoch seconds
|
|
|
|
//! * Ditch some pre-JsonDb ad-hoc migrations
|
|
|
|
//! * Stored files now have optional passwords for
|
|
|
|
//! deleting/extending them, stored in plaintext because the
|
|
|
|
//! threat model doesn't warrant anything stronger
|
|
|
|
|
|
|
|
use super::prelude::*;
|
|
|
|
|
|
|
|
#[serde_as]
|
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
|
|
|
pub struct UploadedFile {
|
|
|
|
pub name: String,
|
|
|
|
pub size: u64,
|
|
|
|
#[serde_as(as = "time::format_description::well_known::Rfc3339")]
|
|
|
|
pub modtime: OffsetDateTime,
|
|
|
|
}
|
|
|
|
impl From<super::v0::UploadedFile> for UploadedFile {
|
|
|
|
fn from(old: super::v0::UploadedFile) -> Self {
|
|
|
|
UploadedFile {
|
|
|
|
name: old.name,
|
|
|
|
size: old.size,
|
|
|
|
modtime: old.modtime,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-11-10 12:41:51 -05:00
|
|
|
impl SizedFile for UploadedFile {
|
2023-09-09 17:04:45 -04:00
|
|
|
fn size(&self) -> u64 {
|
|
|
|
self.size
|
|
|
|
}
|
2022-11-10 12:41:51 -05:00
|
|
|
}
|
2022-08-16 06:16:00 -04:00
|
|
|
|
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
|
|
|
pub struct FileSet {
|
|
|
|
pub files: Vec<UploadedFile>,
|
|
|
|
// Optional for backwards compatibility only
|
|
|
|
pub directory_name: Option<String>,
|
|
|
|
}
|
|
|
|
impl From<super::v0::FileSet> for FileSet {
|
|
|
|
fn from(old: super::v0::FileSet) -> Self {
|
|
|
|
FileSet {
|
|
|
|
files: old.files.into_iter().map(UploadedFile::from).collect(),
|
|
|
|
directory_name: old.directory_name,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[serde_as]
|
|
|
|
#[skip_serializing_none]
|
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
|
|
|
pub struct StoredFile {
|
|
|
|
pub name: String,
|
|
|
|
pub size: u64,
|
|
|
|
#[serde_as(as = "time::format_description::well_known::Rfc3339")]
|
|
|
|
pub modtime: OffsetDateTime,
|
|
|
|
#[serde_as(as = "time::format_description::well_known::Rfc3339")]
|
|
|
|
pub expiry: OffsetDateTime,
|
|
|
|
pub contents: Option<FileSet>,
|
2022-08-16 16:46:39 -04:00
|
|
|
}
|
2022-11-10 12:41:51 -05:00
|
|
|
impl SizedFile for StoredFile {
|
2023-09-09 17:04:45 -04:00
|
|
|
fn size(&self) -> u64 {
|
|
|
|
self.size
|
|
|
|
}
|
2022-11-10 12:41:51 -05:00
|
|
|
}
|
2022-08-16 16:46:39 -04:00
|
|
|
|
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
|
|
|
pub struct StoredFileWithPassword {
|
|
|
|
#[serde(flatten)]
|
|
|
|
pub file: StoredFile,
|
2022-08-16 06:16:00 -04:00
|
|
|
/// None password means the admin page can't be accessed
|
|
|
|
pub password: Option<String>,
|
|
|
|
}
|
2022-08-16 16:46:39 -04:00
|
|
|
impl From<super::v0::StoredFile> for StoredFileWithPassword {
|
2022-08-16 06:16:00 -04:00
|
|
|
fn from(old: super::v0::StoredFile) -> Self {
|
2022-08-16 16:46:39 -04:00
|
|
|
StoredFileWithPassword {
|
|
|
|
file: StoredFile {
|
|
|
|
name: old.name,
|
|
|
|
size: old.size,
|
|
|
|
modtime: old.modtime,
|
|
|
|
expiry: old.expiry,
|
|
|
|
contents: old.contents.map(FileSet::from),
|
|
|
|
},
|
2022-08-16 06:16:00 -04:00
|
|
|
password: None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
2022-08-16 16:46:39 -04:00
|
|
|
pub struct StoredFiles(pub HashMap<String, StoredFileWithPassword>);
|
2022-08-16 06:16:00 -04:00
|
|
|
|
|
|
|
pub type State = StoredFiles;
|
|
|
|
|
|
|
|
impl Schema for State {
|
|
|
|
type Prev = super::v0::State;
|
|
|
|
}
|
|
|
|
impl From<super::v0::State> for State {
|
|
|
|
fn from(old: super::v0::State) -> Self {
|
|
|
|
StoredFiles(
|
|
|
|
old.0
|
|
|
|
.into_iter()
|
2022-08-16 16:46:39 -04:00
|
|
|
.map(|(k, v)| (k, StoredFileWithPassword::from(v)))
|
2022-08-16 06:16:00 -04:00
|
|
|
.collect(),
|
|
|
|
)
|
|
|
|
}
|
2022-08-16 04:54:18 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-16 06:16:00 -04:00
|
|
|
pub use v1::State;
|
2022-08-16 04:54:18 -04:00
|
|
|
pub type StateDb = JsonDb<State>;
|