fix(dashboard/simulator): invalidate effective-permissions on policy/budget mutations (#3228 follow-up)#3237
Merged
Merged
Conversation
…budget mutations (#3228 follow-up) The permission simulator's `useEffectivePermissions` hook caches with `staleTime: 30_000` and no mutation in the dashboard invalidated `authzKeys.effective(name)`. After an admin saved a policy, role, channel-binding, or budget edit, the simulator pane kept showing the pre-edit snapshot for up to 30s. Add invalidation of `authzKeys.effective(variables.name)` (or `authzKeys.all` for bulk import) to every mutation whose write feeds into `EffectivePermissions`: - useCreateUser (clears any cached 404 for the new name) - useUpdateUser (role + channel_bindings; both old & new name on rename) - useDeleteUser (removes the snapshot to avoid racing a 404) - useImportUsers (bulk; sweep authzKeys.all) - useUpdateUserPolicy (tool_policy / tool_categories / memory_access / channel_tool_rules) - useUpdateUserBudget / useDeleteUserBudget (budget) The 30s staleTime is intentional and unchanged — staleness is fine for background refetches; the bug was specifically that user-driven mutations weren't pushing the cache. `channel_role_mapping` was NOT added to `EffectivePermissions`. The struct is per-user; `channel_role_mapping` is a global kernel-config section that translates platform-native admin roles (Telegram supergroup admin, Discord guild admin, Slack workspace admin) to LibreFang roles for users WITHOUT an explicit `[users.x]` row. By the time we're simulating a registered user, the explicit channel_bindings path applies and the global mapping is irrelevant for that user. The two M4 outputs that ARE per-user (`channel_tool_rules` and `channel_bindings`) are already surfaced.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #3228 (RBAC effective-permissions snapshot).
Bug
useEffectivePermissions(crates/librefang-api/dashboard/src/lib/queries/authz.ts) caches withstaleTime: 30_000and no dashboard mutation invalidatedauthzKeys.effective(name). After an admin saved a policy / role / channel-binding / budget edit through the dashboard, the permission simulator pane kept showing the pre-edit snapshot for up to 30 s.The
staleTimeitself is fine — staleness is the right default for a read-only diagnostic page. The bug was specifically the missing invalidation on user-driven writes.Invalidation chain added
Every mutation whose write feeds into
EffectivePermissions(inlibrefang-kernel/src/auth.rs) now invalidates the simulator cache:EffectivePermissionsuseCreateUserauthzKeys.effective(name)useUpdateUserrole,channel_bindingsauthzKeys.effective(originalName)+ new name on renameuseDeleteUserremoveQueries(authzKeys.effective(name))(avoids refetch racing the 404)useImportUsersauthzKeys.all(bulk sweep)useUpdateUserPolicytool_policy,tool_categories,memory_access,channel_tool_rulesauthzKeys.effective(name)useUpdateUserBudget/useDeleteUserBudgetbudgetauthzKeys.effective(name)channel_role_mappingdecision — NOT addedThe reviewer's claim that
EffectivePermissionsis missing M4'schannel_role_mappingwas re-verified and is incorrect. The two M4 outputs that ARE per-user —channel_tool_rulesandchannel_bindings— are already present in the struct (auth.rs:194,198) and rendered in the simulator (PermissionSimulatorPage.tsx:203-204).channel_role_mappingitself is global kernel config, not per-user data. It translates platform-native admin roles (Telegram supergroup admin, Discord guild admin, Slack workspace admin) into LibreFang roles for inbound senders without an explicit[users.x]row. By the time we're simulating a registered user, the explicitchannel_bindingspath applies and the global mapping is irrelevant for that user — adding it to a per-user snapshot would be misleading because the value doesn't depend on the selected user.If a future need arises to surface global RBAC config, it belongs on a separate "RBAC overview" page, not on the per-user simulator.
Verification
pnpm typecheckproduces only pre-existing errors onclient.ts/UserBudgetPage.tsxthat also reproduce on a cleanorigin/maincheckout (unrelated to this fix).cargochecks were skipped.staleTime: 30_000is unchanged — only invalidation handlers were added.Test plan
useImportUsers(bulk sweep) anduseDeleteUser(snapshot disappears immediately).