aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/db.rs39
-rw-r--r--src/handlers.rs36
-rw-r--r--src/student.rs70
3 files changed, 56 insertions, 89 deletions
diff --git a/src/db.rs b/src/db.rs
index fd5c1be..f2921f8 100644
--- a/src/db.rs
+++ b/src/db.rs
@@ -14,13 +14,14 @@ use log::debug;
14use parking_lot::RwLock; 14use parking_lot::RwLock;
15use std::{collections::HashMap, fs, io, path::PathBuf, sync::Arc}; 15use std::{collections::HashMap, fs, io, path::PathBuf, sync::Arc};
16 16
17const PREAPPROVED_STU_FILENAME: &str = "students.csv";
18
17#[derive(Debug, Clone, Default)] 19#[derive(Debug, Clone, Default)]
18pub struct Db { 20pub struct Db {
19 pub blockchain: Arc<RwLock<Block>>, 21 pub blockchain: Arc<RwLock<Block>>,
20 pub pending_transactions: Arc<RwLock<HashMap<Id, Transaction>>>, 22 pub pending_transactions: Arc<RwLock<HashMap<Id, Transaction>>>,
21 pub users: Arc<RwLock<HashMap<Fingerprint, User>>>, 23 pub users: Arc<RwLock<HashMap<Fingerprint, User>>>,
22 approved_users: Vec<MetuId>, 24 preapproved_users: Vec<MetuId>,
23 // TODO: metu_ids or approved_users or something, metu_id struct <11-04-22, yigit> //
24} 25}
25 26
26impl Db { 27impl Db {
@@ -37,13 +38,13 @@ impl Db {
37 } 38 }
38 39
39 let users: HashMap<Fingerprint, User> = get_friendly_users(); 40 let users: HashMap<Fingerprint, User> = get_friendly_users();
40 let approved_users = read_approved_users(); 41 let preapproved_users = read_approved_users();
41 42
42 Db { 43 Db {
43 blockchain: Arc::new(RwLock::new(Block::default())), 44 blockchain: Arc::new(RwLock::new(Block::default())),
44 pending_transactions: Arc::new(RwLock::new(HashMap::new())), 45 pending_transactions: Arc::new(RwLock::new(HashMap::new())),
45 users: Arc::new(RwLock::new(users)), 46 users: Arc::new(RwLock::new(users)),
46 approved_users, 47 preapproved_users,
47 } 48 }
48 } 49 }
49 50
@@ -69,6 +70,16 @@ impl Db {
69 } 70 }
70 } 71 }
71 } 72 }
73
74 pub fn is_user_preapproved(&self, id: &Id, passwd: &String) -> bool {
75 for user in &self.preapproved_users {
76 if *user.get_id() == *id && *user.get_passwd() == *passwd {
77 return true;
78 }
79 }
80
81 false
82 }
72} 83}
73 84
74fn last_block_content() -> Option<String> { 85fn last_block_content() -> Option<String> {
@@ -122,7 +133,7 @@ fn get_friendly_users() -> HashMap<Fingerprint, User> {
122 users.insert( 133 users.insert(
123 "cde48537ca2c28084ff560826d0e6388b7c57a51497a6cb56f397289e52ff41b".to_owned(), 134 "cde48537ca2c28084ff560826d0e6388b7c57a51497a6cb56f397289e52ff41b".to_owned(),
124 User { 135 User {
125 user_id: MetuId::new("friend_1".to_owned(), "not_used".to_owned()).unwrap(), 136 user_id: MetuId::new("friend_1".to_owned(), "not_used".to_owned()),
126 public_key: "not_used".to_owned(), 137 public_key: "not_used".to_owned(),
127 balance: 70, 138 balance: 70,
128 is_bot: true, 139 is_bot: true,
@@ -132,7 +143,7 @@ fn get_friendly_users() -> HashMap<Fingerprint, User> {
132 users.insert( 143 users.insert(
133 "a1a38b5bae5866d7d998a9834229ec2f9db7a4fc8fb6f58b1115a96a446875ff".to_owned(), 144 "a1a38b5bae5866d7d998a9834229ec2f9db7a4fc8fb6f58b1115a96a446875ff".to_owned(),
134 User { 145 User {
135 user_id: MetuId::new("friend_2".to_owned(), "not_used".to_owned()).unwrap(), 146 user_id: MetuId::new("friend_2".to_owned(), "not_used".to_owned()),
136 public_key: "not_used".to_owned(), 147 public_key: "not_used".to_owned(),
137 balance: 20, 148 balance: 20,
138 is_bot: true, 149 is_bot: true,
@@ -142,7 +153,7 @@ fn get_friendly_users() -> HashMap<Fingerprint, User> {
142 users.insert( 153 users.insert(
143 "4e048fd2a62f1307866086e803e9be43f78a702d5df10831fbf434e7663ae0e7".to_owned(), 154 "4e048fd2a62f1307866086e803e9be43f78a702d5df10831fbf434e7663ae0e7".to_owned(),
144 User { 155 User {
145 user_id: MetuId::new("friend_4".to_owned(), "not_used".to_owned()).unwrap(), 156 user_id: MetuId::new("friend_4".to_owned(), "not_used".to_owned()),
146 public_key: "not_used".to_owned(), 157 public_key: "not_used".to_owned(),
147 balance: 120, 158 balance: 120,
148 is_bot: true, 159 is_bot: true,
@@ -152,7 +163,7 @@ fn get_friendly_users() -> HashMap<Fingerprint, User> {
152 users.insert( 163 users.insert(
153 "60e77101e76950a9b1830fa107fd2f8fc545255b3e0f14b6a7797cf9ee005f07".to_owned(), 164 "60e77101e76950a9b1830fa107fd2f8fc545255b3e0f14b6a7797cf9ee005f07".to_owned(),
154 User { 165 User {
155 user_id: MetuId::new("friend_4".to_owned(), "not_used".to_owned()).unwrap(), 166 user_id: MetuId::new("friend_4".to_owned(), "not_used".to_owned()),
156 public_key: "not_used".to_owned(), 167 public_key: "not_used".to_owned(),
157 balance: 40, 168 balance: 40,
158 is_bot: true, 169 is_bot: true,
@@ -163,11 +174,19 @@ fn get_friendly_users() -> HashMap<Fingerprint, User> {
163 174
164fn read_approved_users() -> Vec<MetuId> { 175fn read_approved_users() -> Vec<MetuId> {
165 let mut approved_students: Vec<MetuId> = Vec::new(); 176 let mut approved_students: Vec<MetuId> = Vec::new();
166 let contents = fs::read_to_string("students.csv").unwrap(); 177 let contents = fs::read_to_string(PREAPPROVED_STU_FILENAME).unwrap_or_else(|_| {
178 panic!(
179 "{}",
180 format!(
181 "Expected {} to load preapproved students",
182 PREAPPROVED_STU_FILENAME
183 )
184 )
185 });
167 let mut reader = csv::Reader::from_reader(contents.as_bytes()); 186 let mut reader = csv::Reader::from_reader(contents.as_bytes());
168 for student in reader.records() { 187 for student in reader.records() {
169 let student = student.unwrap(); 188 let student = student.unwrap();
170 approved_students.push(MetuId::_new(student[0].to_owned(), student[1].to_owned())); 189 approved_students.push(MetuId::new(student[0].to_owned(), student[1].to_owned()));
171 } 190 }
172 approved_students 191 approved_students
173} 192}
diff --git a/src/handlers.rs b/src/handlers.rs
index 96001ce..ca0608c 100644
--- a/src/handlers.rs
+++ b/src/handlers.rs
@@ -220,7 +220,7 @@ pub async fn authenticate_user(
220 }; 220 };
221 221
222 // c field was properly base64 encoded, now available in auth_packet 222 // c field was properly base64 encoded, now available in auth_packet
223 // decryptor was setup properly, with the correct lenght key 223 // decryptor was setup properly, with the correct length key
224 let mut buf = auth_packet; 224 let mut buf = auth_packet;
225 let auth_plaintext = match cipher.decrypt(&mut buf) { 225 let auth_plaintext = match cipher.decrypt(&mut buf) {
226 Ok(p) => p, 226 Ok(p) => p,
@@ -278,24 +278,22 @@ pub async fn authenticate_user(
278 }; 278 };
279 279
280 // is the student in AuthRequest privileged? 280 // is the student in AuthRequest privileged?
281 // TODO: this is the only check for 'if metuid is approved' <15-04-22, yigit> // 281 let privileged_student_id = if db.is_user_preapproved(&request.student_id, &request.passwd) {
282 let privileged_student_id = 282 MetuId::new(request.student_id.clone(), request.passwd.clone())
283 if let Some(id) = MetuId::new(request.student_id.clone(), request.passwd.clone()) { 283 } else {
284 id 284 debug!(
285 } else { 285 "Someone tried to auth with invalid credentials: {} {}",
286 debug!( 286 &request.student_id, &request.passwd
287 "Someone tried to auth with invalid credentials: {} {}", 287 );
288 &request.student_id, &request.passwd 288 let res_json = warp::reply::json(&GradeCoinResponse {
289 ); 289 res: ResponseType::Error,
290 let res_json = warp::reply::json(&GradeCoinResponse { 290 message:
291 res: ResponseType::Error, 291 "The credentials given ('student_id', 'passwd') cannot hold a Gradecoin account"
292 message: 292 .to_owned(),
293 "The credentials given ('student_id', 'passwd') cannot hold a Gradecoin account" 293 });
294 .to_owned(),
295 });
296 294
297 return Ok(warp::reply::with_status(res_json, StatusCode::BAD_REQUEST)); 295 return Ok(warp::reply::with_status(res_json, StatusCode::BAD_REQUEST));
298 }; 296 };
299 297
300 // Students should be able to authenticate once 298 // Students should be able to authenticate once
301 { 299 {
@@ -382,7 +380,7 @@ pub async fn list_transactions(db: Db) -> Result<impl warp::Reply, Infallible> {
382/// Proposes a new block for the next round. 380/// Proposes a new block for the next round.
383/// Can reject the block 381/// Can reject the block
384/// 382///
385/// The proposer has to put their transaction as the first transaction of the transaction_list. 383/// The proposer has to put their transaction as the first transaction of the `Block::transaction_list`.
386/// This is the analogue of `coinbase` in Bitcoin works 384/// This is the analogue of `coinbase` in Bitcoin works
387/// 385///
388/// The `coinbase` transaction also gets something for their efforts. 386/// The `coinbase` transaction also gets something for their efforts.
diff --git a/src/student.rs b/src/student.rs
index 711eeeb..2b9c5bd 100644
--- a/src/student.rs
+++ b/src/student.rs
@@ -1,7 +1,6 @@
1use crate::Fingerprint; 1use crate::{Fingerprint, Id};
2use lazy_static::lazy_static;
3use serde::{Deserialize, Serialize}; 2use serde::{Deserialize, Serialize};
4use std::{collections::HashSet, fmt}; 3use std::fmt;
5 4
6#[derive(Debug, Serialize, Deserialize, PartialEq)] 5#[derive(Debug, Serialize, Deserialize, PartialEq)]
7pub struct UserAtRest { 6pub struct UserAtRest {
@@ -25,11 +24,9 @@ pub struct User {
25 pub is_bot: bool, 24 pub is_bot: bool,
26} 25}
27 26
28/// The values are hard coded in [`static@OUR_STUDENTS`] so `MetuId::new`() can accept/reject values based on that
29/// TODO update the statement above
30#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] 27#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
31pub struct MetuId { 28pub struct MetuId {
32 id: String, 29 id: Id,
33 passwd: String, 30 passwd: String,
34} 31}
35 32
@@ -40,62 +37,15 @@ impl fmt::Display for MetuId {
40} 37}
41 38
42impl MetuId { 39impl MetuId {
43 pub fn new(id: String, pwd: String) -> Option<Self> { 40 pub fn new(id: String, passwd: String) -> Self {
44 if OUR_STUDENTS.contains(&(&*id, &*pwd)) { 41 MetuId { id, passwd }
45 Some(MetuId { id, passwd: pwd })
46 } else {
47 None
48 }
49 } 42 }
50 43
51 // TODO: replace the function above with this <15-04-22, yigit> // 44 pub fn get_id(&self) -> &Id {
52 pub fn _new(id: String, passwd: String) -> Self { 45 &self.id
53 MetuId { id, passwd }
54 } 46 }
55}
56 47
57// TODO: remove this, read from a yaml or something, then MetuId::new gets a self <11-04-22, yigit> // 48 pub fn get_passwd(&self) -> &String {
58// Students who are authorized to have Gradecoin accounts 49 &self.passwd
59lazy_static! { 50 }
60 static ref OUR_STUDENTS: HashSet<(&'static str, &'static str)> = {
61 [
62 ("e254275", "DtNX1qk4YF4saRH"),
63 ("e223687", "cvFEs4XLjuGBD1v"),
64 ("e211024", "voQAcxiKJmEXYRT"),
65 ("e209888", "O75dli6AQtz2tUi"),
66 ("e223725", "xXuTD3Y4tyrv2Jz"),
67 ("e209362", "N7wGm5XU5zVWOWu"),
68 ("e209898", "aKBFfB8fZMq8pVn"),
69 ("e230995", "TgcHGlqeFhQGx42"),
70 ("e223743", "YVWVSWuIHplJk9C"),
71 ("e223747", "8LAeHrsjnwXh59Q"),
72 ("e223749", "HMFeJqVOzwCPHbc"),
73 ("e223751", "NjMsxmtmy2VOwMW"),
74 ("e188126", "QibuPdV2gXfsVJW"),
75 ("e209913", "kMxJvl2vHSWCy4A"),
76 ("e203608", "mfkkR0MWurk6Rp1"),
77 ("e233013", "GCqHxdOaDj2pWXx"),
78 ("e216982", "2Z0xmgCStnj5qg5"),
79 ("e217185", "BcaZNlzlhPph7A3"),
80 ("e223780", "2KvVxKUQaA9H4sn"),
81 ("e194931", "hsC0Wb8PQ5vzwdQ"),
82 ("e223783", "ETUJA3kt1QYvJai"),
83 ("e254550", "rPRjX0A4NefvKWi"),
84 ("e217203", "lN3IWhGyCrGfkk5"),
85 ("e217477", "O9xlMaa7LanC82w"),
86 ("e223786", "UxI6czykJfp9T9N"),
87 ("e231060", "VJgziofQQPCoisH"),
88 ("e223795", "pmcTCKox99NFsqp"),
89 ("e223715", "1H5QuOYI1b2r9ET"),
90 ("e181932", "THANKYOUHAVEFUN"),
91 ("bank", "P7oxDm30g1jeIId"),
92 ("friend_1", "not_used"),
93 ("friend_2", "not_used"),
94 ("friend_3", "not_used"),
95 ("friend_4", "not_used"),
96 ]
97 .iter()
98 .copied()
99 .collect()
100 };
101} 51}