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) - if err != nil { - return nil, err - } + 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 - } + 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, - } + 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 + }) - 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), }