Optimize memory allocations in permissions cache (#89645)

This PR reduces the number of allocations made while caching permissions from the database, fixes the hierarchy of spans and adds new spans for tracing.

---------

Signed-off-by: Dave Henderson <dave.henderson@grafana.com>
Co-authored-by: Dave Henderson <dave.henderson@grafana.com>
This commit is contained in:
Jeff Levin
2024-06-26 23:03:13 +03:00
committed by GitHub
co-authored by Dave Henderson
parent f894c22b21
commit ed13959e33
5 changed files with 60 additions and 47 deletions
+2
View File
@@ -274,6 +274,7 @@ func setupSimpleHTTPServer(features featuremgmt.FeatureToggles) *HTTPServer {
authInfoService: &authinfotest.FakeService{ authInfoService: &authinfotest.FakeService{
ExpectedLabels: map[int64]string{int64(1): login.GetAuthProviderLabel(login.LDAPAuthModule)}, ExpectedLabels: map[int64]string{int64(1): login.GetAuthProviderLabel(login.LDAPAuthModule)},
}, },
tracer: tracing.InitializeTracerForTest(),
} }
} }
@@ -299,6 +300,7 @@ func SetupAPITestServer(t *testing.T, opts ...APITestServerOption) *webtest.Serv
Features: featuremgmt.WithFeatures(), Features: featuremgmt.WithFeatures(),
QuotaService: quotatest.New(false, nil), QuotaService: quotatest.New(false, nil),
searchUsersService: &searchusers.OSSService{}, searchUsersService: &searchusers.OSSService{},
tracer: tracing.InitializeTracerForTest(),
} }
for _, opt := range opts { for _, opt := range opts {
+11 -10
View File
@@ -50,7 +50,6 @@ func (hs *HTTPServer) isDashboardStarredByUser(c *contextmodel.ReqContext, dashI
} }
userID, err := identity.IntIdentifier(namespaceID, userIDstr) userID, err := identity.IntIdentifier(namespaceID, userIDstr)
if err != nil { if err != nil {
return false, err return false, err
} }
@@ -83,8 +82,11 @@ func dashboardGuardianResponse(err error) response.Response {
// 404: notFoundError // 404: notFoundError
// 500: internalServerError // 500: internalServerError
func (hs *HTTPServer) GetDashboard(c *contextmodel.ReqContext) response.Response { func (hs *HTTPServer) GetDashboard(c *contextmodel.ReqContext) response.Response {
ctx, span := hs.tracer.Start(c.Req.Context(), "httpserver.GetDashboard")
defer span.End()
uid := web.Params(c.Req)[":uid"] uid := web.Params(c.Req)[":uid"]
dash, rsp := hs.getDashboardHelper(c.Req.Context(), c.SignedInUser.GetOrgID(), 0, uid) dash, rsp := hs.getDashboardHelper(ctx, c.SignedInUser.GetOrgID(), 0, uid)
if rsp != nil { if rsp != nil {
return rsp return rsp
} }
@@ -96,7 +98,7 @@ func (hs *HTTPServer) GetDashboard(c *contextmodel.ReqContext) response.Response
// If public dashboards is enabled and we have a public dashboard, update meta values // If public dashboards is enabled and we have a public dashboard, update meta values
if hs.Features.IsEnabledGlobally(featuremgmt.FlagPublicDashboards) && hs.Cfg.PublicDashboardsEnabled { if hs.Features.IsEnabledGlobally(featuremgmt.FlagPublicDashboards) && hs.Cfg.PublicDashboardsEnabled {
publicDashboard, err := hs.PublicDashboardsApi.PublicDashboardService.FindByDashboardUid(c.Req.Context(), c.SignedInUser.GetOrgID(), dash.UID) publicDashboard, err := hs.PublicDashboardsApi.PublicDashboardService.FindByDashboardUid(ctx, c.SignedInUser.GetOrgID(), dash.UID)
if err != nil && !errors.Is(err, publicdashboardModels.ErrPublicDashboardNotFound) { if err != nil && !errors.Is(err, publicdashboardModels.ErrPublicDashboardNotFound) {
return response.Error(http.StatusInternalServerError, "Error while retrieving public dashboards", err) return response.Error(http.StatusInternalServerError, "Error while retrieving public dashboards", err)
} }
@@ -119,7 +121,7 @@ func (hs *HTTPServer) GetDashboard(c *contextmodel.ReqContext) response.Response
return response.Error(http.StatusInternalServerError, "Error while loading dashboard, dashboard data is invalid", nil) return response.Error(http.StatusInternalServerError, "Error while loading dashboard, dashboard data is invalid", nil)
} }
} }
guardian, err := guardian.NewByDashboard(c.Req.Context(), dash, c.SignedInUser.GetOrgID(), c.SignedInUser) guardian, err := guardian.NewByDashboard(ctx, dash, c.SignedInUser.GetOrgID(), c.SignedInUser)
if err != nil { if err != nil {
return response.Err(err) return response.Err(err)
} }
@@ -139,14 +141,14 @@ func (hs *HTTPServer) GetDashboard(c *contextmodel.ReqContext) response.Response
// Finding creator and last updater of the dashboard // Finding creator and last updater of the dashboard
updater, creator := anonString, anonString updater, creator := anonString, anonString
if dash.UpdatedBy > 0 { if dash.UpdatedBy > 0 {
updater = hs.getUserLogin(c.Req.Context(), dash.UpdatedBy) updater = hs.getUserLogin(ctx, dash.UpdatedBy)
} }
if dash.CreatedBy > 0 { if dash.CreatedBy > 0 {
creator = hs.getUserLogin(c.Req.Context(), dash.CreatedBy) creator = hs.getUserLogin(ctx, dash.CreatedBy)
} }
annotationPermissions := &dashboardsV0.AnnotationPermission{} annotationPermissions := &dashboardsV0.AnnotationPermission{}
if hs.Features.IsEnabled(c.Req.Context(), featuremgmt.FlagAnnotationPermissionUpdate) { if hs.Features.IsEnabled(ctx, featuremgmt.FlagAnnotationPermissionUpdate) {
hs.getAnnotationPermissionsByScope(c, &annotationPermissions.Dashboard, dashboards.ScopeDashboardsProvider.GetResourceScopeUID(dash.UID)) hs.getAnnotationPermissionsByScope(c, &annotationPermissions.Dashboard, dashboards.ScopeDashboardsProvider.GetResourceScopeUID(dash.UID))
} else { } else {
hs.getAnnotationPermissionsByScope(c, &annotationPermissions.Dashboard, accesscontrol.ScopeAnnotationsTypeDashboard) hs.getAnnotationPermissionsByScope(c, &annotationPermissions.Dashboard, accesscontrol.ScopeAnnotationsTypeDashboard)
@@ -182,7 +184,7 @@ func (hs *HTTPServer) GetDashboard(c *contextmodel.ReqContext) response.Response
// nolint:staticcheck // nolint:staticcheck
query := dashboards.GetDashboardQuery{ID: dash.FolderID, OrgID: c.SignedInUser.GetOrgID()} query := dashboards.GetDashboardQuery{ID: dash.FolderID, OrgID: c.SignedInUser.GetOrgID()}
metrics.MFolderIDsAPICount.WithLabelValues(metrics.GetDashboard).Inc() metrics.MFolderIDsAPICount.WithLabelValues(metrics.GetDashboard).Inc()
queryResult, err := hs.DashboardService.GetDashboard(c.Req.Context(), &query) queryResult, err := hs.DashboardService.GetDashboard(ctx, &query)
if err != nil { if err != nil {
if errors.Is(err, dashboards.ErrFolderNotFound) { if errors.Is(err, dashboards.ErrFolderNotFound) {
return response.Error(http.StatusNotFound, "Folder not found", err) return response.Error(http.StatusNotFound, "Folder not found", err)
@@ -194,7 +196,7 @@ func (hs *HTTPServer) GetDashboard(c *contextmodel.ReqContext) response.Response
meta.FolderUrl = queryResult.GetURL() meta.FolderUrl = queryResult.GetURL()
} }
provisioningData, err := hs.dashboardProvisioningService.GetProvisionedDashboardDataByDashboardID(c.Req.Context(), dash.ID) provisioningData, err := hs.dashboardProvisioningService.GetProvisionedDashboardDataByDashboardID(ctx, dash.ID)
if err != nil { if err != nil {
return response.Error(http.StatusInternalServerError, "Error while checking if dashboard is provisioned", err) return response.Error(http.StatusInternalServerError, "Error while checking if dashboard is provisioned", err)
} }
@@ -1004,7 +1006,6 @@ func (hs *HTTPServer) CalculateDashboardDiff(c *contextmodel.ReqContext) respons
newData := newVersionRes.Data newData := newVersionRes.Data
result, err := dashdiffs.CalculateDiff(c.Req.Context(), &options, baseData, newData) result, err := dashdiffs.CalculateDiff(c.Req.Context(), &options, baseData, newData)
if err != nil { if err != nil {
if errors.Is(err, dashver.ErrDashboardVersionNotFound) { if errors.Is(err, dashver.ErrDashboardVersionNotFound) {
return response.Error(http.StatusNotFound, "Dashboard version not found", err) return response.Error(http.StatusNotFound, "Dashboard version not found", err)
+19 -9
View File
@@ -81,6 +81,7 @@ func TestGetHomeDashboard(t *testing.T) {
preferenceService: prefService, preferenceService: prefService,
dashboardVersionService: dashboardVersionService, dashboardVersionService: dashboardVersionService,
log: log.New("test-logger"), log: log.New("test-logger"),
tracer: tracing.InitializeTracerForTest(),
} }
tests := []struct { tests := []struct {
@@ -585,7 +586,8 @@ func TestDashboardAPIEndpoint(t *testing.T) {
DashboardID: 2, DashboardID: 2,
Version: 1, Version: 1,
Data: fakeDash.Data, Data: fakeDash.Data,
}} },
}
mockSQLStore := dbtest.NewFakeDB() mockSQLStore := dbtest.NewFakeDB()
origNewGuardian := guardian.New origNewGuardian := guardian.New
guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{CanSaveValue: true}) guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{CanSaveValue: true})
@@ -622,7 +624,8 @@ func TestDashboardAPIEndpoint(t *testing.T) {
DashboardID: 2, DashboardID: 2,
Version: 1, Version: 1,
Data: fakeDash.Data, Data: fakeDash.Data,
}} },
}
cmd := dtos.RestoreDashboardVersionCommand{ cmd := dtos.RestoreDashboardVersionCommand{
Version: 1, Version: 1,
@@ -680,6 +683,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
DashboardService: dashboardService, DashboardService: dashboardService,
Features: featuremgmt.WithFeatures(), Features: featuremgmt.WithFeatures(),
starService: startest.NewStarServiceFake(), starService: startest.NewStarServiceFake(),
tracer: tracing.InitializeTracerForTest(),
} }
hs.callGetDashboard(sc) hs.callGetDashboard(sc)
@@ -718,6 +722,7 @@ func TestDashboardVersionsAPIEndpoint(t *testing.T) {
userService: userSvc, userService: userSvc,
CacheService: localcache.New(5*time.Minute, 10*time.Minute), CacheService: localcache.New(5*time.Minute, 10*time.Minute),
log: log.New(), log: log.New(),
tracer: tracing.InitializeTracerForTest(),
} }
} }
@@ -855,6 +860,7 @@ func getDashboardShouldReturn200WithConfig(t *testing.T, sc *scenarioContext, pr
DashboardService: dashboardService, DashboardService: dashboardService,
Features: featuremgmt.WithFeatures(), Features: featuremgmt.WithFeatures(),
starService: startest.NewStarServiceFake(), starService: startest.NewStarServiceFake(),
tracer: tracing.InitializeTracerForTest(),
} }
hs.callGetDashboard(sc) hs.callGetDashboard(sc)
@@ -908,6 +914,7 @@ func postDashboardScenario(t *testing.T, desc string, url string, routePattern s
Features: featuremgmt.WithFeatures(), Features: featuremgmt.WithFeatures(),
accesscontrolService: actest.FakeService{}, accesscontrolService: actest.FakeService{},
log: log.New("test-logger"), log: log.New("test-logger"),
tracer: tracing.InitializeTracerForTest(),
} }
sc := setupScenarioContext(t, url) sc := setupScenarioContext(t, url)
@@ -927,7 +934,8 @@ func postDashboardScenario(t *testing.T, desc string, url string, routePattern s
} }
func postDiffScenario(t *testing.T, desc string, url string, routePattern string, cmd dtos.CalculateDiffOptions, func postDiffScenario(t *testing.T, desc string, url string, routePattern string, cmd dtos.CalculateDiffOptions,
role org.RoleType, fn scenarioFunc, sqlmock db.DB, fakeDashboardVersionService *dashvertest.FakeDashboardVersionService) { role org.RoleType, fn scenarioFunc, sqlmock db.DB, fakeDashboardVersionService *dashvertest.FakeDashboardVersionService,
) {
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) { t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
cfg := setting.NewCfg() cfg := setting.NewCfg()
@@ -943,6 +951,7 @@ func postDiffScenario(t *testing.T, desc string, url string, routePattern string
dashboardVersionService: fakeDashboardVersionService, dashboardVersionService: fakeDashboardVersionService,
Features: featuremgmt.WithFeatures(), Features: featuremgmt.WithFeatures(),
DashboardService: dashSvc, DashboardService: dashSvc,
tracer: tracing.InitializeTracerForTest(),
} }
sc := setupScenarioContext(t, url) sc := setupScenarioContext(t, url)
@@ -967,7 +976,8 @@ func postDiffScenario(t *testing.T, desc string, url string, routePattern string
func restoreDashboardVersionScenario(t *testing.T, desc string, url string, routePattern string, func restoreDashboardVersionScenario(t *testing.T, desc string, url string, routePattern string,
mock *dashboards.FakeDashboardService, fakeDashboardVersionService *dashvertest.FakeDashboardVersionService, mock *dashboards.FakeDashboardService, fakeDashboardVersionService *dashvertest.FakeDashboardVersionService,
cmd dtos.RestoreDashboardVersionCommand, fn scenarioFunc, sqlStore db.DB) { cmd dtos.RestoreDashboardVersionCommand, fn scenarioFunc, sqlStore db.DB,
) {
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) { t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
cfg := setting.NewCfg() cfg := setting.NewCfg()
folderSvc := foldertest.NewFakeService() folderSvc := foldertest.NewFakeService()
@@ -986,6 +996,7 @@ func restoreDashboardVersionScenario(t *testing.T, desc string, url string, rout
dashboardVersionService: fakeDashboardVersionService, dashboardVersionService: fakeDashboardVersionService,
accesscontrolService: actest.FakeService{}, accesscontrolService: actest.FakeService{},
folderService: folderSvc, folderService: folderSvc,
tracer: tracing.InitializeTracerForTest(),
} }
sc := setupScenarioContext(t, url) sc := setupScenarioContext(t, url)
@@ -1022,12 +1033,12 @@ type mockDashboardProvisioningService struct {
} }
func (s mockDashboardProvisioningService) GetProvisionedDashboardDataByDashboardID(ctx context.Context, dashboardID int64) ( func (s mockDashboardProvisioningService) GetProvisionedDashboardDataByDashboardID(ctx context.Context, dashboardID int64) (
*dashboards.DashboardProvisioning, error) { *dashboards.DashboardProvisioning, error,
) {
return nil, nil return nil, nil
} }
type mockLibraryPanelService struct { type mockLibraryPanelService struct{}
}
var _ librarypanels.Service = (*mockLibraryPanelService)(nil) var _ librarypanels.Service = (*mockLibraryPanelService)(nil)
@@ -1039,8 +1050,7 @@ func (m *mockLibraryPanelService) ImportLibraryPanelsForDashboard(c context.Cont
return nil return nil
} }
type mockLibraryElementService struct { type mockLibraryElementService struct{}
}
func (l *mockLibraryElementService) CreateElement(c context.Context, signedInUser identity.Requester, cmd model.CreateLibraryElementCommand) (model.LibraryElementDTO, error) { func (l *mockLibraryElementService) CreateElement(c context.Context, signedInUser identity.Requester, cmd model.CreateLibraryElementCommand) (model.LibraryElementDTO, error) {
return model.LibraryElementDTO{}, nil return model.LibraryElementDTO{}, nil
+27 -25
View File
@@ -9,6 +9,7 @@ import (
"time" "time"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"go.opentelemetry.io/otel/attribute"
"github.com/grafana/grafana/pkg/api/routing" "github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/apimachinery/identity" "github.com/grafana/grafana/pkg/apimachinery/identity"
@@ -45,8 +46,7 @@ var SharedWithMeFolderPermission = accesscontrol.Permission{
var OSSRolesPrefixes = []string{accesscontrol.ManagedRolePrefix, accesscontrol.ExternalServiceRolePrefix} var OSSRolesPrefixes = []string{accesscontrol.ManagedRolePrefix, accesscontrol.ExternalServiceRolePrefix}
func ProvideService(cfg *setting.Cfg, db db.DB, routeRegister routing.RouteRegister, cache *localcache.CacheService, func ProvideService(cfg *setting.Cfg, db db.DB, routeRegister routing.RouteRegister, cache *localcache.CacheService, accessControl accesscontrol.AccessControl, actionResolver accesscontrol.ActionResolver, features featuremgmt.FeatureToggles, tracer tracing.Tracer) (*Service, error) {
accessControl accesscontrol.AccessControl, actionResolver accesscontrol.ActionResolver, features featuremgmt.FeatureToggles, tracer tracing.Tracer) (*Service, error) {
service := ProvideOSSService(cfg, database.ProvideService(db), actionResolver, cache, features, tracer) service := ProvideOSSService(cfg, database.ProvideService(db), actionResolver, cache, features, tracer)
api.NewAccessControlAPI(routeRegister, accessControl, service, features).RegisterAPIEndpoints() api.NewAccessControlAPI(routeRegister, accessControl, service, features).RegisterAPIEndpoints()
@@ -151,9 +151,9 @@ func (s *Service) getBasicRolePermissions(ctx context.Context, role string, orgI
ctx, span := s.tracer.Start(ctx, "authz.getBasicRolePermissions") ctx, span := s.tracer.Start(ctx, "authz.getBasicRolePermissions")
defer span.End() defer span.End()
permissions := make([]accesscontrol.Permission, 0) var permissions []accesscontrol.Permission
if basicRole, ok := s.roles[role]; ok { if basicRole, ok := s.roles[role]; ok {
permissions = append(permissions, basicRole.Permissions...) permissions = basicRole.Permissions
} }
// Fetch managed role permissions assigned to basic roles // Fetch managed role permissions assigned to basic roles
@@ -209,7 +209,6 @@ func (s *Service) getUserDirectPermissions(ctx context.Context, user identity.Re
UserID: userID, UserID: userID,
RolePrefixes: OSSRolesPrefixes, RolePrefixes: OSSRolesPrefixes,
}) })
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -225,12 +224,16 @@ func (s *Service) getUserDirectPermissions(ctx context.Context, user identity.Re
} }
func (s *Service) getCachedUserPermissions(ctx context.Context, user identity.Requester, options accesscontrol.Options) ([]accesscontrol.Permission, error) { func (s *Service) getCachedUserPermissions(ctx context.Context, user identity.Requester, options accesscontrol.Options) ([]accesscontrol.Permission, error) {
basicRolesPermissions, err := s.getCachedBasicRolesPermissions(ctx, user, options) ctx, span := s.tracer.Start(ctx, "authz.getCachedUserPermissions")
defer span.End()
permissions := []accesscontrol.Permission{}
permissions, err := s.getCachedBasicRolesPermissions(ctx, user, options, permissions)
if err != nil { if err != nil {
return nil, err return nil, err
} }
teamsPermissions, err := s.getCachedTeamsPermissions(ctx, user, options) permissions, err = s.getCachedTeamsPermissions(ctx, user, options, permissions)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -240,32 +243,33 @@ func (s *Service) getCachedUserPermissions(ctx context.Context, user identity.Re
return nil, err return nil, err
} }
permissions := make([]accesscontrol.Permission, 0, len(basicRolesPermissions)+len(teamsPermissions)+len(userPermissions))
permissions = append(permissions, basicRolesPermissions...)
permissions = append(permissions, teamsPermissions...)
permissions = append(permissions, userPermissions...) permissions = append(permissions, userPermissions...)
span.SetAttributes(attribute.Int("num_permissions", len(permissions)))
return permissions, nil return permissions, nil
} }
func (s *Service) getCachedBasicRolesPermissions(ctx context.Context, user identity.Requester, options accesscontrol.Options) ([]accesscontrol.Permission, error) { func (s *Service) getCachedBasicRolesPermissions(ctx context.Context, user identity.Requester, options accesscontrol.Options, permissions []accesscontrol.Permission) ([]accesscontrol.Permission, error) {
ctx, span := s.tracer.Start(ctx, "authz.getCachedBasicRolesPermissions") ctx, span := s.tracer.Start(ctx, "authz.getCachedBasicRolesPermissions")
defer span.End() defer span.End()
basicRoles := accesscontrol.GetOrgRoles(user) basicRoles := accesscontrol.GetOrgRoles(user)
basicRolesPermissions := make([]accesscontrol.Permission, 0)
for _, role := range basicRoles { for _, role := range basicRoles {
permissions, err := s.getCachedBasicRolePermissions(ctx, role, user.GetOrgID(), options) perms, err := s.getCachedBasicRolePermissions(ctx, role, user.GetOrgID(), options)
if err != nil { if err != nil {
return nil, err return nil, err
} }
basicRolesPermissions = append(basicRolesPermissions, permissions...) permissions = append(permissions, perms...)
} }
return basicRolesPermissions, nil return permissions, nil
} }
func (s *Service) getCachedBasicRolePermissions(ctx context.Context, role string, orgID int64, options accesscontrol.Options) ([]accesscontrol.Permission, error) { func (s *Service) getCachedBasicRolePermissions(ctx context.Context, role string, orgID int64, options accesscontrol.Options) ([]accesscontrol.Permission, error) {
ctx, span := s.tracer.Start(ctx, "authz.getCachedBasicRolePermissions")
defer span.End()
key := accesscontrol.GetBasicRolePermissionCacheKey(role, orgID) key := accesscontrol.GetBasicRolePermissionCacheKey(role, orgID)
getPermissionsFn := func() ([]accesscontrol.Permission, error) { getPermissionsFn := func(ctx context.Context) ([]accesscontrol.Permission, error) {
return s.getBasicRolePermissions(ctx, role, orgID) return s.getBasicRolePermissions(ctx, role, orgID)
} }
return s.getCachedPermissions(ctx, key, getPermissionsFn, options) return s.getCachedPermissions(ctx, key, getPermissionsFn, options)
@@ -276,17 +280,17 @@ func (s *Service) getCachedUserDirectPermissions(ctx context.Context, user ident
defer span.End() defer span.End()
key := accesscontrol.GetUserDirectPermissionCacheKey(user) key := accesscontrol.GetUserDirectPermissionCacheKey(user)
getUserPermissionsFn := func() ([]accesscontrol.Permission, error) { getUserPermissionsFn := func(ctx context.Context) ([]accesscontrol.Permission, error) {
return s.getUserDirectPermissions(ctx, user) return s.getUserDirectPermissions(ctx, user)
} }
return s.getCachedPermissions(ctx, key, getUserPermissionsFn, options) return s.getCachedPermissions(ctx, key, getUserPermissionsFn, options)
} }
type GetPermissionsFn = func() ([]accesscontrol.Permission, error) type getPermissionsFunc = func(ctx context.Context) ([]accesscontrol.Permission, error)
// Generic method for getting various permissions from cache // Generic method for getting various permissions from cache
func (s *Service) getCachedPermissions(ctx context.Context, key string, getPermissionsFn GetPermissionsFn, options accesscontrol.Options) ([]accesscontrol.Permission, error) { func (s *Service) getCachedPermissions(ctx context.Context, key string, getPermissionsFn getPermissionsFunc, options accesscontrol.Options) ([]accesscontrol.Permission, error) {
_, span := s.tracer.Start(ctx, "authz.getCachedTeamsPermissions") _, span := s.tracer.Start(ctx, "authz.getCachedPermissions")
defer span.End() defer span.End()
if !options.ReloadCache { if !options.ReloadCache {
@@ -299,7 +303,7 @@ func (s *Service) getCachedPermissions(ctx context.Context, key string, getPermi
span.AddEvent("cache miss") span.AddEvent("cache miss")
metrics.MAccessPermissionsCacheUsage.WithLabelValues(accesscontrol.CacheMiss).Inc() metrics.MAccessPermissionsCacheUsage.WithLabelValues(accesscontrol.CacheMiss).Inc()
permissions, err := getPermissionsFn() permissions, err := getPermissionsFn(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -308,13 +312,12 @@ func (s *Service) getCachedPermissions(ctx context.Context, key string, getPermi
return permissions, nil return permissions, nil
} }
func (s *Service) getCachedTeamsPermissions(ctx context.Context, user identity.Requester, options accesscontrol.Options) ([]accesscontrol.Permission, error) { func (s *Service) getCachedTeamsPermissions(ctx context.Context, user identity.Requester, options accesscontrol.Options, permissions []accesscontrol.Permission) ([]accesscontrol.Permission, error) {
ctx, span := s.tracer.Start(ctx, "authz.getCachedTeamsPermissions") ctx, span := s.tracer.Start(ctx, "authz.getCachedTeamsPermissions")
defer span.End() defer span.End()
teams := user.GetTeams() teams := user.GetTeams()
orgID := user.GetOrgID() orgID := user.GetOrgID()
permissions := make([]accesscontrol.Permission, 0)
miss := teams miss := teams
if !options.ReloadCache { if !options.ReloadCache {
@@ -433,8 +436,7 @@ func GetActionFilter(options accesscontrol.SearchOptions) func(action string) bo
} }
// SearchUsersPermissions returns all users' permissions filtered by action prefixes // SearchUsersPermissions returns all users' permissions filtered by action prefixes
func (s *Service) SearchUsersPermissions(ctx context.Context, usr identity.Requester, func (s *Service) SearchUsersPermissions(ctx context.Context, usr identity.Requester, options accesscontrol.SearchOptions) (map[int64][]accesscontrol.Permission, error) {
options accesscontrol.SearchOptions) (map[int64][]accesscontrol.Permission, error) {
// Limit roles to available in OSS // Limit roles to available in OSS
options.RolePrefixes = OSSRolesPrefixes options.RolePrefixes = OSSRolesPrefixes
if options.NamespacedID != "" { if options.NamespacedID != "" {
+1 -3
View File
@@ -7,9 +7,7 @@ import (
"github.com/grafana/grafana/pkg/services/authn" "github.com/grafana/grafana/pkg/services/authn"
) )
var ( var errDecodingBasicAuthHeader = errutil.BadRequest("basic-auth.invalid-header", errutil.WithPublicMessage("Invalid Basic Auth Header"))
errDecodingBasicAuthHeader = errutil.BadRequest("basic-auth.invalid-header", errutil.WithPublicMessage("Invalid Basic Auth Header"))
)
var _ authn.ContextAwareClient = new(Basic) var _ authn.ContextAwareClient = new(Basic)