diff options
Diffstat (limited to 'src/model.rs')
-rw-r--r-- | src/model.rs | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/model.rs b/src/model.rs new file mode 100644 index 0000000..ed4fbf8 --- /dev/null +++ b/src/model.rs @@ -0,0 +1,52 @@ +use base64::{engine::general_purpose::URL_SAFE, Engine as _}; +use chrono::{DateTime, Local, NaiveDateTime, TimeZone}; +use rand_core::{OsRng, RngCore}; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct File { + pub id: String, + pub name: String, + pub expires_at: DateTime<Local>, + pub content_length: usize, +} + +pub fn local_time() -> DateTime<Local> { + let dt = Local::now(); + match decode_datetime(&encode_datetime(dt)) { + Some(res) => res, + None => dt, + } +} + +// Using 20 bytes (160 bits) to file identifiers +// https://owasp.org/www-community/vulnerabilities/Insufficient_Session-ID_Length +// https://www.rfc-editor.org/rfc/rfc6749.html#section-10.10 +const FILE_ID_BYTES: usize = 20; + +pub fn generate_file_id() -> String { + let mut token = [0u8; FILE_ID_BYTES]; + OsRng.fill_bytes(&mut token); + URL_SAFE.encode(token) +} + +const FORMAT: &str = "%Y-%m-%d %H:%M:%S"; + +pub fn encode_datetime(dt: DateTime<Local>) -> String { + dt.naive_utc().format(FORMAT).to_string() +} + +pub fn decode_datetime(str: &str) -> Option<DateTime<Local>> { + let naive_time = NaiveDateTime::parse_from_str(str, FORMAT).ok()?; + Some(Local.from_utc_datetime(&naive_time)) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_datetime_serialization() { + let dt = local_time(); + assert_eq!(decode_datetime(&encode_datetime(dt)), Some(dt)) + } +} |