diff --git a/Ecdar-ProtoBuf b/Ecdar-ProtoBuf index 285004c..2f2fdd7 160000 --- a/Ecdar-ProtoBuf +++ b/Ecdar-ProtoBuf @@ -1 +1 @@ -Subproject commit 285004c6a2b310f82a1a6c045933246046499e98 +Subproject commit 2f2fdd79d6564c1233f2e92173098b1c4aece994 diff --git a/src/controllers/controller_impls/session_controller.rs b/src/controllers/controller_impls/session_controller.rs index 2a28d07..e007722 100644 --- a/src/controllers/controller_impls/session_controller.rs +++ b/src/controllers/controller_impls/session_controller.rs @@ -7,7 +7,7 @@ use crate::entities::{session, user}; use crate::services::service_collection::ServiceCollection; use async_trait::async_trait; use sea_orm::DbErr; -use tonic::{Request, Response, Status}; +use tonic::{Code, Request, Response, Status}; pub struct SessionController { contexts: ContextCollection, @@ -75,8 +75,23 @@ impl SessionController { #[async_trait] impl SessionControllerTrait for SessionController { - async fn delete_session(&self, _request: Request<()>) -> Result, Status> { - todo!() + /// Deletes the requester's session, found by their access token. + /// + /// Returns the response that is received from Reveaal. + async fn delete_session(&self, request: Request<()>) -> Result, Status> { + let access_token = request + .token_string() + .ok_or(Status::unauthenticated("No access token provided"))?; + + match self + .contexts + .session_context + .delete_by_token(TokenType::AccessToken, access_token) + .await + { + Ok(_) => Ok(Response::new(())), + Err(error) => Err(Status::new(Code::Internal, error.to_string())), + } } /// This method is used to get a new access and refresh token for a user. diff --git a/src/tests/controllers/session_controller.rs b/src/tests/controllers/session_controller.rs index 05245e6..8e56d57 100644 --- a/src/tests/controllers/session_controller.rs +++ b/src/tests/controllers/session_controller.rs @@ -1,3 +1,4 @@ +use mockall::predicate; use std::env; use std::str::FromStr; @@ -264,3 +265,73 @@ async fn get_auth_token_from_invalid_token_returns_err() { assert_eq!(response.unwrap_err().code(), Code::Unauthenticated); } + +#[tokio::test] +async fn delete_session_returns_ok() { + let mut mock_contexts = get_mock_contexts(); + let mock_services = get_mock_services(); + + mock_contexts + .session_context_mock + .expect_delete_by_token() + .with( + predicate::eq(TokenType::AccessToken), + predicate::eq("test_token".to_string()), + ) + .returning(move |_, _| { + Ok(session::Model { + id: 1, + refresh_token: Default::default(), + access_token: "test_token".to_string(), + updated_at: Default::default(), + user_id: Default::default(), + }) + }); + + let contexts = disguise_context_mocks(mock_contexts); + let services = disguise_service_mocks(mock_services); + let session_logic = SessionController::new(contexts, services); + + let mut request = Request::new(()); + request.metadata_mut().insert( + "authorization", + metadata::MetadataValue::from_str("Bearer test_token").unwrap(), + ); + + let res = session_logic.delete_session(request).await; + + assert!(res.is_ok()); +} + +#[tokio::test] +async fn delete_session_no_session_returns_err() { + let mut mock_contexts = get_mock_contexts(); + let mock_services = get_mock_services(); + + mock_contexts + .session_context_mock + .expect_delete_by_token() + .with( + predicate::eq(TokenType::AccessToken), + predicate::eq("test_token".to_string()), + ) + .returning(move |_, _| { + Err(DbErr::RecordNotFound( + "No session found with the provided access token".to_string(), + )) + }); + + let contexts = disguise_context_mocks(mock_contexts); + let services = disguise_service_mocks(mock_services); + let session_logic = SessionController::new(contexts, services); + + let mut request = Request::new(()); + request.metadata_mut().insert( + "authorization", + metadata::MetadataValue::from_str("Bearer test_token").unwrap(), + ); + + let res = session_logic.delete_session(request).await; + + assert_eq!(res.unwrap_err().code(), Code::Internal); +}