aboutsummaryrefslogtreecommitdiff
path: root/src/model.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/model.rs')
-rw-r--r--src/model.rs52
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))
+ }
+}