@winh I think we can, as long as we keep checking if the current_user (who may be nil) can :read_user, and as long as we verify that we're not exposing any sensitive attributes.
I took a look at the code involved, and it seems to me like an API authentication change is unnecessary (please correct me if I'm wrong!):
When the author autocomplete filter is selected, the page makes a request to /autocomplete/users.json and fetches a list of users. The attributes received here are id, name, username, and avatar_url.
When the user selects an author, the FilteredSearchVisualTokens class makes a request to /api/v4/users.json, passing in the username of the selected user. The server sends back the user record, with a lot more attributes than we received in the previous step.
However, none of these extra attributes are being used. FilteredSearchVisualTokens simply uses the retrieved data to update the user's avatar_url and name. Since we've already received this data in Step 1, I don't see why we need to re-fetch it in Step 2.
EDIT: In conclusion: instead of changing API auth, we could simply save the returned list of users in UsersCache during Step 1, and read from it during Step 2. Alternatively, UsersCache could use the /autocomplete/users.json API rather than the /api/v4/users API.
The hideCurrentUser method in the DropdownUser class is missing an if check:
You are right, we need to change that. I have opened !12415 (merged) so we don't forget but will not be able to work on it now.
save the returned list of users in UsersCache during Step 1, and read from it during Step 2
This covers many cases but not all of them. For example after submitting a search, the dropdown is not opened, so no autocompletion data is loaded.
I originally planned two optimizations there:
fill UsersCache with whatever data we get from autocomplete as you suggested
after submitting a search, fetch all users at once (currently, there can be at most 2)
Unfortunately, I didn't have enough time to work on that for %9.3.
Alternatively, UsersCache could use the /autocomplete/users.json API rather than the /api/v4/users API.
Storing user entities in UsersCache seemed natural to me. We could make it an AutocompleteUsersCache to make clear that it does not contain complete user entities.
@winh: I see what you mean! Looks like /autocomplete/users.json is unsuitable here, since we need to lookup a specific user, not "fetch all users with this string in their name/username". So it looks like our options then are:
Modify /autocomplete/users.json to support username-based search
Open up /autocomplete/users/id.json and search by user ID rather than username.
1. Modify /autocomplete/users.json to support username-based search
My guess is, this would be the easiest from backend perspective but it would also lead to two endpoints basically delivering the same data. We could have this as a quick solution and then merge /autocomplete/users.json into /api/v4/users.json in the long run. I currently don't see why /api/v4/users.json?search=term&per_page=20 shouldn't entirely replace the autocomplete endpoint.
2. Open up /autocomplete/users/id.json and search by user ID rather than username.
We don't have the user ID when typing into the search bar. So we would need to make a backend request for getting the user ID from username first. This doesn't seem very elegant to me. 😟
3. Open up /api/v4/users.json
This one would be the nicest solution both—for frontend and for API consumers. After I finished my current regression I can try to do the necessary changes for this myself and then assign to you for review @timothyandrew if that helps.
@winh: Sure, (edit: using /api/v4/users.json) sounds good to me.
After I finished my current regression I can try to do the necessary changes for this myself and then assign to you for review @timothyandrew if that helps.
Sure! 👍 I can also try implementing it sometime tomorrow, if you haven't got to it by then.
@winh: I just had a thought regarding point number 2 above (using the /autocomplete/<user_id>.json endpoint:
We don't have the user ID when typing into the search bar. So we would need to make a backend request for getting the user ID from username first. This doesn't seem very elegant to me. 😟
How much effort would it take on the frontend to have the user ID along with the username in the search bar? I assume that since we're fetching it in the initial autocomplete step, so we have it then. On page reload we could have it rendered server-side onto the DOM. What do you think?
In any case, I've started implementing a fix to make /api/v4/users.json publicly-accessible. I'll tag you on the MR once it's ready.
How much effort would it take on the frontend to have the user ID along with the username in the search bar?
@timothyandrew In case the user appears in the dropdown, the effort is low (and even lower after #32422 (moved)). We need to store the username along with the token anyway. So instead we could store the ID.
For the case where we know the user from the dropdown already, we could also cache display name and avatar URL. Then we don't even need the user ID to make another Ajax call. I have opened an issue to reflect that: #34293 (moved).
On page reload we could have it rendered server-side onto the DOM.
That means every time we want to adjust the rendering of the tokens, we would have to touch the Ruby and JavaScript side. I can almost guarantee that this will be forgotten in the future. 😉