Support all member namespaces for granular scopes

What does this MR do and why?

Support creating tokens with granular scopes for all groups and projects a user is a member of.

References

Issue: [BE] Support dynamic boundary for all groups an... (#571519)

Query

Rails

user = User.human.last
project = user.projects.first
token = user.personal_access_tokens.last
token.permitted_for_boundary?(Authz::Boundary.for(project), :create_issue)

Raw SQL

SELECT DISTINCT
	jsonb_array_elements_text(permissions)
FROM
	"granular_scopes"
	INNER JOIN "personal_access_token_granular_scopes" ON "granular_scopes"."id" = "personal_access_token_granular_scopes"."granular_scope_id"
WHERE
	"personal_access_token_granular_scopes"."personal_access_token_id" = 63
	AND("granular_scopes"."all_membership_namespaces" = FALSE
		AND "granular_scopes"."namespace_id" IN(90, 89)
		OR "granular_scopes"."all_membership_namespaces" = TRUE)

Query plan

Postgresql.ai: https://console.postgres.ai/shared/6a697a92-d5e0-4029-b594-9d7b5ebf2191

 HashAggregate  (cost=7.23..8.48 rows=100 width=32) (actual time=0.073..0.074 rows=2 loops=1)
   Group Key: jsonb_array_elements_text(granular_scopes.permissions)
   Buffers: shared hit=7
   I/O Timings: read=0.000 write=0.000
   ->  ProjectSet  (cost=0.29..6.98 rows=100 width=32) (actual time=0.067..0.069 rows=2 loops=1)
         Buffers: shared hit=7
         I/O Timings: read=0.000 write=0.000
         ->  Nested Loop  (cost=0.29..6.47 rows=1 width=32) (actual time=0.048..0.049 rows=1 loops=1)
               Buffers: shared hit=7
               I/O Timings: read=0.000 write=0.000
               ->  Index Scan using idx_pat_granular_scopes_on_pat_id on public.personal_access_token_granular_scopes  (cost=0.14..3.16 rows=1 width=8) (actual time=0.041..0.042 rows=1 loops=1)
                     Index Cond: (personal_access_token_granular_scopes.personal_access_token_id = 63)
                     Buffers: shared hit=5
                     I/O Timings: read=0.000 write=0.000
               ->  Index Scan using granular_scopes_pkey on public.granular_scopes  (cost=0.14..3.16 rows=1 width=40) (actual time=0.005..0.005 rows=1 loops=1)
                     Index Cond: (granular_scopes.id = personal_access_token_granular_scopes.granular_scope_id)
                     Filter: (((NOT granular_scopes.all_membership_namespaces) AND (granular_scopes.namespace_id = ANY ('{90,89}'::bigint[]))) OR granular_scopes.all_membership_namespaces)
                     Rows Removed by Filter: 0
                     Buffers: shared hit=2
                     I/O Timings: read=0.000 write=0.000
Settings: work_mem = '100MB', random_page_cost = '1.5', seq_page_cost = '4', effective_cache_size = '472585MB', jit = 'off'

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.

Edited by Alex Buijs

Merge request reports

Loading