From 9dc278972f1c42192ada3c586455f72312cbe1e7 Mon Sep 17 00:00:00 2001 From: Mustafa Zaki Assagaf Date: Tue, 2 Apr 2024 23:08:07 +0700 Subject: [PATCH 1/2] refactor(auth_rust): remove dynamic dispatch trait and use generic trait --- auth_rust/src/main.rs | 71 ++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 41 deletions(-) diff --git a/auth_rust/src/main.rs b/auth_rust/src/main.rs index f77c51b..ce585c1 100644 --- a/auth_rust/src/main.rs +++ b/auth_rust/src/main.rs @@ -1,37 +1,47 @@ +use axum::extract::State; +use axum::http::{header, HeaderMap, StatusCode}; +use axum::response::IntoResponse; +use axum::routing::any; +use axum::{routing::get, Router}; +use redis::aio::MultiplexedConnection; +use redis::{AsyncCommands, Client}; use std::error::Error; use std::fmt::{Display, Formatter}; -use std::rc::Rc; -use axum::{Router, routing::{any, get}}; -use axum::http::{header, HeaderMap, StatusCode}; -use axum::response::{IntoResponse}; -use redis::{AsyncCommands, Client, Commands}; +use std::sync::Arc; use tokio::net::TcpListener; async fn healthcheck() -> impl IntoResponse { (StatusCode::OK, "OK") } -async fn authenticate(headers: HeaderMap) -> impl IntoResponse { +async fn authenticate( + headers: HeaderMap, + State(auth_repo): State>, // auth_repo: AuthRepo, +) -> impl IntoResponse { if let Some(token) = headers.get("X-Pesto-Token") { todo!(); - return (StatusCode::OK, [(header::CONTENT_TYPE, "application/json")], "{\"message\":\"OK\"}"); + return ( + StatusCode::OK, + [(header::CONTENT_TYPE, "application/json")], + r#"{"message":"OK\}"#, + ); } else { return ( StatusCode::UNAUTHORIZED, [(header::CONTENT_TYPE, "application/json")], - "{\"message\":\"Token must be supplied\"}", + r#"{"message":"Token must be supplied"}"#, ); } } enum AuthError { - TokenNotRegistered + TokenNotRegistered, } impl Display for AuthError { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { - AuthError::TokenNotRegistered => write!(f, "Token not registered") + AuthError::TokenNotRegistered => write!(f, "Token not registered"), } } } @@ -42,36 +52,14 @@ struct TokenValue { revoked: bool, } -trait AuthRepo { - fn acquire_token_value(&self, token: String) -> Result; - fn acquire_counter_limit(&self, token_value: TokenValue) -> Result; - fn increment_monthly_counter(&self, token_value: TokenValue, counter_limit: i64) -> Result<(), AuthError>; -} - -// Before you say anything, yes I don't have time to think of the correct naming -// We'll just do it Java-like. #[derive(Clone)] -struct AuthRepoImpl { - pub redis_client: Rc>, -} - -impl AuthRepoImpl { - fn new(redis_client: Rc>) -> Self { - return AuthRepoImpl{ redis_client } - } +struct AuthRepo { + pub redis_client: Arc, } -impl AuthRepo for AuthRepoImpl { - fn acquire_token_value(&self, token: String) -> Result { - todo!() - } - - fn acquire_counter_limit(&self, token_value: TokenValue) -> Result { - todo!() - } - - fn increment_monthly_counter(&self, token_value: TokenValue, counter_limit: i64) -> Result<(), AuthError> { - todo!() +impl AuthRepo { + fn new(redis_client: Arc) -> Self { + return AuthRepo { redis_client }; } } @@ -79,12 +67,13 @@ impl AuthRepo for AuthRepoImpl { async fn main() -> Result<(), Box> { let redis_client = Client::open("redis://@localhost:6739")?; let redis_async_connection = redis_client.get_multiplexed_async_connection().await?; - let rc_client = Rc::new(Box::new(redis_async_connection) as Box); + let rc_client = Arc::new(redis_async_connection); + let auth_repo = AuthRepo::new(rc_client); + let app = Router::new() .route("/healthz", get(healthcheck)) - .route("/", any(authenticate)) - .with_state(rc_client); - + .route("/", any(authenticate::)) + .with_state(auth_repo); let listener = TcpListener::bind("0.0.0.0:3000").await?; axum::serve(listener, app).await?; From 541c87b590e9068be33c6fffa562e478be681408 Mon Sep 17 00:00:00 2001 From: Mustafa Zaki Assagaf Date: Tue, 2 Apr 2024 23:44:26 +0700 Subject: [PATCH 2/2] feat(auth_rust): added back authrepo function and remove unnecessary code --- auth_rust/src/main.rs | 45 +++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/auth_rust/src/main.rs b/auth_rust/src/main.rs index ce585c1..9639979 100644 --- a/auth_rust/src/main.rs +++ b/auth_rust/src/main.rs @@ -3,11 +3,9 @@ use axum::http::{header, HeaderMap, StatusCode}; use axum::response::IntoResponse; use axum::routing::any; use axum::{routing::get, Router}; -use redis::aio::MultiplexedConnection; use redis::{AsyncCommands, Client}; use std::error::Error; use std::fmt::{Display, Formatter}; -use std::sync::Arc; use tokio::net::TcpListener; async fn healthcheck() -> impl IntoResponse { @@ -16,21 +14,19 @@ async fn healthcheck() -> impl IntoResponse { async fn authenticate( headers: HeaderMap, - State(auth_repo): State>, // auth_repo: AuthRepo, + State(auth_repo): State>, ) -> impl IntoResponse { - if let Some(token) = headers.get("X-Pesto-Token") { - todo!(); - return ( + match headers.get("X-Pesto-Token") { + Some(token) => ( StatusCode::OK, [(header::CONTENT_TYPE, "application/json")], - r#"{"message":"OK\}"#, - ); - } else { - return ( + r#"{"message":"OK}"#, + ), + None => ( StatusCode::UNAUTHORIZED, [(header::CONTENT_TYPE, "application/json")], r#"{"message":"Token must be supplied"}"#, - ); + ), } } @@ -54,12 +50,28 @@ struct TokenValue { #[derive(Clone)] struct AuthRepo { - pub redis_client: Arc, + pub redis_client: Command, } impl AuthRepo { - fn new(redis_client: Arc) -> Self { - return AuthRepo { redis_client }; + fn new(redis_client: Command) -> Self { + Self { redis_client } + } + + fn acquire_token_value(&self, token: &str) -> Result { + todo!() + } + + fn acquire_counter_limit(&self, token_value: &TokenValue) -> Result { + todo!() + } + + fn increment_monthly_counter( + &self, + token_value: &TokenValue, + counter_limit: i64, + ) -> Result<(), AuthError> { + todo!() } } @@ -67,12 +79,11 @@ impl AuthRepo { async fn main() -> Result<(), Box> { let redis_client = Client::open("redis://@localhost:6739")?; let redis_async_connection = redis_client.get_multiplexed_async_connection().await?; - let rc_client = Arc::new(redis_async_connection); - let auth_repo = AuthRepo::new(rc_client); + let auth_repo = AuthRepo::new(redis_async_connection); let app = Router::new() .route("/healthz", get(healthcheck)) - .route("/", any(authenticate::)) + .route("/", any(authenticate)) .with_state(auth_repo); let listener = TcpListener::bind("0.0.0.0:3000").await?;