feat: server-authoritative case window via users.toml
The /api/oneliners time window is now read per-user from users.toml (window_hours, default 72h). Clients no longer carry a window: client.toml oneliner_window_hours, SyncConfig.window_hours, the ?hours=N query param, and the render_case_list cutoff filter are gone. ETag suffix keeps the effective hours so an admin edit to users.toml invalidates client caches on the next request. OnelinersResponse.window_hours stays in the wire format, but now exists solely to anchor client reconciliation.
This commit is contained in:
@@ -22,6 +22,9 @@ pub struct AuthenticatedUser {
|
||||
pub slug: String,
|
||||
pub role: String,
|
||||
pub data_dir: PathBuf,
|
||||
/// Copied from the matching entry in `users.toml` — the single
|
||||
/// source of truth for how many hours of history clients see.
|
||||
pub window_hours: u32,
|
||||
}
|
||||
|
||||
impl AuthenticatedUser {
|
||||
@@ -61,6 +64,7 @@ where
|
||||
slug: slug.clone(),
|
||||
role: user.role.clone(),
|
||||
data_dir,
|
||||
window_hours: user.window_hours,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -71,6 +75,9 @@ pub struct AuthenticatedWebUser {
|
||||
pub slug: String,
|
||||
pub role: String,
|
||||
pub data_dir: PathBuf,
|
||||
/// Mirrors [`AuthenticatedUser::window_hours`] so the same policy
|
||||
/// is available to web handlers without a second config lookup.
|
||||
pub window_hours: u32,
|
||||
}
|
||||
|
||||
impl AuthenticatedWebUser {
|
||||
@@ -124,10 +131,21 @@ where
|
||||
.ok_or_else(|| AppError::Redirect("/web/login".into()))?;
|
||||
|
||||
let data_dir = config.data_path.join(&session.slug);
|
||||
// Look up the TOML user record for the policy fields the session
|
||||
// does not carry. A missing record can only happen if users.toml
|
||||
// was edited while a session was still live; fall back to the
|
||||
// serde default so the request stays functional.
|
||||
let window_hours = config
|
||||
.users
|
||||
.iter()
|
||||
.find(|u| u.slug == session.slug)
|
||||
.map(|u| u.window_hours)
|
||||
.unwrap_or(72);
|
||||
Ok(Self {
|
||||
slug: session.slug.clone(),
|
||||
role: session.role.clone(),
|
||||
data_dir,
|
||||
window_hours,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user