feat: add virtual key and user identity filters to OAuth2 grants sidebar - #5969
Conversation
|
|
📝 WalkthroughSummary by CodeRabbit
WalkthroughOAuth grants now support virtual-key and user-ID filters. The UI synchronizes selections with URL parameters, the API and HTTP handler forward them, and the config store applies mode-scoped SQL filtering. ChangesOAuth grant identity filters
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant OAuthGrantsFilterSidebar
participant OAuthGrantsPage
participant oauth2SessionsApi
participant listSessions
participant ListOAuth2Sessions
OAuthGrantsFilterSidebar->>OAuthGrantsPage: select virtual_key_id or user_id
OAuthGrantsPage->>oauth2SessionsApi: request selected filters
oauth2SessionsApi->>listSessions: send serialized query parameters
listSessions->>ListOAuth2Sessions: forward parsed identity filters
ListOAuth2Sessions-->>OAuthGrantsPage: return filtered OAuth2 sessions
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Merge activity
|
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
transports/bifrost-http/handlers/mcpoauth2sessions.go (1)
80-81: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd table-driven coverage for identity-filter semantics.
Cover virtual-key-only, user-only, both groups with OR semantics, and identity filters combined with
bf_mode. Confirm that each identity filter matches only its required mode and does not bypass existing filters.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@transports/bifrost-http/handlers/mcpoauth2sessions.go` around lines 80 - 81, In transports/bifrost-http/handlers/mcpoauth2sessions.go:80-81, add table-driven coverage for virtual-key-only, user-only, combined identity filters with OR semantics, and identity filters combined with bf_mode; verify each filter matches only its required mode and preserves existing filters. In framework/configstore/rdb.go:8637-8652, cover the corresponding query/filter behavior; no production change is requested unless the tests expose incorrect identity-filter semantics.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@ui/app/workspace/oauth-grants/views/oauthGrantsFilterSidebar.tsx`:
- Around line 347-370: Update the filter sidebar rendering around the search
input and filtered items to show “No results” only when fetching is false.
Propagate query errors from both query sections into this component, distinguish
loading, error, and empty states, and render a retryable error state with the
existing query retry mechanism when a request fails.
- Around line 404-410: Ensure selected virtual keys and users remain rendered
when absent from the current result page by merging or resolving selected IDs
before building each filter’s items. Update the virtual-key filter at
ui/app/workspace/oauth-grants/views/oauthGrantsFilterSidebar.tsx lines 404-410
and the user filter at lines 457-463; both sites require the same selected-item
preservation behavior while retaining current search results.
---
Nitpick comments:
In `@transports/bifrost-http/handlers/mcpoauth2sessions.go`:
- Around line 80-81: In
transports/bifrost-http/handlers/mcpoauth2sessions.go:80-81, add table-driven
coverage for virtual-key-only, user-only, combined identity filters with OR
semantics, and identity filters combined with bf_mode; verify each filter
matches only its required mode and preserves existing filters. In
framework/configstore/rdb.go:8637-8652, cover the corresponding query/filter
behavior; no production change is requested unless the tests expose incorrect
identity-filter semantics.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 04de630c-f3c6-48e0-a8a0-969d0f711b93
📒 Files selected for processing (6)
framework/configstore/rdb.goframework/configstore/store.gotransports/bifrost-http/handlers/mcpoauth2sessions.goui/app/workspace/oauth-grants/page.tsxui/app/workspace/oauth-grants/views/oauthGrantsFilterSidebar.tsxui/lib/store/apis/oauth2SessionsApi.ts
| {fetching ? ( | ||
| <LoaderCircle className="text-muted-foreground pointer-events-none absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2 animate-spin" /> | ||
| ) : ( | ||
| <Search className="text-muted-foreground pointer-events-none absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2" /> | ||
| )} | ||
| <Input | ||
| ref={inputRef} | ||
| value={query} | ||
| onChange={(e) => setQuery(e.target.value)} | ||
| placeholder={placeholder} | ||
| className="h-8 border-0 pl-8 text-xs" | ||
| data-testid={testIdPrefix ? `${testIdPrefix}-search` : undefined} | ||
| /> | ||
| </div> | ||
| {filtered.map((item) => ( | ||
| <CheckboxFilterItem | ||
| key={item.key} | ||
| label={item.label} | ||
| checked={isSelected(item.key)} | ||
| onCheckedChange={() => onToggle(item.key)} | ||
| testId={testIdPrefix ? `${testIdPrefix}-checkbox-${item.key}` : undefined} | ||
| /> | ||
| ))} | ||
| {filtered.length === 0 && <div className="text-muted-foreground flex h-9 items-center px-3 text-xs">No results</div>} |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Separate loading, error, and empty states.
When a new search starts, filtered can be empty while fetching is true. The component then shows No results with a loading icon. A failed query also shows No results.
Render the empty state only after loading completes. Pass an error state from both query sections and show a retryable error state.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@ui/app/workspace/oauth-grants/views/oauthGrantsFilterSidebar.tsx` around
lines 347 - 370, Update the filter sidebar rendering around the search input and
filtered items to show “No results” only when fetching is false. Propagate query
errors from both query sections into this component, distinguish loading, error,
and empty states, and render a retryable error state with the existing query
retry mechanism when a request fails.
Sources: Coding guidelines, Path instructions
| items={virtualKeys.map((vk) => ({ key: vk.id, label: vk.name || vk.id }))} | ||
| isSelected={(key) => filters.virtual_key_id.includes(key)} | ||
| onToggle={toggle} | ||
| onSearch={setSearchQuery} | ||
| fetching={isFetching} | ||
| testIdPrefix="oauth-grants-filter-vk" | ||
| /> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
Keep selected entries visible after result pages change.
The current result page is the only source for rendered checkboxes. A selected ID disappears after another search or after reload when it is not in that page. The filter remains active, but the user cannot inspect or clear that ID individually.
ui/app/workspace/oauth-grants/views/oauthGrantsFilterSidebar.tsx#L404-L410: Render selected virtual keys separately from the current search page, or resolve selected IDs before rendering.ui/app/workspace/oauth-grants/views/oauthGrantsFilterSidebar.tsx#L457-L463: Render selected users separately from the current search page, or resolve selected IDs before rendering.
📍 Affects 1 file
ui/app/workspace/oauth-grants/views/oauthGrantsFilterSidebar.tsx#L404-L410(this comment)ui/app/workspace/oauth-grants/views/oauthGrantsFilterSidebar.tsx#L457-L463
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@ui/app/workspace/oauth-grants/views/oauthGrantsFilterSidebar.tsx` around
lines 404 - 410, Ensure selected virtual keys and users remain rendered when
absent from the current result page by merging or resolving selected IDs before
building each filter’s items. Update the virtual-key filter at
ui/app/workspace/oauth-grants/views/oauthGrantsFilterSidebar.tsx lines 404-410
and the user filter at lines 457-463; both sites require the same selected-item
preservation behavior while retaining current search results.
5e6b9eb to
38377ae
Compare

