perf(auth): cached image-free user-flags lookup for per-request guards
Every WebDAV / CalDAV / CardDAV request paid one full-row user fetch in
require_internal_user_layer just to read `is_external` (and the NC Basic
Auth middleware repeated it right after its own cache hit). That SELECT
includes the `image` column — a data URI of up to 512 KiB — so a sync
client issuing hundreds of PROPFINDs per minute dragged hundreds of MB
of avatar bytes out of Postgres to evaluate a boolean.
- New `UserFlags { role, is_external, active }` + a repo query selecting
only those three columns (inherent method, mirroring `update_image`).
- `AuthApplicationService::get_user_flags`: moka cache, 30 s TTL,
10k capacity. `change_user_role` / `set_user_active` invalidate
eagerly, so admin changes still apply immediately; anything else is
visible within the TTL — preserving the documented "no token rotation
needed" semantics at a per-request cost of zero DB round-trips when
warm.
- `require_internal_user`, `require_admin_user` and the NC Basic Auth
external check now go through the flags lookup.
https://claude.ai/code/session_01Dp3oWon5GBMVn4j3QXZdgx
This commit is contained in:
@@ -20,6 +20,18 @@ impl std::fmt::Display for UserRole {
|
||||
}
|
||||
}
|
||||
|
||||
/// Authorization-relevant account flags, fetched without the heavyweight
|
||||
/// profile columns. The full user row drags `image` along — a data URI of
|
||||
/// up to 512 KiB — which per-request guards (`require_internal_user`,
|
||||
/// `require_admin_user`, the NC Basic Auth external check) must never pay
|
||||
/// for just to read a boolean or a role.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct UserFlags {
|
||||
pub role: UserRole,
|
||||
pub is_external: bool,
|
||||
pub active: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct User {
|
||||
id: Uuid,
|
||||
|
||||
Reference in New Issue
Block a user