Make scanning an admin setting, and document SSO
The per-feed schedule picker is gone and global Settings is admin-only, enforced in the handlers with 403s rather than just hidden: polling costs bandwidth and affects everyone reading the feed, so it belongs to the operator. Folders, keywords and per-feed limits stay open to anyone. docs/sso.md covers Cloudflare Zero Trust and Authentik end to end, including why trusted_proxies names the proxy and not a subnet. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AdXho5tTkjFLeUXKbEjKBh
This commit is contained in:
17
src/web.rs
17
src/web.rs
@@ -432,6 +432,13 @@ impl ApiError {
|
||||
status: StatusCode::BAD_REQUEST,
|
||||
}
|
||||
}
|
||||
|
||||
fn forbidden(msg: impl Into<String>) -> Self {
|
||||
Self {
|
||||
error: anyhow::Error::msg(msg.into()),
|
||||
status: StatusCode::FORBIDDEN,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoResponse for ApiError {
|
||||
@@ -616,8 +623,14 @@ where
|
||||
async fn patch_feed(
|
||||
State(state): State<WebState>,
|
||||
Path(id): Path<String>,
|
||||
user: crate::db::User,
|
||||
Json(body): Json<FeedPatch>,
|
||||
) -> Result<StatusCode, ApiError> {
|
||||
// How often a feed is polled is the operator's call: it costs bandwidth, it is what
|
||||
// publishers notice, and one impatient setting affects everyone reading the feed.
|
||||
if body.schedule.is_some() && !user.is_admin {
|
||||
return Err(ApiError::forbidden("only an admin sets when feeds are scanned"));
|
||||
}
|
||||
let mut cfg = (*state.ctx.cfg()).clone();
|
||||
|
||||
// Derived feeds have no config entry. Editing one is the moment it earns a real
|
||||
@@ -990,8 +1003,12 @@ struct SettingsPatch {
|
||||
|
||||
async fn patch_settings(
|
||||
State(state): State<WebState>,
|
||||
user: crate::db::User,
|
||||
Json(body): Json<SettingsPatch>,
|
||||
) -> Result<StatusCode, ApiError> {
|
||||
if !user.is_admin {
|
||||
return Err(ApiError::forbidden("only an admin changes these settings"));
|
||||
}
|
||||
let mut cfg = (*state.ctx.cfg()).clone();
|
||||
if let Some(sched) = body.schedule {
|
||||
let sched = sched.trim().to_owned();
|
||||
|
||||
Reference in New Issue
Block a user