diff options
Diffstat (limited to 'src/handlers.rs')
-rw-r--r-- | src/handlers.rs | 83 |
1 files changed, 70 insertions, 13 deletions
diff --git a/src/handlers.rs b/src/handlers.rs index 856970d..bfd57bc 100644 --- a/src/handlers.rs +++ b/src/handlers.rs | |||
@@ -1,10 +1,62 @@ | |||
1 | /// API handlers, the ends of each filter chain | 1 | /// API handlers, the ends of each filter chain |
2 | use log::debug; // this is more useful than debug! learn how to use this | 2 | use log::debug; |
3 | use parking_lot::RwLockUpgradableReadGuard; | 3 | use parking_lot::RwLockUpgradableReadGuard; |
4 | use serde_json; | ||
4 | use std::convert::Infallible; | 5 | use std::convert::Infallible; |
5 | use warp::{http::StatusCode, reply}; | 6 | use warp::{http::Response, http::StatusCode, reply}; |
6 | 7 | ||
7 | use crate::schema::{Block, Db, Transaction}; | 8 | use std::fs; |
9 | |||
10 | use crate::schema::{AuthRequest, Block, Db, MetuId, Transaction, User}; | ||
11 | |||
12 | /// POST /register | ||
13 | /// Enables a student to introduce themselves to the system | ||
14 | /// Can fail | ||
15 | pub async fn authenticate_user( | ||
16 | request: AuthRequest, | ||
17 | db: Db, | ||
18 | ) -> Result<impl warp::Reply, warp::Rejection> { | ||
19 | let given_id = request.student_id.clone(); | ||
20 | |||
21 | if let Some(priv_student_id) = MetuId::new(request.student_id) { | ||
22 | let userlist = db.users.upgradable_read(); | ||
23 | |||
24 | if userlist.contains_key(&given_id) { | ||
25 | |||
26 | let res = Response::builder() | ||
27 | .status(StatusCode::BAD_REQUEST) | ||
28 | .body("This user is already authenticated"); | ||
29 | |||
30 | Ok(res) | ||
31 | } else { | ||
32 | let new_user = User { | ||
33 | user_id: priv_student_id, | ||
34 | public_key: request.public_key, | ||
35 | balance: 0, | ||
36 | }; | ||
37 | |||
38 | let user_json = serde_json::to_string(&new_user).unwrap(); | ||
39 | |||
40 | fs::write(format!("users/{}.guy", new_user.user_id), user_json).unwrap(); | ||
41 | |||
42 | let mut userlist = RwLockUpgradableReadGuard::upgrade(userlist); | ||
43 | userlist.insert(given_id, new_user); | ||
44 | // TODO: signature of the public key, please <11-04-21, yigit> // | ||
45 | |||
46 | let res = Response::builder() | ||
47 | .status(StatusCode::CREATED) | ||
48 | .body("Ready to use Gradecoin"); | ||
49 | |||
50 | Ok(res) | ||
51 | } | ||
52 | } else { | ||
53 | let res = Response::builder() | ||
54 | .status(StatusCode::BAD_REQUEST) | ||
55 | .body("This user cannot have a gradecoin account"); | ||
56 | |||
57 | Ok(res) | ||
58 | } | ||
59 | } | ||
8 | 60 | ||
9 | /// GET /transaction | 61 | /// GET /transaction |
10 | /// Returns JSON array of transactions | 62 | /// Returns JSON array of transactions |
@@ -28,16 +80,11 @@ pub async fn list_transactions(db: Db) -> Result<impl warp::Reply, Infallible> { | |||
28 | /// Cannot fail | 80 | /// Cannot fail |
29 | /// Mostly around for debug purposes | 81 | /// Mostly around for debug purposes |
30 | pub async fn list_blocks(db: Db) -> Result<impl warp::Reply, Infallible> { | 82 | pub async fn list_blocks(db: Db) -> Result<impl warp::Reply, Infallible> { |
31 | debug!("list all blocks"); | 83 | debug!("list all block"); |
32 | |||
33 | let mut result = Vec::new(); | ||
34 | let blocks = db.blockchain.read(); | ||
35 | 84 | ||
36 | for block in blocks.iter() { | 85 | let block = db.blockchain.read(); |
37 | result.push(block); | ||
38 | } | ||
39 | 86 | ||
40 | Ok(reply::with_status(reply::json(&result), StatusCode::OK)) | 87 | Ok(reply::with_status(reply::json(&*block), StatusCode::OK)) |
41 | } | 88 | } |
42 | 89 | ||
43 | /// POST /transaction | 90 | /// POST /transaction |
@@ -70,7 +117,7 @@ pub async fn propose_block(new_block: Block, db: Db) -> Result<impl warp::Reply, | |||
70 | let pending_transactions = db.pending_transactions.upgradable_read(); | 117 | let pending_transactions = db.pending_transactions.upgradable_read(); |
71 | let blockchain = db.blockchain.upgradable_read(); | 118 | let blockchain = db.blockchain.upgradable_read(); |
72 | 119 | ||
73 | // TODO: check 1, new_block.transaction_list from pending_transactions pool? <07-04-21, yigit> // | 120 | // check 1, new_block.transaction_list from pending_transactions pool? <07-04-21, yigit> // |
74 | for transaction_hash in new_block.transaction_list.iter() { | 121 | for transaction_hash in new_block.transaction_list.iter() { |
75 | if !pending_transactions.contains_key(transaction_hash) { | 122 | if !pending_transactions.contains_key(transaction_hash) { |
76 | return Ok(StatusCode::BAD_REQUEST); | 123 | return Ok(StatusCode::BAD_REQUEST); |
@@ -81,7 +128,17 @@ pub async fn propose_block(new_block: Block, db: Db) -> Result<impl warp::Reply, | |||
81 | // assume it is for now | 128 | // assume it is for now |
82 | 129 | ||
83 | let mut blockchain = RwLockUpgradableReadGuard::upgrade(blockchain); | 130 | let mut blockchain = RwLockUpgradableReadGuard::upgrade(blockchain); |
84 | blockchain.push(new_block); | 131 | |
132 | let block_json = serde_json::to_string(&new_block).unwrap(); | ||
133 | |||
134 | // let mut file = File::create(format!("{}.block", new_block.timestamp.timestamp())).unwrap(); | ||
135 | fs::write( | ||
136 | format!("blocks/{}.block", new_block.timestamp.timestamp()), | ||
137 | block_json, | ||
138 | ) | ||
139 | .unwrap(); | ||
140 | |||
141 | *blockchain = new_block; | ||
85 | 142 | ||
86 | let mut pending_transactions = RwLockUpgradableReadGuard::upgrade(pending_transactions); | 143 | let mut pending_transactions = RwLockUpgradableReadGuard::upgrade(pending_transactions); |
87 | pending_transactions.clear(); | 144 | pending_transactions.clear(); |