Skip to content

Security page refactor#2367

Draft
jvorcak wants to merge 46 commits intomasterfrom
security-page-refactor
Draft

Security page refactor#2367
jvorcak wants to merge 46 commits intomasterfrom
security-page-refactor

Conversation

@jvorcak
Copy link
Copy Markdown
Collaborator

@jvorcak jvorcak commented Apr 7, 2026

No description provided.

weeco and others added 30 commits April 7, 2026 10:45
Move ACL, role, and user management pages from separate directories
into a unified security/ component structure. Remove legacy page
components and replace with streamlined implementations.
… shared utilities

Rebuild security pages (users, roles, permissions) using Registry components,
add ACL create/remove dialogs with pattern type support (Literal/Prefixed/Any),
and display a "Prefixed" badge on ACL tables for non-literal pattern types.

Includes shared ACL utilities with sorting, flattening, and autocomplete helpers.
The /security/roles/$roleName/edit route was a backward-compat redirect
added on master that pointed to /security/roles/$roleName/update, which
no longer exists after the security page refactor.
- Add back navigation buttons to user and role detail pages
- Add page title header to user and role detail pages
- Restructure user detail page header to match mock layout
- Use Empty component consistently for all empty states
- Hide action buttons in section headers when list is empty
- Set proper page titles for browser tabs
Replace the monolithic principal type selector in SharedConfiguration
with a composable renderPrincipal render prop. Role pages provide a
simple "Role name" input without the type selector, while ACL pages
retain the full User/Group/RedpandaRole dropdown.

- Add PrincipalFieldProps type to acl.model.tsx
- Add renderPrincipal prop to CreateACL and SharedConfiguration
- Extract LockedPrincipalField shared component for read-only usage
- Role create page: editable role name input without type selector
- Role update page: disabled role name with error handling
- Add try-catch to updateRoleAclMutation with toast.error
Group principals were hidden behind the gbac enterprise feature flag.
Now they always appear when ACLs exist for them.

- Remove gbac filter gate from ACLs tab display
- Add Group principals to Permissions List with badge and correct links
- Rename UsersEntry to PrincipalEntry with principalType and isScramUser
- Hide "Delete User" options for Group principals in dropdown
- Type-narrow deleteACLsForPrincipal to 'User' | 'Group'
- Fix deduplication to check both name and principalType
- Add data-testid attributes to dropdown menu items
When navigating from user creation to ACL creation, the principal type
and name are now locked via ?lockPrincipal=true query parameter.

- Add lockPrincipal to route search schema as z.literal('true')
- Render LockedPrincipalField when lockPrincipal is active
- Update user-create.tsx link to include lockPrincipal=true
…incipal

- Role CRUD: create/delete role, verify no principal type selector
- Permissions List: delete dropdown with full user+ACL creation flow
- lockPrincipal: verify locked vs editable principal on ACL create
- Tests skip gracefully when features are unavailable in OSS env
Add explicit rule to always use bun run scripts from package.json,
never bunx or npx directly.
Wrap formatToastErrorMessageGRPC return value with toast.error() in
useCreateUserMutation, useUpdateUserMutationWithToast, useCreateRoleMutation,
useDeleteRoleMutation, and useUpdateRoleMembershipMutation. The function
returns a string but onError callbacks discarded the return value, causing
errors to be silently swallowed with no user feedback.
Replace the one-liner formatToastErrorMessageGRPC with a richer implementation
that uses ConnectError.findDetails() to extract well-known protobuf error
detail types: BadRequest, ErrorInfo, PreconditionFailure, QuotaFailure,
ResourceInfo, and LocalizedMessage. Uses rawMessage instead of message to
avoid redundant code prefix.
…egistry

Replace legacy REST api.createServiceAccount with useCreateUserMutation and
rolesApi.updateRoleMembership with useUpdateRoleMembershipMutation. Migrate
all @redpanda-data/ui Chakra components to Redpanda UI Registry equivalents
(Field, Input, Button, Select, Checkbox, Alert, Tooltip, SimpleMultiSelect,
CopyButton). Use useNavigate for Create ACLs navigation with search params.
…ncipal