Summary
Adds Virtual Key and User identity filters to the OAuth Grants filter sidebar, allowing administrators to scope the grants list to rows belonging to specific virtual keys or users. Because
bf_subis a single generic subject column disambiguated only bybf_mode, each identity filter is paired with its corresponding mode guard (bf_mode = 'vk'orbf_mode = 'user') and the two groups are OR'd together server-side.Changes
VirtualKeyIDsandUserIDsfields toOAuth2SessionsQueryParamsand the corresponding SQL filter inListOAuth2Sessions, pairing each ID set with abf_modeguard sobf_sublookups are correctly scoped.virtual_key_idanduser_idas comma-separated query parameters, forwarding them to the store layer.VirtualKeyFilterSectionandUsersFilterSectioncomponents to the OAuth Grants filter sidebar, each using a searchable checkbox list with lazy server-side fetching (only fetches once the section is opened or already has a selection).getUserSearchQuery(). If no hook is registered, the section is omitted entirely rather than showing an unresolvable search box.virtual_key_idanduser_idarray params, included inhasActiveFiltersdetection and reset logic.virtual_key_idanduser_idarrays to keep the cache key stable regardless of selection order.Type of change
Affected areas
How to test
virtual_key_idanduser_idparams and that the reset button clears them.Screenshots/Recordings
Add before/after screenshots of the filter sidebar showing the new Virtual Key and Users sections.
Breaking changes
Related issues
Security considerations
Filters are applied server-side with parameterized
INclauses — no raw user input is interpolated into SQL. Theuser_idfilter is enterprise-only and gated behind the registered user search hook, so OSS deployments have no exposure to user directory data through this surface.Checklist
docs/contributing/README.mdand followed the guidelines