Check read_admin_users permission when accessing admin-level user data

What does this MR do and why?

Fixes a bug (#594499) where non-admin users assigned a custom admin role with read_admin_users permission were not receiving admin-level user data from GET /api/v4/users and GET /api/v4/users/:id API endpoints.

References

Custom role email visibility differs between UI... (#594499).

Screenshots or screen recordings

Before

$ curl --header "PRIVATE-TOKEN: <secret>" --url "localhost:3000/api/v4/users"

[
  {
    "id": 2556,
    "username": "marfivetwo",
    "public_email": null,
    "name": "marfive two",
    "state": "active",
    "locked": false,
    "avatar_url": "https://www.gravatar.com/avatar/62549dfe18dc04bbe9c535b3213cbb1a371e4afddf052dd924609094015636f1?s=80&d=identicon",
    "web_url": "http://127.0.0.1:3000/marfivetwo"
  },
  ...
]

After

$ curl --header "PRIVATE-TOKEN: <secret>" --url "localhost:3000/api/v4/users"

[
  {
    "id": 2556,
    "username": "marfivetwo",
    "public_email": null,
    "name": "marfive two",
    "state": "active",
    "locked": false,
    "avatar_url": "https://www.gravatar.com/avatar/62549dfe18dc04bbe9c535b3213cbb1a371e4afddf052dd924609094015636f1?s=80&d=identicon",
    "web_url": "http://127.0.0.1:3000/marfivetwo",
    ... (other admin-only user fields)
    "email": "marfivetwo@example.com",
    ... (other admin-only user fields)
  },
  ...
]

How to set up and validate locally

  1. Login as an admin and disable Admin Mode in Settings > General > Sign-in restrictions by unchecking Admin Mode.
  2. Create a custom admin role with read_admin_users permission enabled by following Create a custom admin role.
  3. Assign the custom admin role to a non-admin user by following Assign a custom admin role.
  4. Login as the user with the custom role, and create a personal access token with read_api scope.
  5. Call GET /api/v4/users using the token:
    $ curl --header "PRIVATE-TOKEN: <token>" --url "https://<host>/api/v4/users"
  6. Verify the response uses the admin-level entity — each user object includes email, is_admin, created_at, two_factor_enabled, and other admin-only fields. Before the fix, these fields would be absent.
  7. Call GET /api/v4/users/:id for any user:
    $ curl --header "PRIVATE-TOKEN: <token>" --url "https://<host>/api/v4/users/<id>"
  8. Verify the response uses the admin-level entity — the user object includes email, is_admin, note, namespace, and other admin-only fields. Before the fix, these fields would be absent.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Eugie Limpin

Merge request reports

Loading