Skip to content

Check for ancestors confidential access in EpicsFinder

Related to #345879 (closed)

What does this MR do and why?

When using EpicsFinder with param include_ancestor_groups set as true, it doesn't return confidential epics from ancestors that the user is not a member of, despite having permission to read confidential epics (inherited from a parent group).

Example:

Given the following stack:

Group A -> Group B -> Group C -> Project C

If we have a confidential epic in Group C, a member (reporter+) of Group B will have permission to read it. Despite this, currently when the user creates a new issue in Project C is not able to assign it to such epic.

This is happening because EpicsFinder#groups_with_confidential_access only checks if the user is a member of the group, and because the user is not a member of Group C, it won't display the confidential epic.

To correct this, we have to check the permission read_confidential_epic for each group in the stack.

Queries

Executing:

EpicsFinder.new(reporter, {group_id: group_c.id, include_ancestor_groups: true}).execute

Query before:

SELECT "epics".* FROM "epics" WHERE "epics"."group_id" IN (127, 128, 129) AND ("epics"."confidential" = FALSE OR "epics"."confidential" = TRUE AND "epics"."group_id" IN (SELECT "members"."source_id" FROM "members" WHERE "members"."type" = 'GroupMember' AND "members"."source_type" = 'Namespace' AND "members"."source_id" IN (127, 128, 129) AND "members"."user_id" = 85 AND (members.access_level > 10))) ORDER BY "epics"."id" DESC

EXPLAIN (internal)

Query after:

SELECT "epics".* FROM "epics" WHERE "epics"."group_id" IN (127, 128, 129) AND ("epics"."confidential" = FALSE OR "epics"."confidential" = TRUE AND "epics"."group_id" IN (128, 129)) ORDER BY "epics"."id" DESC

EXPLAIN (internal)

Screenshots or screen recordings

Current behaviour After fix
confidential_epic_in_ancestor_not_displaying confidential_epic_in_ancestor_displaying

How to set up and validate locally

  1. Create a public group A.
  2. Create a public subgroup in A, called B.
  3. Create an additional public subgroup in B, called C.
  4. Create a public project in C, called Project C.
  5. Create a confidential epic in group C
  6. Add an external user to B with a reporter role.
  7. Logged in as the reporter visit the confidential epic (http://127.0.0.1:3000/groups/a/b/c/-/epics/1), it should be visible for this user.
  8. Create a new issue in Project C, the epics dropdown should display the confidential epic.

MR acceptance checklist

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

Edited by Eugenia Grieff

Merge request reports