diff --git a/visions/server/Cargo.toml b/visions/server/Cargo.toml index b1a3edc..031dace 100644 --- a/visions/server/Cargo.toml +++ b/visions/server/Cargo.toml @@ -4,6 +4,9 @@ version = "0.1.0" edition = "2021" [dependencies] -axum = "0.8.1" +axum = { version = "0.8.1", features = ["macros"] } +serde = { version = "1.0.217", features = ["derive", "serde_derive"] } tokio = { version = "1.43.0", features = ["full", "rt"] } tower-http = { version = "0.6.2", features = ["cors"] } +typeshare = "1.0.4" +uuid = { version = "1.13.1", features = ["v4"] } diff --git a/visions/server/src/main.rs b/visions/server/src/main.rs index 54d9196..bed0623 100644 --- a/visions/server/src/main.rs +++ b/visions/server/src/main.rs @@ -1,5 +1,60 @@ -use axum::{http::{Method, StatusCode}, routing::get, Json, Router}; +use axum::{http::{Method, StatusCode}, routing::{get, post}, Json, Router}; +use serde::{Deserialize, Serialize}; use tower_http::cors::{Any, CorsLayer}; +use typeshare::typeshare; +use uuid::Uuid; + +#[derive(Deserialize, Serialize)] +#[typeshare] +struct AuthRequest { + username: String, + password: String +} + +#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +#[typeshare] +pub struct SessionId(String); + +impl SessionId { + pub fn new() -> Self { + Self(format!("{}", Uuid::new_v4().hyphenated())) + } + + pub fn as_str(&self) -> &str { + &self.0 + } +} + +impl From<&str> for SessionId { + fn from(s: &str) -> Self { + Self(s.to_owned()) + } +} + +impl From<String> for SessionId { + fn from(s: String) -> Self { + Self(s) + } +} + +#[derive(Deserialize, Serialize)] +#[typeshare] +enum AuthResponse { + Success(SessionId), + PasswordReset(SessionId), +} + +#[axum::debug_handler] +async fn check_password(request: Json<AuthRequest>) -> (StatusCode, Json<Option<AuthResponse>>) { + let Json(request) = request; + if request.username == "vakarian" && request.password == "aoeu" { + (StatusCode::OK, Json(Some(AuthResponse::Success("vakarian-session-id".into())))) + } else if request.username == "shephard" && request.password == "aoeu" { + (StatusCode::OK, Json(Some(AuthResponse::PasswordReset("shephard-session-id".into())))) + } else { + (StatusCode::UNAUTHORIZED, Json(None)) + } +} #[tokio::main] async fn main() { @@ -12,11 +67,11 @@ async fn main() { .allow_methods([Method::GET]).allow_origin(Any), ) .route( - "/api/v1/denied", - get(|| async { (StatusCode::UNAUTHORIZED, Json(None::<String>)) }), + "/api/v1/auth", + post(|req: Json<AuthRequest>| check_password(req)), ).layer( CorsLayer::new() - .allow_methods([Method::GET]).allow_origin(Any), + .allow_methods([Method::POST]).allow_origin(Any), ); let listener = tokio::net::TcpListener::bind("127.0.0.1:8001") .await