summaryrefslogtreecommitdiffstats
path: root/src/schema.rs
diff options
context:
space:
mode:
authoralpaylan2021-04-16 01:03:21 +0300
committeralpaylan2021-04-16 01:03:21 +0300
commitb4212a90caa899785402c06d57216e75de0f1c88 (patch)
tree8adbe6eb6b451eee20d181f26ab771e0c5a920ee /src/schema.rs
parent82864341afc78b23b358cd775c70ffbfa0d0303f (diff)
parent72f8ae422eeb03ed87c7819af5d5e25758267b03 (diff)
downloadgradecoin-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.rs73
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
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,8 +24,6 @@ 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> //
27
28fn block_parser(path: String) -> u64 { 27fn 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
66fn create_db_with_last_block(path: String) -> Db { 65fn 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
73fn 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)]
84pub 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 89fn 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
76pub fn create_database() -> Db { 108pub 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 228impl 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)]
192pub struct User { 240pub 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)]
200pub struct MetuId { 248pub 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)]
215pub struct InitialAuthRequest { 263pub 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 {
265impl MetuId { 313impl 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 }