Skip to main content

max / makenotwork

2.6 KB · 89 lines History Blame Raw
1 //! Database read queries, projection structs and SQL.
2
3 use chrono::{DateTime, Utc};
4 use mt_core::types::{
5 BanType, ChatPolicy, CommunityRole, CommunityState, ModAction, SortColumn, SortOrder,
6 };
7 use sqlx::PgPool;
8 use uuid::Uuid;
9
10 /// A community resource loaded by id but not yet proven to belong to a caller's
11 /// community scope (the ultra-fuzz C1 invariant).
12 ///
13 /// The inner value is private, so [`Unscoped::in_community`] is the only way to
14 /// reach it and the community check cannot be skipped. Why the invariant exists
15 /// and what it replaced is in `src/routes/scope.rs`, which is the canonical
16 /// account; do not restate it here.
17 pub struct Unscoped<T> {
18 inner: T,
19 community_id: Uuid,
20 }
21
22 impl<T> Unscoped<T> {
23 /// Wrap a freshly-loaded resource together with the community it lives in.
24 pub fn new(inner: T, community_id: Uuid) -> Self {
25 Self {
26 inner,
27 community_id,
28 }
29 }
30
31 /// Yield the resource only if it belongs to `expected_community`; `None`
32 /// otherwise (the id names a resource in a different community, which to a
33 /// scoped URL is indistinguishable from "not found").
34 pub fn in_community(self, expected_community: Uuid) -> Option<T> {
35 (self.community_id == expected_community).then_some(self.inner)
36 }
37
38 /// Unwrap without a community check. This is the deliberate escape hatch for
39 /// callers that have no URL slug to scope against, the trusted internal
40 /// server-to-server API. It is on `clippy.toml`'s `disallowed-methods` so a
41 /// normal handler cannot reach for it by accident; the one sanctioned call
42 /// site (`src/routes/internal.rs`) carries a local `#[allow]`. Anything
43 /// reached via `/p/{slug}/…` must use [`Unscoped::in_community`] instead.
44 pub fn into_inner_unchecked(self) -> T {
45 self.inner
46 }
47 }
48
49 mod admin;
50 mod category;
51 mod chat;
52 mod community;
53 mod endorsement;
54 mod footnote;
55 mod image;
56 mod link_preview;
57 mod member;
58 mod mention;
59 mod moderation;
60 mod post;
61 mod search;
62 mod tag;
63 mod thread;
64 mod tracked_thread;
65 mod user;
66
67 pub use admin::*;
68 pub use category::*;
69 pub use chat::*;
70 pub use community::*;
71 pub use endorsement::*;
72 pub use footnote::*;
73 pub use image::*;
74 pub use link_preview::*;
75 pub use member::*;
76 pub use mention::*;
77 pub use moderation::*;
78 pub use post::*;
79 pub use search::*;
80 pub use tag::*;
81 pub use thread::*;
82 pub use tracked_thread::*;
83 pub use user::*;
84
85 // Explicit re-exports so clippy.toml disallowed-methods paths resolve
86 // (path-based lints do not follow glob re-exports).
87 pub use post::get_post_for_edit;
88 pub use thread::get_thread_with_breadcrumb;
89