From 338a41f17888261f8992a5f7ea9774226d55b8fa Mon Sep 17 00:00:00 2001 From: Ieva Date: Wed, 8 Jan 2025 14:53:32 +0200 Subject: [PATCH] AuthZ service: Add single flight groups for permission fetching (#98607) add single flight groups for user and anonymous permission checking --- pkg/services/authz/rbac/service.go | 70 ++++++++++++++++--------- pkg/services/authz/rbac/service_test.go | 1 + 2 files changed, 45 insertions(+), 26 deletions(-) diff --git a/pkg/services/authz/rbac/service.go b/pkg/services/authz/rbac/service.go index 7589eadfd2d..f6b8b5c2fe5 100644 --- a/pkg/services/authz/rbac/service.go +++ b/pkg/services/authz/rbac/service.go @@ -255,32 +255,42 @@ func (s *Service) getUserPermissions(ctx context.Context, ns claims.NamespaceInf return cached.(map[string]bool), nil } - basicRoles, err := s.getUserBasicRole(ctx, ns, userIdentifiers) + res, err, _ := s.sf.Do(userPermKey+"_getUserPermissions", func() (interface{}, error) { + basicRoles, err := s.getUserBasicRole(ctx, ns, userIdentifiers) + if err != nil { + return nil, err + } + + teamIDs, err := s.getUserTeams(ctx, ns, userIdentifiers) + if err != nil { + return nil, err + } + + userPermQuery := store.PermissionsQuery{ + UserID: userIdentifiers.ID, + Action: action, + TeamIDs: teamIDs, + Role: basicRoles.Role, + IsServerAdmin: basicRoles.IsAdmin, + } + + permissions, err := s.store.GetUserPermissions(ctx, ns, userPermQuery) + if err != nil { + return nil, err + } + scopeMap := getScopeMap(permissions) + + s.permCache.Set(userPermKey, scopeMap, 0) + span.SetAttributes(attribute.Int("num_permissions_fetched", len(permissions))) + + return scopeMap, nil + }) + if err != nil { return nil, err } - teamIDs, err := s.getUserTeams(ctx, ns, userIdentifiers) - if err != nil { - return nil, err - } - - userPermQuery := store.PermissionsQuery{ - UserID: userIdentifiers.ID, - Action: action, - TeamIDs: teamIDs, - Role: basicRoles.Role, - IsServerAdmin: basicRoles.IsAdmin, - } - - permissions, err := s.store.GetUserPermissions(ctx, ns, userPermQuery) - if err != nil { - return nil, err - } - scopeMap := getScopeMap(permissions) - s.permCache.Set(userPermKey, scopeMap, 0) - span.SetAttributes(attribute.Int("num_permissions_fetched", len(permissions))) - return scopeMap, nil + return res.(map[string]bool), nil } func (s *Service) getAnonymousPermissions(ctx context.Context, ns claims.NamespaceInfo, action string) (map[string]bool, error) { @@ -292,13 +302,21 @@ func (s *Service) getAnonymousPermissions(ctx context.Context, ns claims.Namespa return cached.(map[string]bool), nil } - permissions, err := s.store.GetUserPermissions(ctx, ns, store.PermissionsQuery{Action: action, Role: "Viewer"}) + res, err, _ := s.sf.Do(anonPermKey+"_getAnonymousPermissions", func() (interface{}, error) { + permissions, err := s.store.GetUserPermissions(ctx, ns, store.PermissionsQuery{Action: action, Role: "Viewer"}) + if err != nil { + return nil, err + } + scopeMap := getScopeMap(permissions) + s.permCache.Set(anonPermKey, scopeMap, 0) + return scopeMap, nil + }) + if err != nil { return nil, err } - scopeMap := getScopeMap(permissions) - s.permCache.Set(anonPermKey, scopeMap, 0) - return scopeMap, nil + + return res.(map[string]bool), nil } func (s *Service) GetUserIdentifiers(ctx context.Context, ns claims.NamespaceInfo, userUID string) (*store.UserIdentifiers, error) { diff --git a/pkg/services/authz/rbac/service_test.go b/pkg/services/authz/rbac/service_test.go index 6aaa0c80eec..8d10c1693f2 100644 --- a/pkg/services/authz/rbac/service_test.go +++ b/pkg/services/authz/rbac/service_test.go @@ -368,6 +368,7 @@ func TestService_getUserPermissions(t *testing.T) { tracer: tracing.NewNoopTracerService(), idCache: localcache.New(longCacheTTL, longCleanupInterval), permCache: cacheService, + sf: new(singleflight.Group), basicRoleCache: localcache.New(longCacheTTL, longCleanupInterval), teamCache: localcache.New(shortCacheTTL, shortCleanupInterval), }