Refactor session ID handling and improve error management

- Introduced `SessionId` newtype for validated session identifiers, ensuring safety against path traversal attacks.
- Updated session repository methods to accept `SessionId` instead of raw strings, enhancing type safety.
- Removed redundant error handling in repository methods by leveraging the new `Error` type from `zesdex_utils`.
- Simplified atomic JSON write operations by eliminating unnecessary error conversions.
- Enhanced integer casting with a new `CastOr` trait for safer narrowing conversions.
- Removed deprecated error handling code and consolidated error types across the codebase.
- Updated HTTP handlers to utilize the new session ID validation, improving overall robustness.
This commit is contained in:
asepharyana
2026-07-20 06:39:30 +07:00
parent ab1a54b72e
commit e9a8e93c83
39 changed files with 413 additions and 366 deletions
@@ -15,8 +15,9 @@
//!
//! - `SessionServiceImpl<R, L>` — service over two generic repositories
//! - `new` / `create_session` / `list_all` / `archive_session` — lifecycle ops
use std::convert::TryInto;
use std::path::PathBuf;
use zesdex_entities::domain::auth::SessionId;
use zesdex_utils::CastOr;
use tracing;
use uuid::Uuid;
@@ -49,13 +50,14 @@ impl<R: SessionRepository, L: SessionLockRepository> SessionServiceImpl<R, L> {
impl<R: SessionRepository, L: SessionLockRepository> SessionService for SessionServiceImpl<R, L> {
fn create_session(&self, title: &str) -> Result<Session, ServiceError> {
let id = Uuid::new_v4().to_string();
let id = SessionId::new(&Uuid::new_v4().to_string())
.expect("UUID is always a valid session id");
let title_owned = if title.is_empty() {
"New Session".to_string()
} else {
title.to_string()
};
let session = Session::new(id, title_owned);
let session = Session::new(id.into_string(), title_owned);
tracing::debug!(session_id = %session.id, title = %session.title, "creating new session");
self.session_repo
.save_session(&self.base_dir, &session)?; // RepositoryError → ServiceError via From
@@ -69,16 +71,16 @@ impl<R: SessionRepository, L: SessionLockRepository> SessionService for SessionS
.map_err(ServiceError::Repository)
}
fn archive_session(&self, id: &str) -> Result<(), ServiceError> {
fn archive_session(&self, id: SessionId) -> Result<(), ServiceError> {
tracing::debug!(session_id = %id, "archiving session");
let mut session = self.session_repo
.load_session(&self.base_dir, id)?; // RepositoryError → ServiceError
.load_session(&self.base_dir, &id)?; // RepositoryError → ServiceError
session.archived = true;
let millis = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap_or_default()
.as_millis();
session.updated_at = millis.try_into().unwrap_or(i64::MAX);
session.updated_at = millis.cast_or(i64::MAX);
self.session_repo
.save_session(&self.base_dir, &session)?; // RepositoryError → ServiceError
Ok(())