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(); | 
