fix(manager-core): F-Q-003 promote authz::script_gate helper, migrate 7 service call sites

Replace nine open-coded `if cx.principal.is_some() {
authz::require(...).await.map_err(...) }` blocks with a single
`authz::script_gate(repo, cx, cap, forbidden_fn, backend_fn)` helper.

The helper enshrines the script-as-gate semantics (anonymous public-
HTTP scripts skip the check) and the AuthzDenied::{Denied,Repo}
mapping in one place — eliminating drift between services.

Call sites migrated:
- kv_service::check_read / check_write
- docs_service::check_read / check_write
- files_service::check_read / check_write
- pubsub_service::check_publish
- queue_service::enqueue

The pubsub_service::mint_subscriber_token path keeps the explicit
match because it does a separate `principal` early-bind for other
validation; converting it would obscure intent.

AUDIT.md anchor: F-Q-003. Depends on F-Q-004 (Backend variant) and
F-Q-005 (Repo-passthrough pattern).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-06-07 19:48:23 +02:00
parent 655c3ab97e
commit 04dc81115e
6 changed files with 95 additions and 85 deletions

View File

@@ -58,19 +58,14 @@ impl QueueService for QueueServiceImpl {
// Script-as-gate authz: anonymous public-HTTP scripts skip the
// check (cx.principal is None); authenticated callers must hold
// AppQueueEnqueue.
if let Some(principal) = cx.principal.as_ref() {
match authz::require(
&*self.authz,
principal,
Capability::AppQueueEnqueue(cx.app_id),
)
.await
{
Ok(()) => {}
Err(authz::AuthzDenied::Denied) => return Err(QueueError::Forbidden),
Err(authz::AuthzDenied::Repo(e)) => return Err(QueueError::Backend(e.to_string())),
}
}
authz::script_gate(
&*self.authz,
cx,
Capability::AppQueueEnqueue(cx.app_id),
|| QueueError::Forbidden,
QueueError::Backend,
)
.await?;
let deliver_after = opts
.delay_ms