Skip to main content

max / makenotwork

1.6 KB · 25 lines History Blame Raw
1 # The C1 resource-in-community invariant (ultra-fuzz CHRONIC) is sealed by the
2 # type system now, with one lint-guarded escape hatch.
3 #
4 # The raw by-id loaders (`get_thread_with_breadcrumb`, `get_post_for_edit`)
5 # return their resource wrapped in `mt_db::queries::Unscoped<T>`. The inner value
6 # is private; the safe way out is `Unscoped::in_community(expected)`, which yields
7 # it only when the resource's community matches the one the caller names.
8 # `routes::scope::CommunityScope::resolve` is the sole such site and it passes the
9 # community the URL slug resolved to, so a handler cannot serve a by-id community
10 # resource without proving it belongs to that community. That check needs no lint:
11 # it is enforced by the type.
12 #
13 # `Unscoped::into_inner_unchecked` unwraps with no community check, for callers
14 # that have no slug to scope against (the trusted internal server-to-server API).
15 # It is disallowed below so a `/p/{slug}/…` handler cannot reach for it by
16 # accident; the few sanctioned sites carry a local `#[allow]`.
17 #
18 # This replaced a deny-list that enumerated every raw loader by hand and failed
19 # open for any loader nobody remembered to add. The seal now fails closed: a new
20 # by-id loader that returns `Unscoped<T>` is bound automatically, and the only
21 # lint entry is on the single unchecked-unwrap primitive. See `src/routes/scope.rs`.
22 disallowed-methods = [
23 { path = "mt_db::queries::Unscoped::into_inner_unchecked", reason = "unwraps a community resource without the C1 scope check; a slug-scoped handler must use Unscoped::in_community via routes::scope::CommunityScope instead" },
24 ]
25