Return masked to-dos behind expired group SAML sessions

What does this MR do and why?

On the dashboard To-Do list, a to-do whose target sits behind an expired group SAML session was dropped from the list entirely, while the to-do counter still counted it. This produced a mismatch: the badge showed more items than the list displayed (for example counter says 6, list shows 4). The frontend already has UI to render such a to-do "masked" (contents hidden, prompting the user to reauthenticate with group SAML), introduced in #500715 (closed), but the backend never returned these to-dos, so the masked UI never appeared.

Root cause: TodoPolicy#read_todo requires the user can read the to-do's target. An expired group SAML session makes the target unreadable, so GraphQL connection authorization filtered the to-do out of the list.

Fix: an EE extension of TodoPolicy keeps read_todo enabled when the target is inaccessible only because of an expired-but-restorable group SAML session, detected via Gitlab::Auth::GroupSaml::SsoEnforcer.access_restricted?. The target_entity GraphQL field still resolves to null via the target's own authorization, so the existing frontend renders the to-do masked. To-dos the user genuinely cannot access (lost membership, confidential notes) stay hidden. Scope is EE and SAML-only, no feature flag, and only the GraphQL to-dos connection is affected.

This addresses point 1 of #565992 (closed) (the banner in point 2 was handled separately in !253026 (merged)), and the count-vs-list discrepancy is tracked in #473762.

Screenshots or screen recordings

To-Do List with a to-do whose target is behind an expired group SAML session. Before, the counter reads 2 but only one item shows (the group SAML to-do is hidden). After, both items show and the group SAML to-do is masked with a "Hidden" badge and a prompt to reauthenticate.

Light mode

Before After
before, light after, light

Dark mode

Before After
before, dark after, dark

How to set up and validate locally

  1. On a SAML-enforced group, create a private project and an issue, and ensure the current user has a to-do targeting it (for example, get assigned or mentioned).
  2. Let the group SAML session expire (or avoid establishing one).
  3. Visit the dashboard To-Do list at /dashboard/todos.
  4. Confirm the to-do now appears in the list in a masked state (contents hidden, with a prompt to reauthenticate) rather than being missing, and that the visible list count matches the counter badge.

Also note the automated coverage: ee/spec/policies/ee/todo_policy_spec.rb and the group SAML context added to ee/spec/requests/api/graphql/current_user/todos_query_spec.rb.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist at https://docs.gitlab.com/development/code_review/#acceptance-checklist.

Edited by Bogdan Denkovych

Merge request reports

Loading
Loading