Extract search param to sharedConfig resolution into a pure testable function
in principal-utils.ts. Remove the lockPrincipal query param from the route
schema and ACL create page — the principal field is now always editable when
pre-populated from user creation.
Add useEffect to sync sharedConfig state from propSharedConfig when it
changes after initial render. Fixes the ACL create form not being
pre-populated when route search params arrive after the first render cycle.
Add E2E test verifying the full user creation → Create ACLs navigation flow
including URL params and form pre-population. Migrate all E2E selectors to
use data-testid attributes where possible for reliability.
…route

Delete the monolithic acl-list.tsx (1114 lines) and its associated test
files, confirmation modals, and permission assignments component. These
are replaced by the new file-based security route structure with dedicated
pages for users, roles, ACLs, and permissions list.
Migrate security section from single $tab dynamic route to dedicated file-based
routes under /security/{users,roles,acls,permissions-list}. Update routeTree.gen.ts
with new route registrations and redirect /security/ to /security/acls.
Update breadcrumbs, navigation, and imports in ACL detail/update pages,
role pages, and user details to use the new file-based security route
structure with useSecurityBreadcrumbs hook.
Update imports and remove unused code in add-user-step.tsx and
create-user-confirmation-modal.tsx.
Add index routes for each security tab: users, roles, ACLs, and
permissions list. Add security.tsx layout route with tab navigation,
breadcrumbs, and feature-gated tab visibility.
Add security section components:
- Tab pages: users-tab, roles-tab, acls-tab, permissions-list-tab
- Hooks: useSecurityBreadcrumbs, usePrincipalList
- Shared: delete confirmation modals, user role tags, filter-by-name
- Tests for hooks, shared utilities, and tab components
Move generatePassword from user-create.tsx to a dedicated utility file.
Update imports in user-create.tsx, user-edit-modals.tsx, add-user-step.tsx,
and their test mocks.
Remove legacy files that are no longer imported after the security page
restructuring: models.ts, operation.tsx, principal-group-editor.tsx,
role-create.tsx, role-edit-page.tsx, role-form.tsx, and
create-user-confirmation-modal.tsx. Also remove dead
AclPrincipalGroupPermissionsTable from user-details.tsx.
Move all files from acls/new-acl/ up to acls/ and update all import paths.
Eliminates the unnecessary nesting now that the legacy acl-list.tsx is removed.
…factor

`new-acl/` subdirectory was removed in 296f51960; update the four test
files that still imported from the old path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…boarding components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…alias

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tory

Reorganize security-related components to mirror the route structure.
ACL pages, user pages, role pages, and shared utilities now live under
src/components/pages/security/{acls,users,roles,shared} instead of
the flat pages/acls/ and pages/roles/ directories.

- acls/: ACL create/detail/update pages and form components
- users/: user create/details, edit modals, and user card components
- roles/: role create/detail/update pages, matching users card
- shared/: acl-model (renamed from acl.model), principal-utils,
  operations-badge, acl-details, autocomplete-input
…doctor upgrade

The useEffect syncing propSharedConfig to state in CreateACL was lost
during the file move to security/acls/. Re-add it to fix the
acl-create-page test that expects principal input to update when search
params arrive after initial render.

Revert react-doctor from 0.0.33 to 0.0.29 because the newer version
pulls knip@6 which requires zod@4, conflicting with the project's zod@3
and causing ERR_PACKAGE_PATH_NOT_EXPORTED for zod/mini on CI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…iation

The FieldLabel and Input in user-create were siblings with no htmlFor/id
link, so Playwright's getByLabel('Username') could not find the input.
This fixes the enterprise E2E users.spec.ts timeout.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jvorcak jvorcak force-pushed the security-page-refactor branch from 54d213e to 1ed3630 Compare April 13, 2026 14:14
jvorcak added 10 commits April 13, 2026 20:37
The /security/roles/$roleName/edit route was deleted in the refactor
but the test file remained. Restore it as a redirect to /update.
useQueryStateWithCallback calls useLocation() internally, which requires
a RouterProvider. Tests only mocked Link and useNavigate, causing crashes.
Added useLocation stub returning empty searchStr to both security tab tests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants