summaryrefslogtreecommitdiffstats
path: root/src/schema.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/schema.rs')
-rw-r--r--src/schema.rs65
1 files changed, 51 insertions, 14 deletions
diff --git a/src/schema.rs b/src/schema.rs
index 79fee2d..80cf73f 100644
--- a/src/schema.rs
+++ b/src/schema.rs
@@ -9,6 +9,7 @@
9//! Users are held in memory and they're also backed up to text files 9//! Users are held in memory and they're also backed up to text files
10use chrono::{NaiveDate, NaiveDateTime}; 10use chrono::{NaiveDate, NaiveDateTime};
11use lazy_static::lazy_static; 11use lazy_static::lazy_static;
12use log::debug;
12use parking_lot::RwLock; 13use parking_lot::RwLock;
13use serde::{Deserialize, Serialize}; 14use serde::{Deserialize, Serialize};
14use std::collections::{HashMap, HashSet}; 15use std::collections::{HashMap, HashSet};
@@ -23,17 +24,15 @@ use std::vec::Vec;
23 24
24pub type Fingerprint = String; 25pub type Fingerprint = String;
25 26
26// TODO: start by reading users from file too <14-04-21, yigit> // 27fn last_block_exists() -> Option<String> {
27
28fn last_block_exists() -> (bool, String) {
29 let blocks = read_block_name().unwrap(); 28 let blocks = read_block_name().unwrap();
30 for block in blocks { 29 for block in blocks {
31 let block = block.to_str().unwrap(); 30 let block = block.to_str().unwrap();
32 if block.contains("last.block") { 31 if block.contains("last.block") {
33 return (true, block.to_string()); 32 return Some(block.to_string());
34 } 33 }
35 } 34 }
36 (false, "".to_string()) 35 None
37} 36}
38 37
39fn read_block_name() -> io::Result<Vec<PathBuf>> { 38fn read_block_name() -> io::Result<Vec<PathBuf>> {
@@ -44,26 +43,64 @@ fn read_block_name() -> io::Result<Vec<PathBuf>> {
44 Ok(entries) 43 Ok(entries)
45} 44}
46 45
47fn create_db_with_last_block(path: String) -> Db { 46fn read_users() -> io::Result<Vec<PathBuf>> {
47 let entries = fs::read_dir("./users")?
48 .map(|res| res.map(|e| e.path()))
49 .collect::<Result<Vec<_>, io::Error>>()?;
50
51 Ok(entries)
52}
53
54fn populate_db_with_last_block(db: &mut Db, path: String) -> &mut Db {
55 debug!("Populating db with last block {}", path);
48 let file = fs::read(path).unwrap(); 56 let file = fs::read(path).unwrap();
49 let json = std::str::from_utf8(&file).unwrap(); 57 let json = std::str::from_utf8(&file).unwrap();
50 let block: Block = serde_json::from_str(json).unwrap(); 58 let block: Block = serde_json::from_str(json).unwrap();
51 let db = Db::new();
52 *db.blockchain.write() = block; 59 *db.blockchain.write() = block;
53 60
54 db 61 db
55} 62}
56 63
57/// Creates a new database, uses the previous last block if one exists 64#[derive(Debug, Serialize, Deserialize, PartialEq)]
65pub struct UserAtRest {
66 pub fingerprint: Fingerprint,
67 pub user: User,
68}
69
70fn populate_db_with_users(db: &mut Db, files: Vec<PathBuf>) -> &mut Db {
71 for fs in files {
72 if let Ok(file_content) = fs::read(fs) {
73 let json =
74 String::from_utf8(file_content).expect("we have written a malformed user file");
75 let user_at_rest: UserAtRest = serde_json::from_str(&json).unwrap();
76
77 debug!("Populating db with user: {:?}", user_at_rest);
78 db.users
79 .write()
80 .insert(user_at_rest.fingerprint, user_at_rest.user);
81 }
82 }
83
84 db
85}
86
87/// Creates a new database, uses the previous last block if one exists and attempts the populate
88/// the users
58pub fn create_database() -> Db { 89pub fn create_database() -> Db {
59 fs::create_dir_all("blocks").unwrap(); 90 fs::create_dir_all("blocks").unwrap();
60 fs::create_dir_all("users").unwrap(); 91 fs::create_dir_all("users").unwrap();
61 let (res, path) = last_block_exists(); 92
62 if res { 93 let mut db = Db::new();
63 create_db_with_last_block(path) 94
64 } else { 95 if let Some(blocks_path) = last_block_exists() {
65 Db::new() 96 populate_db_with_last_block(&mut db, blocks_path);
97 }
98
99 if let Ok(users_path) = read_users() {
100 populate_db_with_users(&mut db, users_path);
66 } 101 }
102
103 db
67} 104}
68 105
69/// A JWT Payload/Claims representation 106/// A JWT Payload/Claims representation
@@ -188,7 +225,7 @@ pub struct User {
188} 225}
189 226
190/// The values are hard coded in [`OUR_STUDENTS`] so MetuId::new() can accept/reject values based on that 227/// The values are hard coded in [`OUR_STUDENTS`] so MetuId::new() can accept/reject values based on that
191#[derive(Serialize, Deserialize, Debug, PartialEq)] 228#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
192pub struct MetuId { 229pub struct MetuId {
193 id: String, 230 id: String,
194 passwd: String, 231 passwd: String,