17 changed files with 209 additions and 28 deletions
@ -0,0 +1,6 @@ |
|||||
|
### |
||||
|
GET /api/user HTTP/1.1 |
||||
|
Host: localhost:7878 |
||||
|
User-Agent: curl/7.68.0 |
||||
|
Accept: */* |
||||
|
Authorization: Bearer 3e1d1902151506191008255c46523e1f1b0d150217001f0937525b503406020d1f0c092c19102b4b5e5568160212010f00331d1b3e544758375912091e |
||||
@ -1 +1,2 @@ |
|||||
pub mod auth; |
pub mod auth; |
||||
|
pub mod user_controller; |
||||
@ -0,0 +1,63 @@ |
|||||
|
use tokio::net::TcpStream; |
||||
|
use tokio::io::AsyncWriteExt; |
||||
|
|
||||
|
use crate::models::token::Token; |
||||
|
use crate::models::user_info::UserInfo; |
||||
|
use crate::models::HttpRequest::HttpRequest; |
||||
|
use crate::utils::{crypt, jwt}; |
||||
|
|
||||
|
pub async fn get_user_info(http_request: HttpRequest, stream: &mut TcpStream) { |
||||
|
// Placeholder for actual user info retrieval logic
|
||||
|
|
||||
|
let authorization = http_request.headers.authorization.clone().unwrap_or_default(); |
||||
|
let token_str = authorization.strip_prefix("Bearer ").unwrap_or(""); |
||||
|
println!("Extracted token: {}", token_str); |
||||
|
let token = crate::utils::crypt::decrypt(token_str); |
||||
|
println!("Decrypted token: {:?}", token); |
||||
|
|
||||
|
if !jwt::verify_token(&token) { |
||||
|
let response = "HTTP/1.1 401 Unauthorized\r\n\r\nInvalid or missing token"; |
||||
|
if let Err(e) = stream.write_all(response.as_bytes()).await { |
||||
|
eprintln!("Error writing response: {}", e); |
||||
|
} |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
let token = match jwt::extract(&token) { |
||||
|
Some(token) => token, |
||||
|
None => { |
||||
|
let response = "HTTP/1.1 400 Bad Request\r\n\r\nMalformed token"; |
||||
|
if let Err(e) = stream.write_all(response.as_bytes()).await { |
||||
|
eprintln!("Error writing response: {}", e); |
||||
|
} |
||||
|
return; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
let user_info = match crate::services::users::get_user_profile(token).await { |
||||
|
Ok(Some(info)) => info, |
||||
|
Ok(None) => { |
||||
|
let response = "HTTP/1.1 404 Not Found\r\n\r\nUser not found"; |
||||
|
if let Err(e) = stream.write_all(response.as_bytes()).await { |
||||
|
eprintln!("Error writing response: {}", e); |
||||
|
} |
||||
|
return; |
||||
|
} |
||||
|
Err(e) => { |
||||
|
let response = format!("HTTP/1.1 500 Internal Server Error\r\n\r\nError: {}", e); |
||||
|
if let Err(e) = stream.write_all(response.as_bytes()).await { |
||||
|
eprintln!("Error writing response: {}", e); |
||||
|
} |
||||
|
return; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
let response = format!( |
||||
|
"HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n{{\"id\": {}, \"username\": \"{}\", \"email\": \"{}\"}}", |
||||
|
user_info.id, user_info.username, user_info.email |
||||
|
); |
||||
|
if let Err(e) = stream.write_all(response.as_bytes()).await { |
||||
|
eprintln!("Error writing response: {}", e); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,7 @@ |
|||||
|
use serde::{Deserialize, Serialize}; |
||||
|
|
||||
|
#[derive(Debug, Serialize, Deserialize)] |
||||
|
pub struct Token { |
||||
|
pub email: String, |
||||
|
pub username: String |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
use serde::{Deserialize, Serialize}; |
||||
|
|
||||
|
#[derive(Debug, Serialize, Deserialize)] |
||||
|
pub struct UserInfo { |
||||
|
pub id: i32, |
||||
|
pub username: String, |
||||
|
pub email: String, |
||||
|
} |
||||
@ -1,3 +1,4 @@ |
|||||
pub mod proxy; |
pub mod proxy; |
||||
pub mod statics; |
pub mod statics; |
||||
pub mod auth; |
pub mod auth; |
||||
|
pub mod user_routes; |
||||
@ -0,0 +1,22 @@ |
|||||
|
use crate::models::HttpRequest::HttpRequest; |
||||
|
use tokio::net::TcpStream as TokioTcpStream; |
||||
|
use tokio::io::AsyncWriteExt; |
||||
|
|
||||
|
pub async fn handle_user_request(http_request: HttpRequest, stream: &mut TokioTcpStream) { |
||||
|
// Placeholder for user request handling logic
|
||||
|
let path = http_request.headers.path.clone().unwrap_or_default().join("/"); |
||||
|
|
||||
|
match path.as_str() { |
||||
|
"/api/user" => { |
||||
|
// Call the get_user_info function from user_controller
|
||||
|
crate::controllers::user_controller::get_user_info(http_request, stream).await; |
||||
|
} |
||||
|
_ => { |
||||
|
let response = "HTTP/1.1 404 Not Found\r\n\r\n"; |
||||
|
if let Err(e) = stream.write_all(response.as_bytes()).await { |
||||
|
eprintln!("Error writing response: {}", e); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,28 @@ |
|||||
|
use crate::models::token::Token; |
||||
|
|
||||
|
pub fn verify_token(token: &str) -> bool { |
||||
|
let token_parts: Vec<&str> = token.split('_').collect(); |
||||
|
if token_parts.len() != 2 { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
if token_parts[0] != std::env::var("JWT_KEY").unwrap_or_default() { |
||||
|
return false; |
||||
|
} |
||||
|
true |
||||
|
} |
||||
|
|
||||
|
pub fn extract(token: &str) -> Option<Token> { |
||||
|
let token_parts: Vec<&str> = token.split('_').collect(); |
||||
|
if token_parts.len() != 2 { |
||||
|
return None; |
||||
|
} |
||||
|
let user_info: Vec<&str> = token_parts[1].split(':').collect(); |
||||
|
if user_info.len() != 2 { |
||||
|
return None; |
||||
|
} |
||||
|
Some(Token { |
||||
|
username: user_info[0].to_string(), |
||||
|
email: user_info[1].to_string() |
||||
|
}) |
||||
|
} |
||||
@ -1,2 +1,3 @@ |
|||||
pub mod db; |
pub mod db; |
||||
pub mod crypt; |
pub mod crypt; |
||||
|
pub mod jwt; |
||||
Loading…
Reference in new issue