Skip to content

Iteration REST API not filtering iterations from groups with no access

What does this MR do and why?

Iterations can be queried from ancestor groups by using the `include_ancestors_ flag.

In GraphQL, it only returns iterations from ancestor groups that the user has access to. In the REST API, it returns all iterations in ancestor groups. It is a bug that the REST API does not filter groups it can't access.

This MR fixes that.

How to set up and validate locally

  1. As an Admin, create the following group structure, with each group being a private group

    iteration-test
      iteration-subgroup
        iteration-subgroup-2
  2. in each group create cadence (Plan -> Iterations), non-automatic. Then for each cadence create a new iteration (3-dot menu to the right of the cadence list)

  3. open the graphql explorer, such as http://ee.gitlab.test:5100/-/graphql-explorer

  4. use the following query

    query {
      group(fullPath: "iteration-test/iteration-subgroup/iteration-subgroup-2") {
        id
        iterations(includeAncestors: true) {
          nodes {
            id
            title
          }
        }
      }
    }

    You should get back results similar to this, 3 iterations, one at each group level

    {
      "data": {
        "group": {
          "id": "gid://gitlab/Group/78",
          "iterations": {
            "nodes": [
              {
                "id": "gid://gitlab/Iteration/13545",
                "title": "Subgroup 2 Iteration"
              },
              {
                "id": "gid://gitlab/Iteration/11626",
                "title": "Iteration subgroup 1"
              },
              {
                "id": "gid://gitlab/Iteration/11627",
                "title": "Top level iteration"
              }
            ]
          }
        }
      }
    }
  5. Now test the REST API by pasting this into a new tab in the same browser session (so that it uses the admin session cookie)

    http://ee.gitlab.test:5100/api/v4/groups/78/iterations?include_ancestors=true

    Change the 78 into the group id that you got back in the GraphQL results above. You should see JSON returned that looks like this:

    [
        {
            "id":13545,
            "iid":1,
            "sequence":1,
            "group_id":78,
            "title":"Subgroup 2 Iteration",
            "description":"",
            "state":3,
            "created_at":"2023-11-07T19:11:23.992Z",
            "updated_at":"2023-11-16T00:05:06.221Z",
            "start_date":"2023-11-08",
            "due_date":"2023-11-15",
            "web_url":"http://ee.gitlab.test:5100/groups/iteration-test/iteration-subgroup/iteration-subgroup-2/-/iterations/13545"
            
        },
        {
            "id":11626,
            "iid":1,
            "sequence":1,
            "group_id":77,
            "title":"Iteration subgroup 1",
            "description":"",
            "state":2,
            "created_at":"2023-11-03T20:49:18.964Z",
            "updated_at":"2023-11-16T00:05:06.132Z",
            "start_date":"2023-11-10",
            "due_date":"2023-11-17",
            "web_url":"http://ee.gitlab.test:5100/groups/iteration-test/iteration-subgroup/-/iterations/11626"
            
        },
        {
            "id":11627,
            "iid":1,
            "sequence":1,
            "group_id":76,
            "title":"Top level iteration",
            "description":"",
            "state":2,
            "created_at":"2023-11-03T20:50:14.913Z",
            "updated_at":"2023-11-16T00:05:06.132Z",
            "start_date":"2023-11-10",
            "due_date":"2023-11-17",
            "web_url":"http://ee.gitlab.test:5100/groups/iteration-test/-/iterations/11627"
        }
    ]
  6. Now bring up another browser (a private tab, or if you're using Chrome then start Safari or Firefox)

  7. Login to your instance as an admin. Pick a user from http://ee.gitlab.test:5100/admin/users, and then add them as a member reporter (Manage -> Members) to the iteration-subgroup-2 group and the iteration-subgroup group. This gives that user permission to those two groups, but not the top-level group.

  8. Impersonate the user you chose. Now execute the same GraphQL query as above, you should only see 2 iterations returned.

  9. Execute the same REST API as above, and you should only see 2 iterations returned.

  10. For extra credit, change to master and re-run step 7 and 8. You will get different results (step 8 will be wrong).

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Related to #433082

Edited by Brett Walker

Merge request reports