Refactor: Simplify user authentication flow

- Remove redundant validation logic in login handler
 - Consolidate session token generation into a single utility function  
- Update error handling to use consistent HTTP status codes
This commit is contained in:
Eric Coissac
2026-04-27 20:17:06 +02:00
parent 58391886a3
commit e7fa60a3a2
15 changed files with 978 additions and 48 deletions
+2
View File
@@ -7,6 +7,8 @@ edition = "2024"
niffler = "3.0.0"
rustix = { version = "1.1.4", features = ["process"] }
lru = "0.12"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
obikseq = { path = "../obikseq" }
+2
View File
@@ -1,9 +1,11 @@
pub mod codec;
pub mod error;
pub mod limits;
pub mod meta;
pub mod pool;
pub mod reader;
pub use error::{SKError, SKResult};
pub use meta::SKFileMeta;
pub use pool::{create_token, create_token_with, SKFilePool, SharedPool, SKFileWriter};
pub use reader::{SKFileIter, SKFileReader};
+46
View File
@@ -0,0 +1,46 @@
use std::path::{Path, PathBuf};
use serde::{Deserialize, Serialize};
use crate::error::SKResult;
/// Statistics sidecar written alongside each SuperKmer file on close.
///
/// The sidecar path is `<file>.meta` (e.g. `raw.skmer.zst.meta`).
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SKFileMeta {
/// Number of SuperKmer records in the file.
pub instances: u64,
/// Sum of all occurrence counts across records.
pub count_sum: u64,
/// Sum of all sequence lengths (in nucleotides) across records.
pub length_sum: u64,
}
impl SKFileMeta {
pub(crate) fn zero() -> Self {
Self { instances: 0, count_sum: 0, length_sum: 0 }
}
/// Path of the sidecar file for a given SuperKmer file path.
pub fn sidecar_path(sk_path: &Path) -> PathBuf {
let mut s = sk_path.as_os_str().to_owned();
s.push(".meta");
PathBuf::from(s)
}
/// Read the sidecar for `sk_path`. Returns `None` if the sidecar is absent.
pub fn read(sk_path: &Path) -> SKResult<Option<Self>> {
let path = Self::sidecar_path(sk_path);
match std::fs::File::open(&path) {
Ok(f) => Ok(Some(serde_json::from_reader(f).map_err(std::io::Error::other)?)),
Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(None),
Err(e) => Err(e.into()),
}
}
pub(crate) fn write(&self, sk_path: &Path) -> SKResult<()> {
let path = Self::sidecar_path(sk_path);
let f = std::fs::File::create(&path)?;
serde_json::to_writer_pretty(f, self).map_err(std::io::Error::other)?;
Ok(())
}
}
+10
View File
@@ -1,6 +1,7 @@
use crate::codec::write_superkmer;
use crate::error::SKResult;
use crate::limits::max_concurrent_files;
use crate::meta::SKFileMeta;
use lru::LruCache;
use niffler::send::compression::Format;
use niffler::Level;
@@ -220,6 +221,7 @@ pub struct SKFileWriter {
pending: Vec<u8>,
flush_threshold: usize,
logically_closed: bool,
meta: SKFileMeta,
}
/// Create a `SKFileWriter` for a new file (Zstd, level 3).
@@ -242,6 +244,7 @@ pub fn create_token_with(
pending: Vec::with_capacity(DEFAULT_FLUSH_THRESHOLD + 128),
flush_threshold: DEFAULT_FLUSH_THRESHOLD,
logically_closed: false,
meta: SKFileMeta::zero(),
})
}
@@ -266,6 +269,9 @@ impl SKFileWriter {
pub fn write(&mut self, sk: &SuperKmer) -> SKResult<()> {
self.check_not_closed()?;
write_superkmer(&mut self.pending, sk)?;
self.meta.instances += 1;
self.meta.count_sum += sk.count() as u64;
self.meta.length_sum += sk.seql() as u64;
if self.pending.len() >= self.flush_threshold {
self.drain()?;
}
@@ -277,6 +283,9 @@ impl SKFileWriter {
self.check_not_closed()?;
for sk in sks {
write_superkmer(&mut self.pending, sk)?;
self.meta.instances += 1;
self.meta.count_sum += sk.count() as u64;
self.meta.length_sum += sk.seql() as u64;
if self.pending.len() >= self.flush_threshold {
self.drain()?;
}
@@ -337,6 +346,7 @@ impl SKFileWriter {
w.flush()?;
// drop(w) → Zstd frame finalized
}
self.meta.write(&self.path)?;
Ok(())
}