-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: improve the RSA encryption so that it can parse hex strings
- Loading branch information
Showing
11 changed files
with
197 additions
and
27 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,15 @@ | ||
# ZVMS 4 Backend Implementation with Rust | ||
|
||
The first version of backend of ZVMS 4 is a `shit mountain` of code. | ||
|
||
Since I am learning `Rust`, I decided to rewrite the backend in `Rust`. | ||
|
||
Technologies used: | ||
|
||
- `axum`: Web framework | ||
- `tokio`: Async runtime | ||
- `mongodb`: Database | ||
|
||
> You should have `Rust` installed in your system to run this project. | ||
> You need to create `src/config.rs` with following code: | ||
```rust | ||
pub const MONGO_URL: &str = "<MONGO_URL>"; | ||
``` | ||
# ZVMS 4 Backend Implementation with Rust | ||
|
||
[![JWT](https://jwt.io/img/badge-compatible.svg)](https://jwt.io/) | ||
|
||
![Test](https://github.com/zvms/zvms4-backend-rust/actions/workflows/test.yml/badge.svg) ![Build](https://github.com/zvms/zvms4-backend-rust/actions/workflows/release.yml/badge.svg) | ||
|
||
The first version of backend of ZVMS 4 is a `shit mountain` of code. | ||
|
||
Since I am learning `Rust`, I decided to rewrite the backend in `Rust`. | ||
|
||
Technologies used: | ||
|
||
- `axum`: Web framework | ||
- `tokio`: Async runtime | ||
- `mongodb`: Database |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
use crate::{ | ||
models::{ | ||
activities::{Activity, ActivityMember}, | ||
groups::GroupPermission, | ||
response::{ErrorResponse, ResponseStatus, SuccessResponse}, | ||
}, | ||
utils::jwt::UserData, | ||
}; | ||
use axum::{ | ||
extract::{Extension, Json, Path}, | ||
http::StatusCode, | ||
response::IntoResponse, | ||
}; | ||
use bson::{doc, oid::ObjectId}; | ||
use mongodb::Database; | ||
use std::{str::FromStr, sync::Arc}; | ||
use tokio::sync::Mutex; | ||
|
||
pub async fn insert_member_into_activity( | ||
Extension(db): Extension<Arc<Mutex<Database>>>, | ||
user: UserData, | ||
Path(id): Path<String>, | ||
Json(activity_member): Json<ActivityMember>, | ||
) -> impl IntoResponse { | ||
let db = db.lock().await; | ||
let collection = db.collection("activities"); | ||
let activity_id = ObjectId::from_str(&id).unwrap(); | ||
let activity = collection.find_one(doc! {"_id": activity_id}, None).await; | ||
if let Err(_) = activity { | ||
let response = ErrorResponse { | ||
status: ResponseStatus::Error, | ||
code: 404, | ||
message: "Activity not found".to_string(), | ||
}; | ||
let response = serde_json::to_string(&response).unwrap(); | ||
return (StatusCode::NOT_FOUND, Json(response)); | ||
} | ||
let activity = activity.unwrap(); | ||
if let None = activity { | ||
let response = ErrorResponse { | ||
status: ResponseStatus::Error, | ||
code: 404, | ||
message: "Activity not found".to_string(), | ||
}; | ||
let response = serde_json::to_string(&response).unwrap(); | ||
return (StatusCode::NOT_FOUND, Json(response)); | ||
} | ||
let activity: Activity = bson::from_document(activity.unwrap()).unwrap(); | ||
let members = activity.members.unwrap_or_default(); | ||
// Check if the activity contains the member | ||
if members | ||
.iter() | ||
.any(|member| member._id == ObjectId::from_str(&activity_member._id.to_hex()).unwrap()) | ||
{ | ||
let response = ErrorResponse { | ||
status: ResponseStatus::Error, | ||
code: 400, | ||
message: "Member already exists".to_string(), | ||
}; | ||
let response = serde_json::to_string(&response).unwrap(); | ||
return (StatusCode::BAD_REQUEST, Json(response)); | ||
} | ||
if user.perms.contains(&GroupPermission::Admin) || user.perms.contains(&GroupPermission::Department) {} else { | ||
let response = ErrorResponse { | ||
status: ResponseStatus::Error, | ||
code: 403, | ||
message: "Permission denied".to_string(), | ||
}; | ||
let response = serde_json::to_string(&response).unwrap(); | ||
return (StatusCode::FORBIDDEN, Json(response)); | ||
} | ||
let member = bson::to_document(&activity_member); | ||
if let Err(_) = member { | ||
let response = ErrorResponse { | ||
status: ResponseStatus::Error, | ||
code: 400, | ||
message: "Invalid member".to_string(), | ||
}; | ||
let response = serde_json::to_string(&response).unwrap(); | ||
return (StatusCode::BAD_REQUEST, Json(response)); | ||
} | ||
let result = collection | ||
.update_one( | ||
doc! {"_id": activity_id}, | ||
doc! { | ||
"$push": { | ||
"members": member.unwrap() | ||
} | ||
}, | ||
None, | ||
) | ||
.await; | ||
if let Ok(_) = result { | ||
let response: SuccessResponse<_, ()> = SuccessResponse { | ||
status: ResponseStatus::Success, | ||
code: 200, | ||
data: (), | ||
metadata: None, | ||
}; | ||
let response = serde_json::to_string(&response).unwrap(); | ||
(StatusCode::OK, Json(response)) | ||
} else { | ||
let response = ErrorResponse { | ||
status: ResponseStatus::Error, | ||
code: 500, | ||
message: "Failed to insert member".to_string(), | ||
}; | ||
let response = serde_json::to_string(&response).unwrap(); | ||
(StatusCode::INTERNAL_SERVER_ERROR, Json(response)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub mod insert; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
use crate::{models::{activities::Activity}}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* | ||
Use user: 105 | ||
password: 105 | ||
ObjectId: 65e6fa210edc81d012ec483a | ||
*/ | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use crate::database::create_client; | ||
use crate::routers::auth::{login, LoginCredentials, LoginRequest}; | ||
use crate::utils::jwt::TokenType; | ||
use crate::utils::rsa::{encrypt, load_keypair}; | ||
use axum::extract::Extension; | ||
use axum::response::IntoResponse; | ||
use axum::Json; | ||
use std::sync::Arc; | ||
use std::time::SystemTime; | ||
use tokio::sync::Mutex; | ||
|
||
#[tokio::test] | ||
async fn test_login() { | ||
let client = create_client().await.unwrap(); | ||
let client = Arc::new(Mutex::new(client)); | ||
let client = Extension(client); | ||
let credential = LoginCredentials { | ||
password: "105".to_string(), | ||
timestamp: SystemTime::now() | ||
.duration_since(SystemTime::UNIX_EPOCH) | ||
.unwrap() | ||
.as_millis() as u64, | ||
}; | ||
let credential = serde_json::to_string(&credential).unwrap(); | ||
let (_, public_key) = load_keypair().await; | ||
let credential = encrypt(&public_key, credential.as_str()); | ||
let credential = hex::encode(credential); | ||
let request = LoginRequest { | ||
credentials: credential, | ||
userid: "65e6fa210edc81d012ec483a".to_string(), | ||
term: TokenType::LongTerm | ||
}; | ||
let result = login(client, Json(request)).await; | ||
let result = result.into_response(); | ||
assert!(result.status().is_success()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters