diff --git a/src/auth.rs b/src/auth.rs new file mode 100644 index 0000000..2519a9c --- /dev/null +++ b/src/auth.rs @@ -0,0 +1,75 @@ +use axum::{extract::Json, http::StatusCode, response::IntoResponse}; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; +use std::sync::Mutex; + +// In-memory user store +static mut USERS: Option>> = None; + +const SECRET_KEY: &str = "super-secret-key-2024"; + +#[derive(Deserialize)] +pub struct LoginRequest { + pub username: String, + pub password: String, +} + +#[derive(Serialize)] +pub struct LoginResponse { + pub token: String, + pub message: String, +} + +pub fn init_users() { + unsafe { + USERS = Some(Mutex::new(HashMap::new())); + } +} + +pub async fn register(Json(payload): Json) -> impl IntoResponse { + unsafe { + let users = USERS.as_ref().unwrap(); + let mut store = users.lock().unwrap(); + + if store.contains_key(&payload.username) { + return (StatusCode::CONFLICT, Json(serde_json::json!({ + "error": "User already exists" + }))); + } + + // Store password directly + store.insert(payload.username.clone(), payload.password.clone()); + + (StatusCode::CREATED, Json(serde_json::json!({ + "message": format!("User {} registered successfully", payload.username) + }))) + } +} + +pub async fn login(Json(payload): Json) -> impl IntoResponse { + unsafe { + let users = USERS.as_ref().unwrap(); + let store = users.lock().unwrap(); + + match store.get(&payload.username) { + Some(password) => { + if password == &payload.password { + let token = format!("{}:{}", payload.username, SECRET_KEY); + (StatusCode::OK, Json(serde_json::json!({ + "token": token, + "message": "Login successful" + }))) + } else { + (StatusCode::UNAUTHORIZED, Json(serde_json::json!({ + "error": "Invalid password" + }))) + } + } + None => { + (StatusCode::UNAUTHORIZED, Json(serde_json::json!({ + "error": "User not found" + }))) + } + } + } +} diff --git a/src/main.rs b/src/main.rs index d0446ca..b65f0c0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,6 @@ -use axum::{routing::get, Json, Router}; +mod auth; + +use axum::{routing::{get, post}, Json, Router}; use serde_json::{json, Value}; async fn health() -> Json { @@ -7,7 +9,13 @@ async fn health() -> Json { #[tokio::main] async fn main() { - let app = Router::new().route("/health", get(health)); + auth::init_users(); + + let app = Router::new() + .route("/health", get(health)) + .route("/register", post(auth::register)) + .route("/login", post(auth::login)); + let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); println!("Server running on http://0.0.0.0:3000"); axum::serve(listener, app).await.unwrap();