Refactor CMS and IAM modules: restructure presentation and command layers

- Removed HTTP adapter module from CMS infrastructure.
- Updated CMS infrastructure module to exclude HTTP.
- Introduced presentation layer in CMS with DTOs and handlers for REST API.
- Added command types for CMS domain operations to encapsulate input data.
- Created typed error handling for CMS presentation layer.
- Implemented handlers for CMS REST API endpoints.
- Removed HTTP DTOs and handlers from IAM infrastructure.
- Introduced command types for IAM domain operations.
- Created presentation layer in IAM with DTOs and handlers for OAuth flow.
- Implemented typed error handling for IAM presentation layer.
This commit is contained in:
asepharyana
2026-07-20 06:53:01 +07:00
parent e9a8e93c83
commit 714b4617dd
22 changed files with 465 additions and 175 deletions
+16 -12
View File
@@ -122,7 +122,7 @@ pub struct SessionAuthMiddleware<S> {
/// Extract and validate `X-Session-Id` from request headers.
///
/// Flow: read header -> validate non-empty -> return ID or a 401 error response.
fn extract_session_id<ReqBody>(req: &Request<ReqBody>) -> Result<String, Response> {
fn extract_session_id<ReqBody>(req: &Request<ReqBody>) -> Result<String, Box<Response>> {
let session_id = req
.headers()
.get("X-Session-Id") // custom header carrying the session identifier
@@ -131,7 +131,9 @@ fn extract_session_id<ReqBody>(req: &Request<ReqBody>) -> Result<String, Respons
match session_id {
Some(id) if !id.is_empty() => Ok(id),
_ => Err((StatusCode::UNAUTHORIZED, "missing X-Session-Id header").into_response()),
_ => Err(Box::new(
(StatusCode::UNAUTHORIZED, "missing X-Session-Id header").into_response(),
)),
}
}
@@ -142,7 +144,7 @@ fn validate_and_build_identity<ReqBody>(
session_id: &str,
store: &Store,
req: &Request<ReqBody>,
) -> Result<SessionIdentity, Response> {
) -> Result<SessionIdentity, Box<Response>> {
match validate_session(session_id, store) {
Ok(_session) => {
let user_agent = req
@@ -153,11 +155,13 @@ fn validate_and_build_identity<ReqBody>(
.to_string();
Ok(SessionIdentity::new(session_id.to_string(), user_agent))
}
Err(e) => Err((
StatusCode::UNAUTHORIZED,
format!("session validation failed: {e}"),
)
.into_response()),
Err(e) => Err(Box::new(
(
StatusCode::UNAUTHORIZED,
format!("session validation failed: {e}"),
)
.into_response(),
)),
}
}
@@ -181,14 +185,14 @@ where
let session_id = match extract_session_id(&req) {
Ok(id) => id,
Err(resp) => return Box::pin(async move { Ok(resp) }),
Err(resp) => return Box::pin(async move { Ok(*resp) }),
};
match validate_and_build_identity(&session_id, &store, &req) {
Ok(identity) => {
req.extensions_mut().insert(identity);
}
Err(resp) => return Box::pin(async move { Ok(resp) }),
Err(resp) => return Box::pin(async move { Ok(*resp) }),
};
let fut = self.inner.call(req);
@@ -212,12 +216,12 @@ pub async fn require_session(
) -> Response {
let session_id = match extract_session_id(&req) {
Ok(id) => id,
Err(resp) => return resp,
Err(resp) => return *resp,
};
let identity = match validate_and_build_identity(&session_id, &store, &req) {
Ok(identity) => identity,
Err(resp) => return resp,
Err(resp) => return *resp,
};
req.extensions_mut().insert(identity);
next.run(req).await