diff --git a/backend/Cargo.lock b/backend/Cargo.lock index b9586a0..7ffa59d 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -1664,6 +1664,7 @@ dependencies = [ "actix-multipart", "actix-web", "async-trait", + "auth", "futures", "log", "serde", diff --git a/backend/feature/auth/src/framework/web.rs b/backend/feature/auth/src/framework/web.rs index 8853d00..54b1487 100644 --- a/backend/feature/auth/src/framework/web.rs +++ b/backend/feature/auth/src/framework/web.rs @@ -1,3 +1,4 @@ +pub mod auth_middleware; pub mod auth_web_routes; mod constants; diff --git a/backend/feature/auth/src/framework/web/auth_middleware.rs b/backend/feature/auth/src/framework/web/auth_middleware.rs new file mode 100644 index 0000000..c1ff8d0 --- /dev/null +++ b/backend/feature/auth/src/framework/web/auth_middleware.rs @@ -0,0 +1,33 @@ +use std::future::{self, Ready}; + +use actix_session::SessionExt; +use actix_web::{Error, FromRequest, HttpRequest, dev::Payload, error::ErrorUnauthorized}; + +use crate::framework::web::constants::SESSION_KEY_USER_ID; + +pub struct UserId(i32); + +impl UserId { + pub fn get(&self) -> i32 { + self.0 + } +} + +impl FromRequest for UserId { + type Error = Error; + type Future = Ready>; + + fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future { + let user_id_result = req.get_session().get::(SESSION_KEY_USER_ID); + + let user_id = match user_id_result { + Ok(id) => id, + _ => return future::ready(Err(ErrorUnauthorized(""))), + }; + + match user_id { + Some(id) => future::ready(Ok(UserId(id))), + None => future::ready(Err(ErrorUnauthorized(""))), + } + } +} diff --git a/backend/feature/auth/src/framework/web/auth_web_routes.rs b/backend/feature/auth/src/framework/web/auth_web_routes.rs index f0ab70d..2e06a6a 100644 --- a/backend/feature/auth/src/framework/web/auth_web_routes.rs +++ b/backend/feature/auth/src/framework/web/auth_web_routes.rs @@ -6,8 +6,9 @@ use crate::{ auth_controller::AuthController, oidc_callback_query_dto::OidcCallbackQueryDto, }, application::error::auth_error::AuthError, - framework::web::constants::{ - SESSION_KEY_AUTH_NONCE, SESSION_KEY_AUTH_STATE, SESSION_KEY_USER_ID, + framework::web::{ + auth_middleware::UserId, + constants::{SESSION_KEY_AUTH_NONCE, SESSION_KEY_AUTH_STATE, SESSION_KEY_USER_ID}, }, }; @@ -18,6 +19,8 @@ pub fn configure_auth_routes(cfg: &mut web::ServiceConfig) { .route("/callback", web::get().to(oidc_callback_handler)) .route("/logout", web::get().to(logout_handler)), ); + + cfg.service(web::resource("/me").route(web::get().to(get_logged_in_user_handler))); } async fn oidc_login_handler( @@ -92,10 +95,12 @@ async fn oidc_callback_handler( } async fn logout_handler(session: Session) -> impl Responder { - session.remove(SESSION_KEY_AUTH_STATE); - session.remove(SESSION_KEY_AUTH_NONCE); - session.remove(SESSION_KEY_USER_ID); + session.clear(); HttpResponse::Found() .append_header((header::LOCATION, "/")) .finish() } + +async fn get_logged_in_user_handler(user_id: UserId) -> impl Responder { + HttpResponse::Ok().body(format!("Logged in user ID: {}", user_id.get())) +} diff --git a/backend/feature/image/Cargo.toml b/backend/feature/image/Cargo.toml index 0e6fc35..d7777cf 100644 --- a/backend/feature/image/Cargo.toml +++ b/backend/feature/image/Cargo.toml @@ -11,3 +11,5 @@ futures.workspace = true log.workspace = true serde.workspace = true sqlx.workspace = true + +auth.workspace = true diff --git a/backend/feature/image/src/framework/web/image_web_routes.rs b/backend/feature/image/src/framework/web/image_web_routes.rs index 4d0c206..e8ae4bb 100644 --- a/backend/feature/image/src/framework/web/image_web_routes.rs +++ b/backend/feature/image/src/framework/web/image_web_routes.rs @@ -1,5 +1,6 @@ use actix_multipart::Multipart; use actix_web::{HttpResponse, Responder, web}; +use auth::framework::web::auth_middleware::UserId; use futures::StreamExt; use crate::{ @@ -18,6 +19,7 @@ pub fn configure_image_routes(cfg: &mut web::ServiceConfig) { async fn upload_image_handler( image_controller: web::Data, mut payload: Multipart, + _: UserId, ) -> impl Responder { let mut image_request_dto: Option = None; diff --git a/backend/server/src/configuration/session.rs b/backend/server/src/configuration/session.rs index 5eb8ff1..ba4ec8f 100644 --- a/backend/server/src/configuration/session.rs +++ b/backend/server/src/configuration/session.rs @@ -20,7 +20,7 @@ impl SessionConfiguration { let session_key = Key::from(&session_key_bytes); let redis_url = - std::env::var("REDIS_URL").unwrap_or_else(|_| "redis://127.0.1:6379".to_string()); + std::env::var("REDIS_URL").unwrap_or_else(|_| "redis://127.0.0.1:6379".to_string()); Self { session_key, diff --git a/backend/server/src/main.rs b/backend/server/src/main.rs index 17fe620..adc4724 100644 --- a/backend/server/src/main.rs +++ b/backend/server/src/main.rs @@ -63,6 +63,7 @@ fn create_app( let container = Container::new(db_pool, http_client, configuration); App::new() + // The middlewares are executed in opposite order as registration. .wrap(session_middleware_builder.build()) .app_data(web::Data::from(container.auth_controller)) .app_data(web::Data::from(container.image_controller))