Improve epics finder group authorizations
What does this MR do and why?
Small refactoring that allows saving some queries skipping authorization checks for groups when a user has access and can read epics on their parent.
This is a temporary improvement until transversal ids are not enabled to query groups.
Sample logs
No queries are going to be changed with this MR. We are actually skipping queries
for group descendants array when checking permissions, the array is already loaded into memory. To compare queries ran I did set up a hierarchy of groups with 40 descendants, which produced the following results:
Query saved for each descendant group
SELECT Max("members"."access_level") AS maximum_access_level,
"members"."user_id" AS members_user_id
FROM (
(
SELECT "members"."id",
"members"."access_level",
"members"."source_id",
"members"."source_type",
"members"."user_id",
"members"."notification_level",
"members"."type",
"members"."created_at",
"members"."updated_at",
"members"."created_by_id",
"members"."invite_email",
"members"."invite_token",
"members"."invite_accepted_at",
"members"."requested_at",
"members"."expires_at",
"members"."ldap",
"members"."override",
"members"."state",
"members"."invite_email_success",
"members"."member_namespace_id"
FROM "members"
LEFT OUTER JOIN "users"
ON "users"."id" = "members"."user_id"
WHERE "members"."type" = 'GroupMember'
AND "members"."source_type" = 'Namespace'
AND "users"."state" = 'active'
AND "members"."state" = 0
AND "members"."requested_at" IS NULL
AND "members"."invite_token" IS NULL
AND (
members.access_level > 5)
AND (
members.access_level > 5)
AND "members"."source_id" IN
(
SELECT "namespaces"."id"
FROM "namespaces"
WHERE "namespaces"."type" = 'Group'
AND "namespaces"."id" IN (184,
197,
198,
199,
200,
201,
202,
203,
204,
205,
206,
207,
208,
209,
210,
211,
212)))
UNION
(WITH "group_group_links_cte" AS materialized
(
SELECT "group_group_links".*
FROM "group_group_links"
WHERE "group_group_links"."shared_group_id" IN
(
SELECT "namespaces"."id"
FROM "namespaces"
WHERE "namespaces"."type" = 'Group'
AND "namespaces"."id" IN (184,
197,
198,
199,
200,
201,
202,
203,
204,
205,
206,
207,
208,
209,
210,
211,
212)))SELECT "members"."id",
Least("group_group_links"."group_access", "members"."access_level") AS access_level,
"members"."source_id",
"members"."source_type",
"members"."user_id",
"members"."notification_level",
"members"."type",
"members"."created_at",
"members"."updated_at",
"members"."created_by_id",
"members"."invite_email",
"members"."invite_token",
"members"."invite_accepted_at",
"members"."requested_at",
"members"."expires_at",
"members"."ldap",
"members"."override",
"members"."state",
"members"."invite_email_success",
"members"."member_namespace_id"
FROM "members",
"group_group_links_cte" AS "group_group_links"
WHERE "members"."type" = 'GroupMember'
AND "members"."source_type" = 'Namespace'
AND "members"."requested_at" IS NULL
AND "members"."source_id" = "group_group_links"."shared_with_group_id"
AND "members"."source_type" = 'Namespace'
AND "members"."state" = 0
AND (
members.access_level > 5))) members
WHERE "members"."type" = 'GroupMember'
AND "members"."source_type" = 'Namespace'
AND "members"."user_id" = 85
GROUP BY "members"."user_id"
The new filter will give us some advantage in some specific scenarios, especially when the user is fetching epics on a group in which it has membership and has too many descendants.
This filtering is a bit sensitive, so the new filtering method with improvements
is behind a feature flag: :find_epics_performance_improvement
.
related to #327901 (closed)
How to set up and validate locally
Run the spec added to ee/spec/finders/epics_finder_spec.rb
and check for logs/test.log
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
-
I have evaluated the MR acceptance checklist for this MR.