sfirke opened a new pull request, #45591:
URL: https://github.com/apache/superset/pull/45591

   ### SUMMARY
   
   The user pickers in the Roles and Groups modals, and the user filter on the 
Roles, Groups and Action Log list pages, could not find a user by typing. 
`fetchUserOptions` sent the search term under a rison `filter` key, which the 
`/api/v1/security/users/` list endpoint ignores, so every search returned the 
first page of users in username order. Any user outside that page was 
unreachable.
   
   This PR fixes that in three parts:
   
   - **Backend:** registers a `UserSearchFilter` (operator `user_all_text`) on 
`SupersetUserApi` that matches the search term case-insensitively against 
username, first name, last name, full name and email. The full name is matched 
as a whole so "Jane Sm" finds "Jane Smith", and email is included because 
single sign-on usernames are often opaque identifiers. LIKE metacharacters in 
the term are escaped with the same `_escape_like` helper the DAO LIKE operators 
use, so `%` and `_` match literally instead of turning the search into "match 
everyone". A `None` value matches no rows, mirroring SQL `LIKE NULL` and the 
DAO operators. Surrounding whitespace is stripped.
   - **Frontend request:** `fetchUserOptions` sends the term as a `filters` 
entry with the `user_all_text` operator, trims it first (the ListView filter 
path passes the raw input, so a whitespace-only search no longer reaches the 
server), and types the response instead of mapping over `any`.
   - **Frontend pickers:** user options now show the email under the display 
name, the way the subject-based owners and editors pickers do, using the shared 
`SubjectSelectLabel`. Without this, `AsyncSelect`'s client-side re-filter 
compared the search term against the display name and hid every server-side 
match on email or username, and a user surfacing for a term that doesn't appear 
in their name would have looked like a bug. Both modal pickers now re-filter on 
the option's plain-text name and email props, so email matches are visible and 
self-explanatory.
   
   Design notes:
   - The filter is registered under the `username` column, which is what the 
existing pickers already order by. Flask-AppBuilder only attaches a custom 
search filter when its column is in `search_columns`, so the unit test resolves 
a `user_all_text` filter through FAB's `Filters` wiring rather than asserting 
the class attribute, and will fail if `username` is ever removed from 
`search_columns`.
   - A blank term sent directly to the API matches every user, the same as 
FAB's built-in `ct` operator. The frontend omits the filter entirely when the 
trimmed term is empty.
   - Username matches are not explained in the option. A user found by typing 
part of an opaque SSO username shows their name and email, not the username. 
This is deliberate: showing a third line clutters the picker for a case that 
mostly serves admins pasting an identifier, and a user with no first or last 
name already shows their username as the label.
   - Preselected users in the edit modals are built with the same option helper 
so they render and filter consistently with search results. ListView's 
cold-load tooltip label falls back to an option's `title` before its id, since 
the Users filter options on the list pages now carry a React label.
   
   ### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
   
   Before: typing a name in the role modal's user picker returns the same first 
page of users regardless of input. Typing an email returns nothing.
   
   After: typing "Jane", "Smith", "jane@" or "Jane Sm" narrows the picker to 
matching users, and each option shows the email beneath the name.
   
   ### TESTING INSTRUCTIONS
   
   1. Create more users than one picker page (100), or pick a user whose 
username sorts after the first 100 alphabetically.
   2. Open Settings → List Roles, edit a role, and type part of that user's 
first name, last name or email in the Users picker. The user should appear, 
with their email shown under their name.
   3. Type part of their username. The user should appear even though the 
username is not displayed.
   4. Repeat in Settings → List Groups and in the Users filter on the Roles, 
Groups and Action Log list pages.
   5. Type a lone `%` or `_` in the picker. The list should narrow to users 
whose name or email contains that literal character, not show everyone.
   6. Type only spaces. The picker should show the unfiltered first page, not 
an empty or oddly filtered list.
   7. Edit a role or group that already has users. The preselected users should 
render as before, and searching should still work alongside them.
   
   Automated coverage:
   - `pytest tests/unit_tests/security/user_search_filter_test.py` covers 
matching across each column, wildcard escaping, whitespace, blank and `None` 
values, and the FAB filter wiring.
   - `npm run test -- src/features/groups` covers the request shape, trimming, 
the blank-term cases, the option builder, and a group modal test that searches 
by email and expects the user to be listed with their email. That test fails if 
the picker's `optionFilterProps` is removed.
   - `npm run test -- src/features/roles/RoleFormItems.test.tsx` has the same 
email-search regression test for the role modal's Users picker.
   
   ### ADDITIONAL INFORMATION
   <!--- Check any relevant boxes with "x" -->
   <!--- HINT: Include "Fixes #nnn" if you are fixing an existing issue -->
   - [ ] Has associated issue:
   - [ ] Required feature flags:
   - [x] Changes UI
   - [ ] Includes DB Migration (follow approval process in 
[SIP-59](https://github.com/apache/superset/issues/13351))
     - [ ] Migration is atomic, supports rollback & is backwards-compatible
     - [ ] Confirm DB migration upgrade and downgrade tested
     - [ ] Runtime estimates and downtime expectations provided
   - [x] Introduces new feature or API
   - [ ] Removes existing feature or API
   
   ---
   🤖 _Drafted by Claude Code, reviewed and approved by @sfirke._
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to