diff options
| author | alpaylan | 2021-04-16 01:03:21 +0300 |
|---|---|---|
| committer | alpaylan | 2021-04-16 01:03:21 +0300 |
| commit | b4212a90caa899785402c06d57216e75de0f1c88 (patch) | |
| tree | 8adbe6eb6b451eee20d181f26ab771e0c5a920ee /src/schema.rs | |
| parent | 82864341afc78b23b358cd775c70ffbfa0d0303f (diff) | |
| parent | 72f8ae422eeb03ed87c7819af5d5e25758267b03 (diff) | |
| download | gradecoin-b4212a90caa899785402c06d57216e75de0f1c88.tar.gz gradecoin-b4212a90caa899785402c06d57216e75de0f1c88.tar.bz2 gradecoin-b4212a90caa899785402c06d57216e75de0f1c88.zip | |
Merge remote-tracking branch 'origin/main'
# Conflicts:
# src/schema.rs
Diffstat (limited to 'src/schema.rs')
| -rw-r--r-- | src/schema.rs | 73 |
1 files changed, 59 insertions, 14 deletions
diff --git a/src/schema.rs b/src/schema.rs index 264d2bd..cb353e4 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 |
| 10 | use chrono::{NaiveDate, NaiveDateTime}; | 10 | use chrono::{NaiveDate, NaiveDateTime}; |
| 11 | use lazy_static::lazy_static; | 11 | use lazy_static::lazy_static; |
| 12 | use log::debug; | ||
| 12 | use parking_lot::RwLock; | 13 | use parking_lot::RwLock; |
| 13 | use serde::{Deserialize, Serialize}; | 14 | use serde::{Deserialize, Serialize}; |
| 14 | use std::collections::{HashMap, HashSet}; | 15 | use std::collections::{HashMap, HashSet}; |
| @@ -23,8 +24,6 @@ use std::vec::Vec; | |||
| 23 | 24 | ||
| 24 | pub type Fingerprint = String; | 25 | pub type Fingerprint = String; |
| 25 | 26 | ||
| 26 | // TODO: start by reading users from file too <14-04-21, yigit> // | ||
| 27 | |||
| 28 | fn block_parser(path: String) -> u64 { | 27 | fn block_parser(path: String) -> u64 { |
| 29 | let end_pos = path.find(".block").unwrap(); | 28 | let end_pos = path.find(".block").unwrap(); |
| 30 | let block_str = path[9..end_pos].to_string(); | 29 | let block_str = path[9..end_pos].to_string(); |
| @@ -63,16 +62,49 @@ fn read_block_name() -> io::Result<Vec<PathBuf>> { | |||
| 63 | Ok(entries) | 62 | Ok(entries) |
| 64 | } | 63 | } |
| 65 | 64 | ||
| 66 | fn create_db_with_last_block(path: String) -> Db { | 65 | fn read_users() -> io::Result<Vec<PathBuf>> { |
| 66 | let entries = fs::read_dir("./users")? | ||
| 67 | .map(|res| res.map(|e| e.path())) | ||
| 68 | .collect::<Result<Vec<_>, io::Error>>()?; | ||
| 69 | |||
| 70 | Ok(entries) | ||
| 71 | } | ||
| 72 | |||
| 73 | fn populate_db_with_last_block(db: &mut Db, path: String) -> &mut Db { | ||
| 74 | debug!("Populating db with last block {}", path); | ||
| 67 | let file = fs::read(path).unwrap(); | 75 | let file = fs::read(path).unwrap(); |
| 68 | let json = std::str::from_utf8(&file).unwrap(); | 76 | let json = std::str::from_utf8(&file).unwrap(); |
| 69 | let block: Block = serde_json::from_str(json).unwrap(); | 77 | let block: Block = serde_json::from_str(json).unwrap(); |
| 70 | let db = Db::new(); | ||
| 71 | *db.blockchain.write() = block; | 78 | *db.blockchain.write() = block; |
| 72 | return db; | 79 | |
| 80 | db | ||
| 81 | } | ||
| 82 | |||
| 83 | #[derive(Debug, Serialize, Deserialize, PartialEq)] | ||
| 84 | pub struct UserAtRest { | ||
| 85 | pub fingerprint: Fingerprint, | ||
| 86 | pub user: User, | ||
| 73 | } | 87 | } |
| 74 | 88 | ||
| 75 | /// Creates a new database, uses the previous last block if one exists | 89 | fn populate_db_with_users(db: &mut Db, files: Vec<PathBuf>) -> &mut Db { |
| 90 | for fs in files { | ||
| 91 | if let Ok(file_content) = fs::read(fs) { | ||
| 92 | let json = | ||
| 93 | String::from_utf8(file_content).expect("we have written a malformed user file"); | ||
| 94 | let user_at_rest: UserAtRest = serde_json::from_str(&json).unwrap(); | ||
| 95 | |||
| 96 | debug!("Populating db with user: {:?}", user_at_rest); | ||
| 97 | db.users | ||
| 98 | .write() | ||
| 99 | .insert(user_at_rest.fingerprint, user_at_rest.user); | ||
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 103 | db | ||
| 104 | } | ||
| 105 | |||
| 106 | /// Creates a new database, uses the previous last block if one exists and attempts the populate | ||
| 107 | /// the users | ||
| 76 | pub fn create_database() -> Db { | 108 | pub fn create_database() -> Db { |
| 77 | fs::create_dir_all("blocks").unwrap(); | 109 | fs::create_dir_all("blocks").unwrap(); |
| 78 | fs::create_dir_all("users").unwrap(); | 110 | fs::create_dir_all("users").unwrap(); |
| @@ -82,6 +114,12 @@ pub fn create_database() -> Db { | |||
| 82 | } else { | 114 | } else { |
| 83 | return Db::new(); | 115 | return Db::new(); |
| 84 | } | 116 | } |
| 117 | |||
| 118 | if let Ok(users_path) = read_users() { | ||
| 119 | populate_db_with_users(&mut db, users_path); | ||
| 120 | } | ||
| 121 | |||
| 122 | db | ||
| 85 | } | 123 | } |
| 86 | 124 | ||
| 87 | /// A JWT Payload/Claims representation | 125 | /// A JWT Payload/Claims representation |
| @@ -181,13 +219,23 @@ impl Block { | |||
| 181 | Block { | 219 | Block { |
| 182 | transaction_list: vec!["gradecoin_bank".to_owned()], | 220 | transaction_list: vec!["gradecoin_bank".to_owned()], |
| 183 | nonce: 0, | 221 | nonce: 0, |
| 184 | timestamp: NaiveDate::from_ymd(2021, 04, 11).and_hms(20, 45, 00), | 222 | timestamp: NaiveDate::from_ymd(2021, 4, 11).and_hms(20, 45, 00), |
| 185 | hash: String::from("not_actually_mined"), | 223 | hash: String::from("not_actually_mined"), |
| 186 | } | 224 | } |
| 187 | } | 225 | } |
| 188 | } | 226 | } |
| 189 | 227 | ||
| 190 | /// Simply a Student | 228 | impl Default for Block { |
| 229 | fn default() -> Self { | ||
| 230 | Self::new() | ||
| 231 | } | ||
| 232 | } | ||
| 233 | |||
| 234 | /// A Student | ||
| 235 | /// | ||
| 236 | /// * [`user_id`]: Can only be one of the repopulated | ||
| 237 | /// * [`public_key`]: A PEM format public key "---- BEGIN" and all | ||
| 238 | /// * [`balance`]: User's current Gradecoin amount | ||
| 191 | #[derive(Serialize, Deserialize, Debug, PartialEq)] | 239 | #[derive(Serialize, Deserialize, Debug, PartialEq)] |
| 192 | pub struct User { | 240 | pub struct User { |
| 193 | pub user_id: MetuId, | 241 | pub user_id: MetuId, |
| @@ -196,7 +244,7 @@ pub struct User { | |||
| 196 | } | 244 | } |
| 197 | 245 | ||
| 198 | /// The values are hard coded in [`OUR_STUDENTS`] so MetuId::new() can accept/reject values based on that | 246 | /// The values are hard coded in [`OUR_STUDENTS`] so MetuId::new() can accept/reject values based on that |
| 199 | #[derive(Serialize, Deserialize, Debug, PartialEq)] | 247 | #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] |
| 200 | pub struct MetuId { | 248 | pub struct MetuId { |
| 201 | id: String, | 249 | id: String, |
| 202 | passwd: String, | 250 | passwd: String, |
| @@ -214,7 +262,7 @@ pub struct AuthRequest { | |||
| 214 | #[derive(Serialize, Deserialize, Debug)] | 262 | #[derive(Serialize, Deserialize, Debug)] |
| 215 | pub struct InitialAuthRequest { | 263 | pub struct InitialAuthRequest { |
| 216 | pub c: String, | 264 | pub c: String, |
| 217 | pub iv: [u8; 32], | 265 | pub iv: String, |
| 218 | pub key: String, | 266 | pub key: String, |
| 219 | } | 267 | } |
| 220 | 268 | ||
| @@ -265,10 +313,7 @@ impl fmt::Display for MetuId { | |||
| 265 | impl MetuId { | 313 | impl MetuId { |
| 266 | pub fn new(id: String, pwd: String) -> Option<Self> { | 314 | pub fn new(id: String, pwd: String) -> Option<Self> { |
| 267 | if OUR_STUDENTS.contains(&(&*id, &*pwd)) { | 315 | if OUR_STUDENTS.contains(&(&*id, &*pwd)) { |
| 268 | Some(MetuId { | 316 | Some(MetuId { id, passwd: pwd }) |
| 269 | id: id, | ||
| 270 | passwd: pwd, | ||
| 271 | }) | ||
| 272 | } else { | 317 | } else { |
| 273 | None | 318 | None |
| 274 | } | 319 | } |
