Expose two_factor_enabled in group members API for owners
What does this MR do and why?
Expose two_factor_enabled in group members API for owners
Group owners can view the 2FA badge in the UI but had no way to
retrieve this information via the API. This change exposes the
two_factor_enabled field in GET /groups/:id/members and
GET /groups/:id/members/all responses when the requester has
the read_two_factor_member ability (group owners and administrators).
References
Screenshots or screen recordings
| Before | After |
|---|---|
![]() |
![]() |
Some tests executed via the CLI (click to expand)
# Owner — should see two_factor_enabled on all members ❯ curl --silent \ --url "http://gdk.test:3000/api/v4/groups/136/members" \ --header "PRIVATE-TOKEN: xxxx" \ | jq '[.[] | {username: .username} + (if has("two_factor_enabled") then {two_factor_enabled: .two_factor_enabled} else {} end)]' [ { "username": "tfa_owner", "two_factor_enabled": true }, { "username": "tfa_dev_2fa", "two_factor_enabled": true }, { "username": "tfa_dev_no2fa", "two_factor_enabled": false }, { "username": "tfa_reporter", "two_factor_enabled": false } ]Developer (with 2FA) — should NOT see two_factor_enabled
curl --silent
--url "http://gdk.test:3000/api/v4/groups/136/members"
--header "PRIVATE-TOKEN: xxxx"
| jq '[.[] | {username: .username} + (if has("two_factor_enabled") then {two_factor_enabled: .two_factor_enabled} else {} end)]' [ { "username": "tfa_owner" }, { "username": "tfa_dev_2fa" }, { "username": "tfa_dev_no2fa" }, { "username": "tfa_reporter" } ]Developer (without 2FA) — should NOT see two_factor_enabled
curl --silent
--url "http://gdk.test:3000/api/v4/groups/136/members"
--header "PRIVATE-TOKEN: xxxx"
| jq '[.[] | {username: .username} + (if has("two_factor_enabled") then {two_factor_enabled: .two_factor_enabled} else {} end)]' [ { "username": "tfa_owner" }, { "username": "tfa_dev_2fa" }, { "username": "tfa_dev_no2fa" }, { "username": "tfa_reporter" } ]Reporter — should NOT see two_factor_enabled
curl --silent
--url "http://gdk.test:3000/api/v4/groups/136/members"
--header "PRIVATE-TOKEN: xxxx"
| jq '[.[] | {username: .username} + (if has("two_factor_enabled") then {two_factor_enabled: .two_factor_enabled} else {} end)]' [ { "username": "tfa_owner" }, { "username": "tfa_dev_2fa" }, { "username": "tfa_dev_no2fa" }, { "username": "tfa_reporter" } ]
How to set up and validate locally
-
Run this Rails snippet to quickly generate a group with users, along with personal access tokens (see mr-238995-gen.rb).
The script will provide you with the personal access tokens for each user role, and a group ID you can use in the next step.
-
Use this
curlcommand with the PATs generated for testing:curl --silent \ --url "http://gdk.test:3000/api/v4/groups/xxxx/members" \ --header "PRIVATE-TOKEN: xxxx" \ | jq '[.[] | {username: .username} + (if has("two_factor_enabled") then {two_factor_enabled: .two_factor_enabled} else {} end)]'
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.

