diff --git a/pkg/api/annotations_test.go b/pkg/api/annotations_test.go index 977f3307ca1..12eea783e5d 100644 --- a/pkg/api/annotations_test.go +++ b/pkg/api/annotations_test.go @@ -15,6 +15,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" "github.com/grafana/grafana/pkg/services/annotations" "github.com/grafana/grafana/pkg/services/annotations/annotationstest" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/folder" @@ -401,7 +402,7 @@ func TestAPI_Annotations(t *testing.T) { folderDB.On("GetFolderByID", mock.Anything, mock.Anything, mock.Anything).Return(&folder.Folder{UID: folderUID, ID: 1}, nil) hs.DashboardService = dashService hs.folderService = folderService - hs.AccessControl = acimpl.ProvideAccessControl(featuremgmt.WithFeatures()) + hs.AccessControl = acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()) hs.AccessControl.RegisterScopeAttributeResolver(AnnotationTypeScopeResolver(hs.annotationsRepo, hs.Features, dashService, folderService)) hs.AccessControl.RegisterScopeAttributeResolver(dashboards.NewDashboardIDScopeResolver(folderDB, dashService, folderService)) }) diff --git a/pkg/api/common_test.go b/pkg/api/common_test.go index 91efe95161a..34a57c453f0 100644 --- a/pkg/api/common_test.go +++ b/pkg/api/common_test.go @@ -26,6 +26,7 @@ import ( "github.com/grafana/grafana/pkg/services/auth/authtest" "github.com/grafana/grafana/pkg/services/authn" "github.com/grafana/grafana/pkg/services/authn/authntest" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/contexthandler" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" dashver "github.com/grafana/grafana/pkg/services/dashboardversion" @@ -269,7 +270,7 @@ func setupSimpleHTTPServer(features featuremgmt.FeatureToggles) *HTTPServer { Cfg: cfg, Features: features, License: &licensing.OSSLicensingService{}, - AccessControl: acimpl.ProvideAccessControl(featuremgmt.WithFeatures()), + AccessControl: acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()), annotationsRepo: annotationstest.NewFakeAnnotationsRepo(), authInfoService: &authinfotest.FakeService{ ExpectedLabels: map[int64]string{int64(1): login.GetAuthProviderLabel(login.LDAPAuthModule)}, @@ -312,7 +313,7 @@ func SetupAPITestServer(t *testing.T, opts ...APITestServerOption) *webtest.Serv } if hs.AccessControl == nil { - hs.AccessControl = acimpl.ProvideAccessControl(featuremgmt.WithFeatures()) + hs.AccessControl = acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()) } hs.registerRoutes() diff --git a/pkg/api/dashboard_snapshot_test.go b/pkg/api/dashboard_snapshot_test.go index e005ae6a6a5..03ecb227b68 100644 --- a/pkg/api/dashboard_snapshot_test.go +++ b/pkg/api/dashboard_snapshot_test.go @@ -17,6 +17,7 @@ import ( "github.com/grafana/grafana/pkg/infra/db/dbtest" "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/dashboardsnapshots" "github.com/grafana/grafana/pkg/services/featuremgmt" @@ -39,7 +40,7 @@ func TestHTTPServer_DeleteDashboardSnapshot(t *testing.T) { hs.DashboardService = svc - hs.AccessControl = acimpl.ProvideAccessControl(featuremgmt.WithFeatures()) + hs.AccessControl = acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()) guardian.InitAccessControlGuardian(hs.Cfg, hs.AccessControl, hs.DashboardService) }) } diff --git a/pkg/api/dashboard_test.go b/pkg/api/dashboard_test.go index e249765952b..9b0c771d185 100644 --- a/pkg/api/dashboard_test.go +++ b/pkg/api/dashboard_test.go @@ -30,6 +30,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol/actest" accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock" "github.com/grafana/grafana/pkg/services/annotations/annotationstest" + "github.com/grafana/grafana/pkg/services/authz/zanzana" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/dashboards/database" @@ -130,7 +131,7 @@ func newTestLive(t *testing.T, store db.DB) *live.GrafanaLive { nil, &usagestats.UsageStatsMock{T: t}, nil, - features, acimpl.ProvideAccessControl(features), &dashboards.FakeDashboardService{}, annotationstest.NewFakeAnnotationsRepo(), nil) + features, acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()), &dashboards.FakeDashboardService{}, annotationstest.NewFakeAnnotationsRepo(), nil) require.NoError(t, err) return gLive } @@ -147,7 +148,7 @@ func TestHTTPServer_GetDashboard_AccessControl(t *testing.T) { hs.DashboardService = dashSvc hs.Cfg = setting.NewCfg() - hs.AccessControl = acimpl.ProvideAccessControl(featuremgmt.WithFeatures()) + hs.AccessControl = acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()) hs.starService = startest.NewStarServiceFake() hs.dashboardProvisioningService = mockDashboardProvisioningService{} @@ -266,7 +267,7 @@ func TestHTTPServer_DeleteDashboardByUID_AccessControl(t *testing.T) { hs.DashboardService = dashSvc hs.Cfg = setting.NewCfg() - hs.AccessControl = acimpl.ProvideAccessControl(featuremgmt.WithFeatures()) + hs.AccessControl = acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()) hs.starService = startest.NewStarServiceFake() hs.LibraryPanelService = &mockLibraryPanelService{} @@ -322,7 +323,7 @@ func TestHTTPServer_GetDashboardVersions_AccessControl(t *testing.T) { hs.DashboardService = dashSvc hs.Cfg = setting.NewCfg() - hs.AccessControl = acimpl.ProvideAccessControl(featuremgmt.WithFeatures()) + hs.AccessControl = acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()) hs.starService = startest.NewStarServiceFake() hs.dashboardVersionService = &dashvertest.FakeDashboardVersionService{ diff --git a/pkg/api/datasources_test.go b/pkg/api/datasources_test.go index a5e9bf72326..9ce98859bb2 100644 --- a/pkg/api/datasources_test.go +++ b/pkg/api/datasources_test.go @@ -19,6 +19,7 @@ import ( ac "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" "github.com/grafana/grafana/pkg/services/accesscontrol/actest" + "github.com/grafana/grafana/pkg/services/authz/zanzana" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" "github.com/grafana/grafana/pkg/services/datasources" "github.com/grafana/grafana/pkg/services/datasources/guardian" @@ -115,7 +116,7 @@ func TestAddDataSource_URLWithoutProtocol(t *testing.T) { expectedDatasource: &datasources.DataSource{}, }, Cfg: setting.NewCfg(), - AccessControl: acimpl.ProvideAccessControl(featuremgmt.WithFeatures()), + AccessControl: acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()), accesscontrolService: actest.FakeService{}, } @@ -332,7 +333,7 @@ func TestUpdateDataSource_URLWithoutProtocol(t *testing.T) { expectedDatasource: &datasources.DataSource{}, }, Cfg: setting.NewCfg(), - AccessControl: acimpl.ProvideAccessControl(featuremgmt.WithFeatures()), + AccessControl: acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()), accesscontrolService: actest.FakeService{}, } @@ -365,7 +366,7 @@ func TestUpdateDataSourceByID_DataSourceNameExists(t *testing.T) { }, }, Cfg: setting.NewCfg(), - AccessControl: acimpl.ProvideAccessControl(featuremgmt.WithFeatures()), + AccessControl: acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()), accesscontrolService: actest.FakeService{}, Live: newTestLive(t, nil), } diff --git a/pkg/api/folder_bench_test.go b/pkg/api/folder_bench_test.go index 478a97eb2b9..d1ae9f030ba 100644 --- a/pkg/api/folder_bench_test.go +++ b/pkg/api/folder_bench_test.go @@ -456,7 +456,7 @@ func setupServer(b testing.TB, sc benchScenario, features featuremgmt.FeatureTog folderStore := folderimpl.ProvideDashboardFolderStore(sc.db) - ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures()) + ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()) folderServiceWithFlagOn := folderimpl.ProvideService(ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashStore, folderStore, sc.db, features, supportbundlestest.NewFakeBundleService(), nil) cfg := setting.NewCfg() @@ -494,7 +494,7 @@ func setupServer(b testing.TB, sc benchScenario, features featuremgmt.FeatureTog DashboardService: dashboardSvc, } - hs.AccessControl = acimpl.ProvideAccessControl(featuremgmt.WithFeatures()) + hs.AccessControl = acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()) guardian.InitAccessControlGuardian(hs.Cfg, hs.AccessControl, hs.DashboardService) m.Get("/api/folders", hs.GetFolders) diff --git a/pkg/api/pluginproxy/ds_proxy_test.go b/pkg/api/pluginproxy/ds_proxy_test.go index 03fa9f076cc..5ceee760033 100644 --- a/pkg/api/pluginproxy/ds_proxy_test.go +++ b/pkg/api/pluginproxy/ds_proxy_test.go @@ -32,6 +32,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" "github.com/grafana/grafana/pkg/services/accesscontrol/actest" "github.com/grafana/grafana/pkg/services/authn" + "github.com/grafana/grafana/pkg/services/authz/zanzana" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" "github.com/grafana/grafana/pkg/services/datasources" datasourceservice "github.com/grafana/grafana/pkg/services/datasources/service" @@ -844,7 +845,7 @@ func getDatasourceProxiedRequest(t *testing.T, ctx *contextmodel.ReqContext, cfg secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger")) features := featuremgmt.WithFeatures() quotaService := quotatest.New(false, nil) - dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, features, acimpl.ProvideAccessControl(features), + dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, features, acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()), &actest.FakePermissionsService{}, quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{}, plugincontext.ProvideBaseService(cfg, pluginconfig.NewFakePluginRequestConfigProvider())) require.NoError(t, err) @@ -966,7 +967,7 @@ func runDatasourceAuthTest(t *testing.T, secretsService secrets.Service, secrets var routes []*plugins.Route features := featuremgmt.WithFeatures() quotaService := quotatest.New(false, nil) - dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, features, acimpl.ProvideAccessControl(features), + dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, features, acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()), &actest.FakePermissionsService{}, quotaService, &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{}, plugincontext.ProvideBaseService(cfg, pluginconfig.NewFakePluginRequestConfigProvider())) require.NoError(t, err) @@ -1022,7 +1023,7 @@ func setupDSProxyTest(t *testing.T, ctx *contextmodel.ReqContext, ds *datasource secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore()) secretsStore := secretskvs.NewSQLSecretsKVStore(dbtest.NewFakeDB(), secretsService, log.NewNopLogger()) features := featuremgmt.WithFeatures() - dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, features, acimpl.ProvideAccessControl(features), + dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, features, acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()), &actest.FakePermissionsService{}, quotatest.New(false, nil), &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{}, plugincontext.ProvideBaseService(cfg, pluginconfig.NewFakePluginRequestConfigProvider())) require.NoError(t, err) diff --git a/pkg/api/pluginproxy/pluginproxy_test.go b/pkg/api/pluginproxy/pluginproxy_test.go index 7bd4634de0d..ab8961a42ea 100644 --- a/pkg/api/pluginproxy/pluginproxy_test.go +++ b/pkg/api/pluginproxy/pluginproxy_test.go @@ -16,6 +16,7 @@ import ( "github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" "github.com/grafana/grafana/pkg/services/authn" + "github.com/grafana/grafana/pkg/services/authz/zanzana" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/org" @@ -265,7 +266,7 @@ func TestPluginProxy(t *testing.T) { SecureJSONData: map[string][]byte{}, } cfg := &setting.Cfg{} - proxy, err := NewPluginProxy(ps, routes, ctx, "", cfg, secretsService, tracing.InitializeTracerForTest(), &http.Transport{}, acimpl.ProvideAccessControl(featuremgmt.WithFeatures()), featuremgmt.WithFeatures()) + proxy, err := NewPluginProxy(ps, routes, ctx, "", cfg, secretsService, tracing.InitializeTracerForTest(), &http.Transport{}, acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()), featuremgmt.WithFeatures()) require.NoError(t, err) proxy.HandleRequest() @@ -421,7 +422,7 @@ func TestPluginProxyRoutes(t *testing.T) { SecureJSONData: map[string][]byte{}, } cfg := &setting.Cfg{} - proxy, err := NewPluginProxy(ps, testRoutes, ctx, tc.proxyPath, cfg, secretsService, tracing.InitializeTracerForTest(), &http.Transport{}, acimpl.ProvideAccessControl(featuremgmt.WithFeatures()), featuremgmt.WithFeatures(tc.withFeatures...)) + proxy, err := NewPluginProxy(ps, testRoutes, ctx, tc.proxyPath, cfg, secretsService, tracing.InitializeTracerForTest(), &http.Transport{}, acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()), featuremgmt.WithFeatures(tc.withFeatures...)) require.NoError(t, err) proxy.HandleRequest() @@ -536,7 +537,7 @@ func TestPluginProxyRoutesAccessControl(t *testing.T) { SecureJSONData: map[string][]byte{}, } cfg := &setting.Cfg{} - proxy, err := NewPluginProxy(ps, testRoutes, ctx, tc.proxyPath, cfg, secretsService, tracing.InitializeTracerForTest(), &http.Transport{}, acimpl.ProvideAccessControl(featuremgmt.WithFeatures()), featuremgmt.WithFeatures(featuremgmt.FlagAccessControlOnCall)) + proxy, err := NewPluginProxy(ps, testRoutes, ctx, tc.proxyPath, cfg, secretsService, tracing.InitializeTracerForTest(), &http.Transport{}, acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()), featuremgmt.WithFeatures(featuremgmt.FlagAccessControlOnCall)) require.NoError(t, err) proxy.HandleRequest() @@ -567,7 +568,7 @@ func getPluginProxiedRequest(t *testing.T, ps *pluginsettings.DTO, secretsServic ReqRole: org.RoleEditor, } } - proxy, err := NewPluginProxy(ps, []*plugins.Route{}, ctx, "", cfg, secretsService, tracing.InitializeTracerForTest(), &http.Transport{}, acimpl.ProvideAccessControl(featuremgmt.WithFeatures()), featuremgmt.WithFeatures()) + proxy, err := NewPluginProxy(ps, []*plugins.Route{}, ctx, "", cfg, secretsService, tracing.InitializeTracerForTest(), &http.Transport{}, acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()), featuremgmt.WithFeatures()) require.NoError(t, err) req, err := http.NewRequest(http.MethodGet, "/api/plugin-proxy/grafana-simple-app/api/v4/alerts", nil) diff --git a/pkg/api/plugins_test.go b/pkg/api/plugins_test.go index e47f1ec9bb6..1801f2b315a 100644 --- a/pkg/api/plugins_test.go +++ b/pkg/api/plugins_test.go @@ -34,6 +34,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol/actest" "github.com/grafana/grafana/pkg/services/authn" "github.com/grafana/grafana/pkg/services/authn/authntest" + "github.com/grafana/grafana/pkg/services/authz/zanzana" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/org" @@ -746,7 +747,7 @@ func TestHTTPServer_hasPluginRequestedPermissions(t *testing.T) { } hs.log = logger hs.accesscontrolService = actest.FakeService{} - hs.AccessControl = acimpl.ProvideAccessControl(featuremgmt.WithFeatures()) + hs.AccessControl = acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()) expectedIdentity := &authn.Identity{ OrgID: tt.orgID, diff --git a/pkg/api/user_test.go b/pkg/api/user_test.go index dbaa0f0f848..5e1ec0d112c 100644 --- a/pkg/api/user_test.go +++ b/pkg/api/user_test.go @@ -28,6 +28,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock" "github.com/grafana/grafana/pkg/services/auth/idtest" + "github.com/grafana/grafana/pkg/services/authz/zanzana" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/login" @@ -60,7 +61,7 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) { hs := &HTTPServer{ Cfg: settings, SQLStore: sqlStore, - AccessControl: acimpl.ProvideAccessControl(featuremgmt.WithFeatures()), + AccessControl: acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()), } mockResult := user.SearchUserQueryResult{ diff --git a/pkg/infra/usagestats/service/usage_stats_test.go b/pkg/infra/usagestats/service/usage_stats_test.go index 32d62354caf..b85c9fd3eef 100644 --- a/pkg/infra/usagestats/service/usage_stats_test.go +++ b/pkg/infra/usagestats/service/usage_stats_test.go @@ -23,6 +23,7 @@ import ( "github.com/grafana/grafana/pkg/infra/tracing" "github.com/grafana/grafana/pkg/infra/usagestats" "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" "github.com/grafana/grafana/pkg/setting" @@ -247,7 +248,7 @@ func createService(t *testing.T, sqlStore db.DB, withDB bool) *UsageStats { kvstore.ProvideService(sqlStore), routing.NewRouteRegister(), tracing.InitializeTracerForTest(), - acimpl.ProvideAccessControl(featuremgmt.WithFeatures()), + acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()), supportbundlestest.NewFakeBundleService(), ) diff --git a/pkg/login/social/socialimpl/service_test.go b/pkg/login/social/socialimpl/service_test.go index 1984704104f..374fe6b6ba9 100644 --- a/pkg/login/social/socialimpl/service_test.go +++ b/pkg/login/social/socialimpl/service_test.go @@ -13,6 +13,7 @@ import ( "github.com/grafana/grafana/pkg/login/social" "github.com/grafana/grafana/pkg/login/social/connectors" "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/licensing" secretsfake "github.com/grafana/grafana/pkg/services/secrets/fakes" @@ -67,7 +68,7 @@ func TestSocialService_ProvideService(t *testing.T) { cfg.Raw = iniFile secrets := secretsfake.NewMockService(t) - accessControl := acimpl.ProvideAccessControl(featuremgmt.WithFeatures()) + accessControl := acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()) sqlStore := db.InitTestDB(t) ssoSettingsSvc := ssosettingsimpl.ProvideService( @@ -179,7 +180,7 @@ func TestSocialService_ProvideService_GrafanaComGrafanaNet(t *testing.T) { cfg := setting.NewCfg() secrets := secretsfake.NewMockService(t) - accessControl := acimpl.ProvideAccessControl(featuremgmt.WithFeatures()) + accessControl := acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()) sqlStore := db.InitTestDB(t) ssoSettingsSvc := ssosettingsimpl.ProvideService( diff --git a/pkg/services/accesscontrol/accesscontrol.go b/pkg/services/accesscontrol/accesscontrol.go index 0c2b31efe42..41fe41bd214 100644 --- a/pkg/services/accesscontrol/accesscontrol.go +++ b/pkg/services/accesscontrol/accesscontrol.go @@ -6,15 +6,16 @@ import ( "fmt" "strings" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" + "github.com/grafana/grafana/pkg/apimachinery/identity" "github.com/grafana/grafana/pkg/registry" "github.com/grafana/grafana/pkg/services/authn" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/user" - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/trace" ) var tracer = otel.Tracer("github.com/grafana/grafana/pkg/services/accesscontrol") diff --git a/pkg/services/accesscontrol/acimpl/accesscontrol.go b/pkg/services/accesscontrol/acimpl/accesscontrol.go index fe2d8697972..fb75df4e371 100644 --- a/pkg/services/accesscontrol/acimpl/accesscontrol.go +++ b/pkg/services/accesscontrol/acimpl/accesscontrol.go @@ -3,32 +3,52 @@ package acimpl import ( "context" "errors" + "time" + openfgav1 "github.com/openfga/api/proto/openfga/v1" "github.com/prometheus/client_golang/prometheus" "github.com/grafana/grafana/pkg/apimachinery/identity" "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/infra/metrics" "github.com/grafana/grafana/pkg/services/accesscontrol" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/featuremgmt" ) +var ( + errAccessNotImplemented = errors.New("access control not implemented for resource") +) + var _ accesscontrol.AccessControl = new(AccessControl) -func ProvideAccessControl(features featuremgmt.FeatureToggles) *AccessControl { +func ProvideAccessControl(features featuremgmt.FeatureToggles, zclient zanzana.Client) *AccessControl { logger := log.New("accesscontrol") return &AccessControl{ - features, logger, accesscontrol.NewResolvers(logger), + features, logger, accesscontrol.NewResolvers(logger), zclient, } } +func ProvideAccessControlTest() *AccessControl { + return ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()) +} + type AccessControl struct { features featuremgmt.FeatureToggles log log.Logger resolvers accesscontrol.Resolvers + zclient zanzana.Client } func (a *AccessControl) Evaluate(ctx context.Context, user identity.Requester, evaluator accesscontrol.Evaluator) (bool, error) { + if a.features.IsEnabledGlobally(featuremgmt.FlagZanzana) { + return a.evaluateCompare(ctx, user, evaluator) + } + + return a.evaluate(ctx, user, evaluator) +} + +func (a *AccessControl) evaluate(ctx context.Context, user identity.Requester, evaluator accesscontrol.Evaluator) (bool, error) { timer := prometheus.NewTimer(metrics.MAccessEvaluationsSummary) defer timer.ObserveDuration() metrics.MAccessEvaluationCount.Inc() @@ -66,6 +86,87 @@ func (a *AccessControl) Evaluate(ctx context.Context, user identity.Requester, e return resolvedEvaluator.Evaluate(permissions), nil } +func (a *AccessControl) evaluateZanzana(ctx context.Context, user identity.Requester, evaluator accesscontrol.Evaluator) (bool, error) { + eval, err := evaluator.MutateScopes(ctx, a.resolvers.GetScopeAttributeMutator(user.GetOrgID())) + if err != nil { + if !errors.Is(err, accesscontrol.ErrResolverNotFound) { + return false, err + } + eval = evaluator + } + + return eval.EvaluateCustom(func(action, scope string) (bool, error) { + kind, _, identifier := accesscontrol.SplitScope(scope) + key, ok := zanzana.TranslateToTuple(user.GetUID().String(), action, kind, identifier, user.GetOrgID()) + if !ok { + // unsupported translation + return false, errAccessNotImplemented + } + + res, err := a.zclient.Check(ctx, &openfgav1.CheckRequest{ + TupleKey: &openfgav1.CheckRequestTupleKey{ + User: key.User, + Relation: key.Relation, + Object: key.Object, + }, + }) + + if err != nil { + return false, err + } + + return res.Allowed, nil + }) +} + +type evalResult struct { + runner string + decision bool + err error + duration time.Duration +} + +// evaluateCompare run RBAC and zanzana checks in parallel and then compare result +func (a *AccessControl) evaluateCompare(ctx context.Context, user identity.Requester, evaluator accesscontrol.Evaluator) (bool, error) { + res := make(chan evalResult, 2) + go func() { + start := time.Now() + hasAccess, err := a.evaluateZanzana(ctx, user, evaluator) + res <- evalResult{"zanzana", hasAccess, err, time.Since(start)} + }() + + go func() { + start := time.Now() + hasAccess, err := a.evaluate(ctx, user, evaluator) + res <- evalResult{"grafana", hasAccess, err, time.Since(start)} + }() + first, second := <-res, <-res + close(res) + + if second.runner == "grafana" { + first, second = second, first + } + + if !errors.Is(second.err, errAccessNotImplemented) { + if second.err != nil { + a.log.Error("zanzana evaluation failed", "error", second.err) + } else if first.decision != second.decision { + a.log.Warn( + "zanzana evaluation result does not match grafana", + "grafana_decision", first.decision, + "zanana_decision", second.decision, + "grafana_ms", first.duration, + "zanzana_ms", second.duration, + "eval", evaluator.GoString(), + ) + } else { + a.log.Debug("zanzana evaluation is correct", "grafana_ms", first.duration, "zanzana_ms", second.duration) + } + } + + return first.decision, first.err +} + func (a *AccessControl) RegisterScopeAttributeResolver(prefix string, resolver accesscontrol.ScopeAttributeResolver) { a.resolvers.AddScopeAttributeResolver(prefix, resolver) } diff --git a/pkg/services/accesscontrol/acimpl/accesscontrol_test.go b/pkg/services/accesscontrol/acimpl/accesscontrol_test.go index 9bc60141a14..22f2e5d4858 100644 --- a/pkg/services/accesscontrol/acimpl/accesscontrol_test.go +++ b/pkg/services/accesscontrol/acimpl/accesscontrol_test.go @@ -8,6 +8,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/user" ) @@ -65,7 +66,7 @@ func TestAccessControl_Evaluate(t *testing.T) { for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { - ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures(featuremgmt.FlagAccessActionSets)) + ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures(featuremgmt.FlagAccessActionSets), zanzana.NewNoopClient()) if tt.scopeResolver != nil { ac.RegisterScopeAttributeResolver(tt.resolverPrefix, tt.scopeResolver) diff --git a/pkg/services/accesscontrol/authorize_in_org_test.go b/pkg/services/accesscontrol/authorize_in_org_test.go index f9cc616c73a..47d117766f2 100644 --- a/pkg/services/accesscontrol/authorize_in_org_test.go +++ b/pkg/services/accesscontrol/authorize_in_org_test.go @@ -14,6 +14,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol/actest" "github.com/grafana/grafana/pkg/services/authn" "github.com/grafana/grafana/pkg/services/authn/authntest" + "github.com/grafana/grafana/pkg/services/authz/zanzana" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/team" @@ -24,7 +25,7 @@ import ( ) func TestAuthorizeInOrgMiddleware(t *testing.T) { - ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures()) + ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()) // Define test cases testCases := []struct { diff --git a/pkg/services/accesscontrol/evaluator.go b/pkg/services/accesscontrol/evaluator.go index 4b082e267d4..9a49cc15f0e 100644 --- a/pkg/services/accesscontrol/evaluator.go +++ b/pkg/services/accesscontrol/evaluator.go @@ -11,9 +11,13 @@ import ( var logger = log.New("accesscontrol.evaluator") +type CheckerFn func(action string, scope string) (bool, error) + type Evaluator interface { // Evaluate permissions that are grouped by action Evaluate(permissions map[string][]string) bool + // EvaluateCustom allows to perform evaluation with custom check function + EvaluateCustom(fn CheckerFn) (bool, error) // MutateScopes executes a sequence of ScopeModifier functions on all embedded scopes of an evaluator and returns a new Evaluator MutateScopes(ctx context.Context, mutate ScopeAttributeMutator) (Evaluator, error) // String returns a string representation of permission required by the evaluator @@ -80,6 +84,25 @@ func match(scope, target string) bool { return scope == target } +func (p permissionEvaluator) EvaluateCustom(fn CheckerFn) (bool, error) { + if len(p.Scopes) == 0 { + return fn(p.Action, "") + } + + for _, target := range p.Scopes { + matches, err := fn(p.Action, target) + if err != nil { + return false, err + } + + if matches { + return true, nil + } + } + + return false, nil +} + func (p permissionEvaluator) MutateScopes(ctx context.Context, mutate ScopeAttributeMutator) (Evaluator, error) { if p.Scopes == nil { return EvalPermission(p.Action), nil @@ -135,6 +158,19 @@ func (a allEvaluator) Evaluate(permissions map[string][]string) bool { return true } +func (a allEvaluator) EvaluateCustom(fn CheckerFn) (bool, error) { + for _, e := range a.allOf { + allowed, err := e.EvaluateCustom(fn) + if err != nil { + return false, err + } + if !allowed { + return false, nil + } + } + return true, nil +} + func (a allEvaluator) MutateScopes(ctx context.Context, mutate ScopeAttributeMutator) (Evaluator, error) { resolved := false modified := make([]Evaluator, 0, len(a.allOf)) @@ -195,6 +231,19 @@ func (a anyEvaluator) Evaluate(permissions map[string][]string) bool { return false } +func (a anyEvaluator) EvaluateCustom(fn CheckerFn) (bool, error) { + for _, e := range a.anyOf { + allowed, err := e.EvaluateCustom(fn) + if err != nil { + return false, err + } + if allowed { + return true, nil + } + } + return false, nil +} + func (a anyEvaluator) MutateScopes(ctx context.Context, mutate ScopeAttributeMutator) (Evaluator, error) { resolved := false modified := make([]Evaluator, 0, len(a.anyOf)) diff --git a/pkg/services/accesscontrol/middleware_test.go b/pkg/services/accesscontrol/middleware_test.go index 6374f165a5c..afdb8ef5063 100644 --- a/pkg/services/accesscontrol/middleware_test.go +++ b/pkg/services/accesscontrol/middleware_test.go @@ -10,6 +10,7 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/contexthandler/ctxkey" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" "github.com/grafana/grafana/pkg/services/featuremgmt" @@ -25,7 +26,7 @@ type middlewareTestCase struct { } func TestMiddleware(t *testing.T) { - ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures()) + ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()) tests := []middlewareTestCase{ { @@ -81,7 +82,7 @@ func TestMiddleware_forceLogin(t *testing.T) { {url: "/endpoint"}, } - ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures()) + ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()) for _, tc := range tests { t.Run(tc.url, func(t *testing.T) { diff --git a/pkg/services/accesscontrol/models.go b/pkg/services/accesscontrol/models.go index 7e68c0d8091..bac02e9096c 100644 --- a/pkg/services/accesscontrol/models.go +++ b/pkg/services/accesscontrol/models.go @@ -214,19 +214,7 @@ func (p Permission) OSSPermission() Permission { // SplitScope returns kind, attribute and Identifier func (p Permission) SplitScope() (string, string, string) { - if p.Scope == "" { - return "", "", "" - } - - fragments := strings.Split(p.Scope, ":") - switch l := len(fragments); l { - case 1: // Splitting a wildcard scope "*" -> kind: "*"; attribute: "*"; identifier: "*" - return fragments[0], fragments[0], fragments[0] - case 2: // Splitting a wildcard scope with specified kind "dashboards:*" -> kind: "dashboards"; attribute: "*"; identifier: "*" - return fragments[0], fragments[1], fragments[1] - default: // Splitting a scope with all fields specified "dashboards:uid:my_dash" -> kind: "dashboards"; attribute: "uid"; identifier: "my_dash" - return fragments[0], fragments[1], strings.Join(fragments[2:], ":") - } + return SplitScope(p.Scope) } type GetUserPermissionsQuery struct { diff --git a/pkg/services/accesscontrol/resourcepermissions/service_test.go b/pkg/services/accesscontrol/resourcepermissions/service_test.go index ec208395cb8..039530fe1bf 100644 --- a/pkg/services/accesscontrol/resourcepermissions/service_test.go +++ b/pkg/services/accesscontrol/resourcepermissions/service_test.go @@ -13,6 +13,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" "github.com/grafana/grafana/pkg/services/accesscontrol/actest" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/licensing/licensingtest" "github.com/grafana/grafana/pkg/services/org/orgimpl" @@ -289,7 +290,7 @@ func TestService_RegisterActionSets(t *testing.T) { if tt.actionSetsEnabled { features = featuremgmt.WithFeatures(featuremgmt.FlagAccessActionSets) } - ac := acimpl.ProvideAccessControl(features) + ac := acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()) actionSets := NewActionSetService() _, err := New( setting.NewCfg(), tt.options, features, routing.NewRouteRegister(), licensingtest.NewFakeLicensing(), @@ -335,7 +336,7 @@ func setupTestEnvironment(t *testing.T, ops Options) (*Service, user.Service, te license := licensingtest.NewFakeLicensing() license.On("FeatureEnabled", "accesscontrol.enforcement").Return(true).Maybe() acService := &actest.FakeService{} - ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures()) + ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()) service, err := New( cfg, ops, featuremgmt.WithFeatures(), routing.NewRouteRegister(), license, ac, acService, sql, teamSvc, userSvc, NewActionSetService(), diff --git a/pkg/services/accesscontrol/scope.go b/pkg/services/accesscontrol/scope.go index 4805b25f2a1..367fd2eecfc 100644 --- a/pkg/services/accesscontrol/scope.go +++ b/pkg/services/accesscontrol/scope.go @@ -10,6 +10,23 @@ const ( maxPrefixParts = 2 ) +// SplitScope returns kind, attribute and Identifier +func SplitScope(scope string) (string, string, string) { + if scope == "" { + return "", "", "" + } + + fragments := strings.Split(scope, ":") + switch l := len(fragments); l { + case 1: // Splitting a wildcard scope "*" -> kind: "*"; attribute: "*"; identifier: "*" + return fragments[0], fragments[0], fragments[0] + case 2: // Splitting a wildcard scope with specified kind "dashboards:*" -> kind: "dashboards"; attribute: "*"; identifier: "*" + return fragments[0], fragments[1], fragments[1] + default: // Splitting a scope with all fields specified "dashboards:uid:my_dash" -> kind: "dashboards"; attribute: "uid"; identifier: "my_dash" + return fragments[0], fragments[1], strings.Join(fragments[2:], ":") + } +} + func ParseScopeID(scope string) (int64, error) { id, err := strconv.ParseInt(ScopeSuffix(scope), 10, 64) if err != nil { diff --git a/pkg/services/annotations/annotationsimpl/annotations_test.go b/pkg/services/annotations/annotationsimpl/annotations_test.go index eb603a14664..d98af424ad5 100644 --- a/pkg/services/annotations/annotationsimpl/annotations_test.go +++ b/pkg/services/annotations/annotationsimpl/annotations_test.go @@ -18,6 +18,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" "github.com/grafana/grafana/pkg/services/annotations" "github.com/grafana/grafana/pkg/services/annotations/testutil" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/dashboards" dashboardstore "github.com/grafana/grafana/pkg/services/dashboards/database" "github.com/grafana/grafana/pkg/services/featuremgmt" @@ -225,7 +226,7 @@ func TestIntegrationAnnotationListingWithInheritedRBAC(t *testing.T) { guardian.New = origNewGuardian }) - ac := acimpl.ProvideAccessControl(features) + ac := acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()) folderSvc := folderimpl.ProvideService(ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashStore, folderimpl.ProvideDashboardFolderStore(sql), sql, features, supportbundlestest.NewFakeBundleService(), nil) cfg.AnnotationMaximumTagsLength = 60 diff --git a/pkg/services/correlations/correlationstest/fake.go b/pkg/services/correlations/correlationstest/fake.go index 6263f9db41f..f5f134bf51b 100644 --- a/pkg/services/correlations/correlationstest/fake.go +++ b/pkg/services/correlations/correlationstest/fake.go @@ -5,6 +5,7 @@ import ( "github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/correlations" "github.com/grafana/grafana/pkg/services/datasources" fakeDatasources "github.com/grafana/grafana/pkg/services/datasources/fakes" @@ -20,6 +21,6 @@ func New(db db.DB, cfg *setting.Cfg, bus bus.Bus) *correlations.CorrelationsServ }, } - correlationsSvc, _ := correlations.ProvideService(db, routing.NewRouteRegister(), ds, acimpl.ProvideAccessControl(featuremgmt.WithFeatures()), bus, quotatest.New(false, nil), cfg) + correlationsSvc, _ := correlations.ProvideService(db, routing.NewRouteRegister(), ds, acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()), bus, quotatest.New(false, nil), cfg) return correlationsSvc } diff --git a/pkg/services/dashboards/database/database_test.go b/pkg/services/dashboards/database/database_test.go index f955b99152c..e7050847483 100644 --- a/pkg/services/dashboards/database/database_test.go +++ b/pkg/services/dashboards/database/database_test.go @@ -16,6 +16,7 @@ import ( "github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/infra/tracing" "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/folder" @@ -827,7 +828,7 @@ func TestIntegrationFindDashboardsByTitle(t *testing.T) { orgID := int64(1) insertTestDashboard(t, dashboardStore, "dashboard under general", orgID, 0, "", false) - ac := acimpl.ProvideAccessControl(features) + ac := acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()) folderStore := folderimpl.ProvideDashboardFolderStore(sqlStore) folderServiceWithFlagOn := folderimpl.ProvideService(ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore, folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), nil) @@ -944,7 +945,7 @@ func TestIntegrationFindDashboardsByFolder(t *testing.T) { orgID := int64(1) insertTestDashboard(t, dashboardStore, "dashboard under general", orgID, 0, "", false) - ac := acimpl.ProvideAccessControl(features) + ac := acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()) folderStore := folderimpl.ProvideDashboardFolderStore(sqlStore) folderServiceWithFlagOn := folderimpl.ProvideService(ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore, folderStore, sqlStore, features, supportbundlestest.NewFakeBundleService(), nil) diff --git a/pkg/services/folder/folderimpl/folder_test.go b/pkg/services/folder/folderimpl/folder_test.go index f47d4698769..c3c07dc89c4 100644 --- a/pkg/services/folder/folderimpl/folder_test.go +++ b/pkg/services/folder/folderimpl/folder_test.go @@ -27,6 +27,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" "github.com/grafana/grafana/pkg/services/accesscontrol/actest" acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/dashboards/dashboardaccess" "github.com/grafana/grafana/pkg/services/dashboards/database" @@ -97,7 +98,7 @@ func TestIntegrationFolderService(t *testing.T) { features: features, bus: bus.ProvideBus(tracing.InitializeTracerForTest()), db: db, - accessControl: acimpl.ProvideAccessControl(features), + accessControl: acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()), metrics: newFoldersMetrics(nil), registry: make(map[string]folder.RegistryService), } @@ -427,7 +428,7 @@ func TestIntegrationNestedFolderService(t *testing.T) { nestedFolderStore := ProvideStore(db) b := bus.ProvideBus(tracing.InitializeTracerForTest()) - ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures()) + ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()) serviceWithFlagOn := &Service{ log: slog.New(logtest.NewTestHandler(t)).With("logger", "test-folder-service"), @@ -803,7 +804,7 @@ func TestNestedFolderServiceFeatureToggle(t *testing.T) { dashboardStore: &dashStore, dashboardFolderStore: dashboardFolderStore, features: featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders), - accessControl: acimpl.ProvideAccessControl(featuremgmt.WithFeatures()), + accessControl: acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()), metrics: newFoldersMetrics(nil), } t.Run("create folder", func(t *testing.T) { @@ -839,7 +840,7 @@ func TestFolderServiceDualWrite(t *testing.T) { dashboardStore: dashStore, dashboardFolderStore: dashboardFolderStore, features: featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders), - accessControl: acimpl.ProvideAccessControl(featuremgmt.WithFeatures()), + accessControl: acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()), metrics: newFoldersMetrics(nil), bus: bus.ProvideBus(tracing.InitializeTracerForTest()), } @@ -903,7 +904,7 @@ func TestNestedFolderService(t *testing.T) { features := featuremgmt.WithFeatures() db, _ := sqlstore.InitTestDB(t) - folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, features, acimpl.ProvideAccessControl(features), db) + folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, features, acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()), db) _, err := folderSvc.Create(context.Background(), &folder.CreateFolderCommand{ OrgID: orgID, Title: dash.Title, @@ -937,7 +938,7 @@ func TestNestedFolderService(t *testing.T) { features := featuremgmt.WithFeatures("nestedFolders") db, _ := sqlstore.InitTestDB(t) - folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, features, acimpl.ProvideAccessControl(features), db) + folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, features, acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()), db) _, err := folderSvc.Create(context.Background(), &folder.CreateFolderCommand{ OrgID: orgID, Title: dash.Title, @@ -969,7 +970,7 @@ func TestNestedFolderService(t *testing.T) { dashStore.On("SaveDashboard", mock.Anything, mock.AnythingOfType("dashboards.SaveDashboardCommand")).Return(&dashboards.Dashboard{}, nil) features := featuremgmt.WithFeatures("nestedFolders") - folderSvc := setup(t, dashStore, nil, nil, features, acimpl.ProvideAccessControl(features), dbtest.NewFakeDB()) + folderSvc := setup(t, dashStore, nil, nil, features, acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()), dbtest.NewFakeDB()) _, err := folderSvc.Create(context.Background(), &folder.CreateFolderCommand{ OrgID: orgID, Title: dash.Title, @@ -1005,7 +1006,7 @@ func TestNestedFolderService(t *testing.T) { nestedFolderStore := NewFakeStore() db, _ := sqlstore.InitTestDB(t) features := featuremgmt.WithFeatures("nestedFolders") - folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, features, acimpl.ProvideAccessControl(features), db) + folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, features, acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()), db) _, err := folderSvc.Create(context.Background(), &folder.CreateFolderCommand{ OrgID: orgID, Title: dash.Title, @@ -1141,7 +1142,7 @@ func TestNestedFolderService(t *testing.T) { nestedFolderUser.Permissions[orgID] = map[string][]string{dashboards.ActionFoldersWrite: {dashboards.ScopeFoldersProvider.GetResourceScopeUID("wrong_uid")}} features := featuremgmt.WithFeatures("nestedFolders") - folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, features, acimpl.ProvideAccessControl(features), dbtest.NewFakeDB()) + folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, features, acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()), dbtest.NewFakeDB()) _, err := folderSvc.Move(context.Background(), &folder.MoveFolderCommand{UID: "myFolder", NewParentUID: "newFolder", OrgID: orgID, SignedInUser: nestedFolderUser}) require.ErrorIs(t, err, dashboards.ErrFolderAccessDenied) }) @@ -1162,7 +1163,7 @@ func TestNestedFolderService(t *testing.T) { nestedFolderUser.Permissions[orgID] = map[string][]string{dashboards.ActionFoldersWrite: {dashboards.ScopeFoldersProvider.GetResourceScopeUID("newFolder")}} features := featuremgmt.WithFeatures("nestedFolders") - folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, features, acimpl.ProvideAccessControl(features), dbtest.NewFakeDB()) + folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, features, acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()), dbtest.NewFakeDB()) _, err := folderSvc.Move(context.Background(), &folder.MoveFolderCommand{UID: "myFolder", NewParentUID: "newFolder", OrgID: orgID, SignedInUser: nestedFolderUser}) require.NoError(t, err) // the folder is set inside InTransaction() but the fake one is called @@ -1174,7 +1175,7 @@ func TestNestedFolderService(t *testing.T) { nestedFolderUser.Permissions[orgID] = map[string][]string{dashboards.ActionFoldersWrite: {dashboards.ScopeFoldersProvider.GetResourceAllScope()}} features := featuremgmt.WithFeatures("nestedFolders") - folderSvc := setup(t, &dashboards.FakeDashboardStore{}, foldertest.NewFakeFolderStore(t), NewFakeStore(), features, acimpl.ProvideAccessControl(features), dbtest.NewFakeDB()) + folderSvc := setup(t, &dashboards.FakeDashboardStore{}, foldertest.NewFakeFolderStore(t), NewFakeStore(), features, acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()), dbtest.NewFakeDB()) _, err := folderSvc.Move(context.Background(), &folder.MoveFolderCommand{UID: accesscontrol.K6FolderUID, NewParentUID: "newFolder", OrgID: orgID, SignedInUser: nestedFolderUser}) require.Error(t, err, folder.ErrBadRequest) }) @@ -1192,7 +1193,7 @@ func TestNestedFolderService(t *testing.T) { } features := featuremgmt.WithFeatures("nestedFolders") - folderSvc := setup(t, &dashboards.FakeDashboardStore{}, foldertest.NewFakeFolderStore(t), nestedFolderStore, features, acimpl.ProvideAccessControl(features), dbtest.NewFakeDB()) + folderSvc := setup(t, &dashboards.FakeDashboardStore{}, foldertest.NewFakeFolderStore(t), nestedFolderStore, features, acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()), dbtest.NewFakeDB()) _, err := folderSvc.Move(context.Background(), &folder.MoveFolderCommand{UID: childUID, NewParentUID: "newFolder", OrgID: orgID, SignedInUser: nestedFolderUser}) require.Error(t, err, folder.ErrBadRequest) }) @@ -1208,7 +1209,7 @@ func TestNestedFolderService(t *testing.T) { nestedFolderUser.Permissions[orgID] = map[string][]string{dashboards.ActionFoldersWrite: {dashboards.ScopeFoldersProvider.GetResourceScopeUID("")}} features := featuremgmt.WithFeatures("nestedFolders") - folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, features, acimpl.ProvideAccessControl(features), dbtest.NewFakeDB()) + folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, features, acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()), dbtest.NewFakeDB()) _, err := folderSvc.Move(context.Background(), &folder.MoveFolderCommand{UID: "myFolder", NewParentUID: "", OrgID: orgID, SignedInUser: nestedFolderUser}) require.Error(t, err, dashboards.ErrFolderAccessDenied) }) @@ -1229,7 +1230,7 @@ func TestNestedFolderService(t *testing.T) { nestedFolderUser.Permissions[orgID] = map[string][]string{dashboards.ActionFoldersCreate: {}} features := featuremgmt.WithFeatures("nestedFolders") - folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, features, acimpl.ProvideAccessControl(features), dbtest.NewFakeDB()) + folderSvc := setup(t, dashStore, dashboardFolderStore, nestedFolderStore, features, acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()), dbtest.NewFakeDB()) _, err := folderSvc.Move(context.Background(), &folder.MoveFolderCommand{UID: "myFolder", NewParentUID: "", OrgID: orgID, SignedInUser: nestedFolderUser}) require.NoError(t, err) // the folder is set inside InTransaction() but the fake one is called @@ -1387,7 +1388,7 @@ func TestIntegrationNestedFolderSharedWithMe(t *testing.T) { nestedFolderStore := ProvideStore(db) b := bus.ProvideBus(tracing.InitializeTracerForTest()) - ac := acimpl.ProvideAccessControl(featuresFlagOn) + ac := acimpl.ProvideAccessControl(featuresFlagOn, zanzana.NewNoopClient()) serviceWithFlagOn := &Service{ log: slog.New(logtest.NewTestHandler(t)).With("logger", "test-folder-service"), @@ -1807,7 +1808,7 @@ func TestFolderServiceGetFolder(t *testing.T) { nestedFolderStore := ProvideStore(db) b := bus.ProvideBus(tracing.InitializeTracerForTest()) - ac := acimpl.ProvideAccessControl(featuresFlagOff) + ac := acimpl.ProvideAccessControl(featuresFlagOff, zanzana.NewNoopClient()) return Service{ log: slog.New(logtest.NewTestHandler(t)).With("logger", "test-folder-service"), @@ -1889,7 +1890,7 @@ func TestFolderServiceGetFolders(t *testing.T) { nestedFolderStore := ProvideStore(db) b := bus.ProvideBus(tracing.InitializeTracerForTest()) - ac := acimpl.ProvideAccessControl(featuresFlagOff) + ac := acimpl.ProvideAccessControl(featuresFlagOff, zanzana.NewNoopClient()) serviceWithFlagOff := &Service{ log: slog.New(logtest.NewTestHandler(t)).With("logger", "test-folder-service"), @@ -1973,7 +1974,7 @@ func TestGetChildrenFilterByPermission(t *testing.T) { nestedFolderStore := ProvideStore(db) b := bus.ProvideBus(tracing.InitializeTracerForTest()) - ac := acimpl.ProvideAccessControl(featuresFlagOff) + ac := acimpl.ProvideAccessControl(featuresFlagOff, zanzana.NewNoopClient()) features := featuremgmt.WithFeatures(featuremgmt.FlagNestedFolders) diff --git a/pkg/services/guardian/accesscontrol_guardian_test.go b/pkg/services/guardian/accesscontrol_guardian_test.go index 8d24b282395..ae6aaf279b7 100644 --- a/pkg/services/guardian/accesscontrol_guardian_test.go +++ b/pkg/services/guardian/accesscontrol_guardian_test.go @@ -11,6 +11,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/folder/foldertest" @@ -956,7 +957,7 @@ func setupAccessControlGuardianTest( fakeDashboardService := dashboards.NewFakeDashboardService(t) fakeDashboardService.On("GetDashboard", mock.Anything, mock.AnythingOfType("*dashboards.GetDashboardQuery")).Maybe().Return(d, nil) - ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures()) + ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()) folderSvc := foldertest.NewFakeService() folderStore := foldertest.NewFakeFolderStore(t) diff --git a/pkg/services/ldap/api/service_test.go b/pkg/services/ldap/api/service_test.go index 0e8ddc3c3dc..c3147819d1f 100644 --- a/pkg/services/ldap/api/service_test.go +++ b/pkg/services/ldap/api/service_test.go @@ -17,6 +17,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" "github.com/grafana/grafana/pkg/services/auth/authtest" "github.com/grafana/grafana/pkg/services/authn/authntest" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/ldap" "github.com/grafana/grafana/pkg/services/ldap/multildap" @@ -67,7 +68,7 @@ func setupAPITest(t *testing.T, opts ...func(a *Service)) (*Service, *webtest.Se a := ProvideService(cfg, router, - acimpl.ProvideAccessControl(featuremgmt.WithFeatures()), + acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()), usertest.NewUserServiceFake(), &authinfotest.FakeService{}, ldap.ProvideGroupsService(), diff --git a/pkg/services/libraryelements/libraryelements_test.go b/pkg/services/libraryelements/libraryelements_test.go index 133443f7264..bf82e13b3c8 100644 --- a/pkg/services/libraryelements/libraryelements_test.go +++ b/pkg/services/libraryelements/libraryelements_test.go @@ -25,6 +25,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" "github.com/grafana/grafana/pkg/services/accesscontrol/actest" acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock" + "github.com/grafana/grafana/pkg/services/authz/zanzana" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/dashboards/database" @@ -444,7 +445,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo quotaService := quotatest.New(false, nil) dashboardStore, err := database.ProvideDashboardStore(sqlStore, cfg, features, tagimpl.ProvideService(sqlStore), quotaService) require.NoError(t, err) - ac := acimpl.ProvideAccessControl(features) + ac := acimpl.ProvideAccessControl(features, zanzana.NewNoopClient()) folderPermissions := acmock.NewMockedPermissionsService() folderPermissions.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil) dashboardPermissions := acmock.NewMockedPermissionsService() diff --git a/pkg/services/live/live_test.go b/pkg/services/live/live_test.go index 447910e1b84..427a6abf2aa 100644 --- a/pkg/services/live/live_test.go +++ b/pkg/services/live/live_test.go @@ -14,6 +14,7 @@ import ( "github.com/grafana/grafana/pkg/infra/usagestats" "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" "github.com/grafana/grafana/pkg/services/annotations/annotationstest" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/setting" @@ -36,7 +37,7 @@ func Test_provideLiveService_RedisUnavailable(t *testing.T) { nil, &usagestats.UsageStatsMock{T: t}, nil, - featuremgmt.WithFeatures(), acimpl.ProvideAccessControl(featuremgmt.WithFeatures()), &dashboards.FakeDashboardService{}, annotationstest.NewFakeAnnotationsRepo(), nil) + featuremgmt.WithFeatures(), acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()), &dashboards.FakeDashboardService{}, annotationstest.NewFakeAnnotationsRepo(), nil) // Proceeds without live HA if redis is unavaialble require.NoError(t, err) diff --git a/pkg/services/navtree/navtreeimpl/applinks_test.go b/pkg/services/navtree/navtreeimpl/applinks_test.go index 0b87ea27064..eeba3af0445 100644 --- a/pkg/services/navtree/navtreeimpl/applinks_test.go +++ b/pkg/services/navtree/navtreeimpl/applinks_test.go @@ -12,6 +12,7 @@ import ( ac "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock" + "github.com/grafana/grafana/pkg/services/authz/zanzana" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" "github.com/grafana/grafana/pkg/services/datasources" "github.com/grafana/grafana/pkg/services/featuremgmt" @@ -434,7 +435,7 @@ func TestAddAppLinksAccessControl(t *testing.T) { service := ServiceImpl{ log: log.New("navtree"), cfg: cfg, - accessControl: acimpl.ProvideAccessControl(featuremgmt.WithFeatures()), + accessControl: acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()), pluginSettings: &pluginSettings, features: featuremgmt.WithFeatures(), pluginStore: &pluginstore.FakePluginStore{ diff --git a/pkg/services/ngalert/api/api_alertmanager_test.go b/pkg/services/ngalert/api/api_alertmanager_test.go index 52def62fa93..d025bd86796 100644 --- a/pkg/services/ngalert/api/api_alertmanager_test.go +++ b/pkg/services/ngalert/api/api_alertmanager_test.go @@ -15,6 +15,8 @@ import ( "github.com/stretchr/testify/require" alertingNotify "github.com/grafana/alerting/notify" + + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/ngalert/accesscontrol" "github.com/grafana/grafana/pkg/api/response" @@ -631,9 +633,9 @@ func createSut(t *testing.T) AlertmanagerSrv { } mam := createMultiOrgAlertmanager(t, configs) log := log.NewNopLogger() - ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures()) + ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()) ruleStore := ngfakes.NewRuleStore(t) - ruleAuthzService := accesscontrol.NewRuleService(acimpl.ProvideAccessControl(featuremgmt.WithFeatures())) + ruleAuthzService := accesscontrol.NewRuleService(acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient())) return AlertmanagerSrv{ mam: mam, crypto: mam.Crypto, diff --git a/pkg/services/ngalert/api/api_prometheus_test.go b/pkg/services/ngalert/api/api_prometheus_test.go index 1f28c685ef7..a7fd8016472 100644 --- a/pkg/services/ngalert/api/api_prometheus_test.go +++ b/pkg/services/ngalert/api/api_prometheus_test.go @@ -14,11 +14,13 @@ import ( "github.com/stretchr/testify/require" alertingModels "github.com/grafana/alerting/models" + "github.com/grafana/grafana-plugin-sdk-go/data" "github.com/grafana/grafana/pkg/expr" "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" + "github.com/grafana/grafana/pkg/services/authz/zanzana" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" "github.com/grafana/grafana/pkg/services/datasources" "github.com/grafana/grafana/pkg/services/featuremgmt" @@ -558,7 +560,7 @@ func TestRouteGetRuleStatuses(t *testing.T) { log: log.NewNopLogger(), manager: fakeAIM, store: ruleStore, - authz: accesscontrol.NewRuleService(acimpl.ProvideAccessControl(featuremgmt.WithFeatures())), + authz: accesscontrol.NewRuleService(acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient())), } permissions := createPermissionsForRules(slices.Concat(rulesInGroup1, rulesInGroup2, rulesInGroup3), orgID) @@ -673,7 +675,7 @@ func TestRouteGetRuleStatuses(t *testing.T) { log: log.NewNopLogger(), manager: fakeAIM, store: ruleStore, - authz: accesscontrol.NewRuleService(acimpl.ProvideAccessControl(featuremgmt.WithFeatures())), + authz: accesscontrol.NewRuleService(acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient())), } c := &contextmodel.ReqContext{Context: &web.Context{Req: req}, SignedInUser: &user.SignedInUser{OrgID: orgID, Permissions: createPermissionsForRules(rules, orgID)}} diff --git a/pkg/services/ngalert/api/api_ruler_test.go b/pkg/services/ngalert/api/api_ruler_test.go index 2b675426b2b..e1ae7815bb2 100644 --- a/pkg/services/ngalert/api/api_ruler_test.go +++ b/pkg/services/ngalert/api/api_ruler_test.go @@ -20,6 +20,7 @@ import ( "github.com/grafana/grafana/pkg/infra/log" ac "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" + "github.com/grafana/grafana/pkg/services/authz/zanzana" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/datasources" @@ -649,7 +650,7 @@ func createService(store *fakes.RuleStore) *RulerSrv { cfg: &setting.UnifiedAlertingSettings{ BaseInterval: 10 * time.Second, }, - authz: accesscontrol.NewRuleService(acimpl.ProvideAccessControl(featuremgmt.WithFeatures())), + authz: accesscontrol.NewRuleService(acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient())), amConfigStore: &fakeAMRefresher{}, amRefresher: &fakeAMRefresher{}, featureManager: featuremgmt.WithFeatures(), diff --git a/pkg/services/ngalert/notifier/receiver_svc_test.go b/pkg/services/ngalert/notifier/receiver_svc_test.go index 862bc75e060..da367d576f1 100644 --- a/pkg/services/ngalert/notifier/receiver_svc_test.go +++ b/pkg/services/ngalert/notifier/receiver_svc_test.go @@ -6,12 +6,15 @@ import ( "fmt" "testing" + "github.com/stretchr/testify/require" + "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" "github.com/grafana/grafana/pkg/services/accesscontrol/actest" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" "github.com/grafana/grafana/pkg/services/ngalert/models" @@ -20,7 +23,6 @@ import ( "github.com/grafana/grafana/pkg/services/secrets/database" "github.com/grafana/grafana/pkg/services/secrets/manager" "github.com/grafana/grafana/pkg/services/user" - "github.com/stretchr/testify/require" ) func TestReceiverService_GetReceiver(t *testing.T) { @@ -72,7 +74,7 @@ func TestReceiverService_GetReceivers(t *testing.T) { func TestReceiverService_DecryptRedact(t *testing.T) { sqlStore := db.InitTestDB(t) secretsService := manager.SetupTestService(t, database.ProvideSecretsStore(sqlStore)) - ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures()) + ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()) getMethods := []string{"single", "multi"} diff --git a/pkg/services/ngalert/provisioning/contactpoints_test.go b/pkg/services/ngalert/provisioning/contactpoints_test.go index 016e2552acd..b07dcc80237 100644 --- a/pkg/services/ngalert/provisioning/contactpoints_test.go +++ b/pkg/services/ngalert/provisioning/contactpoints_test.go @@ -17,6 +17,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" "github.com/grafana/grafana/pkg/services/accesscontrol/actest" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" "github.com/grafana/grafana/pkg/services/ngalert/models" @@ -261,7 +262,7 @@ func TestContactPointServiceDecryptRedact(t *testing.T) { secretsService := manager.SetupTestService(t, database.ProvideSecretsStore(db.InitTestDB(t))) receiverServiceWithAC := func(ecp *ContactPointService) *notifier.ReceiverService { return notifier.NewReceiverService( - acimpl.ProvideAccessControl(featuremgmt.WithFeatures()), + acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()), // Get won't use the sut's config store, so we can use a different one here. fakes.NewFakeAlertmanagerConfigStore(createEncryptedConfig(t, secretsService)), ecp.provenanceStore, diff --git a/pkg/services/publicdashboards/api/common_test.go b/pkg/services/publicdashboards/api/common_test.go index bc70087a0ff..4c02be71c97 100644 --- a/pkg/services/publicdashboards/api/common_test.go +++ b/pkg/services/publicdashboards/api/common_test.go @@ -7,9 +7,10 @@ import ( "net/http/httptest" "testing" + "github.com/stretchr/testify/require" + "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/data" - "github.com/stretchr/testify/require" "github.com/grafana/grafana/pkg/api/routing" "github.com/grafana/grafana/pkg/infra/db" @@ -17,6 +18,7 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/contexthandler/ctxkey" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" "github.com/grafana/grafana/pkg/services/datasources" @@ -55,7 +57,7 @@ func setupTestServer( // build router to register routes rr := routing.NewRouteRegister() - ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures()) + ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()) // build mux m := web.New() diff --git a/pkg/services/publicdashboards/service/service_test.go b/pkg/services/publicdashboards/service/service_test.go index 30c662ed04a..fa28eed134c 100644 --- a/pkg/services/publicdashboards/service/service_test.go +++ b/pkg/services/publicdashboards/service/service_test.go @@ -18,6 +18,7 @@ import ( "github.com/grafana/grafana/pkg/apimachinery/errutil" "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/dashboards" dashboardsDB "github.com/grafana/grafana/pkg/services/dashboards/database" "github.com/grafana/grafana/pkg/services/featuremgmt" @@ -1482,7 +1483,7 @@ func TestPublicDashboardServiceImpl_ListPublicDashboards(t *testing.T) { }, } - ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures()) + ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()) for _, tt := range testCases { t.Run(tt.name, func(t *testing.T) { diff --git a/pkg/services/quota/quotaimpl/quota_test.go b/pkg/services/quota/quotaimpl/quota_test.go index e24082e5ffb..e74347c1ed9 100644 --- a/pkg/services/quota/quotaimpl/quota_test.go +++ b/pkg/services/quota/quotaimpl/quota_test.go @@ -22,6 +22,7 @@ import ( "github.com/grafana/grafana/pkg/services/apikey/apikeyimpl" "github.com/grafana/grafana/pkg/services/auth" "github.com/grafana/grafana/pkg/services/auth/authimpl" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/dashboards" dashboardStore "github.com/grafana/grafana/pkg/services/dashboards/database" "github.com/grafana/grafana/pkg/services/datasources" @@ -494,7 +495,7 @@ func setupEnv(t *testing.T, sqlStore db.DB, cfg *setting.Cfg, b bus.Bus, quotaSe require.NoError(t, err) m := metrics.NewNGAlert(prometheus.NewRegistry()) - ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures()) + ac := acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()) ruleStore, err := ngstore.ProvideDBStore(cfg, featuremgmt.WithFeatures(), sqlStore, &foldertest.FakeService{}, &dashboards.FakeDashboardService{}, ac) require.NoError(t, err) _, err = ngalert.ProvideService( diff --git a/pkg/services/serviceaccounts/api/api_test.go b/pkg/services/serviceaccounts/api/api_test.go index 144869b390a..03713c57e2a 100644 --- a/pkg/services/serviceaccounts/api/api_test.go +++ b/pkg/services/serviceaccounts/api/api_test.go @@ -16,6 +16,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" "github.com/grafana/grafana/pkg/services/accesscontrol/actest" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/serviceaccounts" @@ -306,7 +307,7 @@ func setupTests(t *testing.T, opts ...func(a *ServiceAccountsAPI)) *webtest.Serv cfg: cfg, service: &satests.FakeServiceAccountService{}, accesscontrolService: &actest.FakeService{}, - accesscontrol: acimpl.ProvideAccessControl(featuremgmt.WithFeatures()), + accesscontrol: acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()), RouterRegister: routing.NewRouteRegister(), log: log.NewNopLogger(), permissionService: &actest.FakePermissionsService{}, diff --git a/pkg/services/ssosettings/api/api_test.go b/pkg/services/ssosettings/api/api_test.go index 9084d4d3155..c70dbd36165 100644 --- a/pkg/services/ssosettings/api/api_test.go +++ b/pkg/services/ssosettings/api/api_test.go @@ -19,6 +19,7 @@ import ( "github.com/grafana/grafana/pkg/login/social" "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/ssosettings" @@ -564,7 +565,7 @@ func setupTests(t *testing.T, service ssosettings.Service) *webtest.Server { api := &Api{ Log: logger, RouteRegister: routing.NewRouteRegister(), - AccessControl: acimpl.ProvideAccessControl(featuremgmt.WithFeatures()), + AccessControl: acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()), SSOSettingsService: service, } diff --git a/pkg/services/ssosettings/ssosettingsimpl/service_test.go b/pkg/services/ssosettings/ssosettingsimpl/service_test.go index 7aa812f3f2a..cabf5dfe719 100644 --- a/pkg/services/ssosettings/ssosettingsimpl/service_test.go +++ b/pkg/services/ssosettings/ssosettingsimpl/service_test.go @@ -21,6 +21,7 @@ import ( "github.com/grafana/grafana/pkg/login/social" "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/licensing/licensingtest" secretsFakes "github.com/grafana/grafana/pkg/services/secrets/fakes" @@ -1858,7 +1859,7 @@ func setupTestEnv(t *testing.T, isLicensingEnabled, keepFallbackStratergies, sam store := ssosettingstests.NewFakeStore() fallbackStrategy := ssosettingstests.NewFakeFallbackStrategy() secrets := secretsFakes.NewMockService(t) - accessControl := acimpl.ProvideAccessControl(featuremgmt.WithFeatures()) + accessControl := acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()) reloadables := make(map[string]ssosettings.Reloadable) fallbackStrategy.ExpectedIsMatch = true diff --git a/pkg/services/store/testdata/public_testdata.golden.jsonc b/pkg/services/store/testdata/public_testdata.golden.jsonc index 88d0760e029..a37239596c2 100644 --- a/pkg/services/store/testdata/public_testdata.golden.jsonc +++ b/pkg/services/store/testdata/public_testdata.golden.jsonc @@ -1,5 +1,5 @@ // 🌟 This was machine generated. Do not edit. 🌟 -// +// // Frame[0] { // "type": "directory-listing", // "typeVersion": [ @@ -10,7 +10,7 @@ // "HasMore": false // } // } -// Name: +// Name: // Dimensions: 3 Fields by 3 Rows // +----------------------------+----------------------+---------------+ // | Name: name | Name: mediaType | Name: size | @@ -21,8 +21,8 @@ // | example-with-style.geojson | application/geo+json | 3332 | // | usa-states.geojson | application/geo+json | 89263 | // +----------------------------+----------------------+---------------+ -// -// +// +// // 🌟 This was machine generated. Do not edit. 🌟 { "status": 200, diff --git a/pkg/services/team/teamapi/team_members_test.go b/pkg/services/team/teamapi/team_members_test.go index 9fba37925fa..c3eb3d2f639 100644 --- a/pkg/services/team/teamapi/team_members_test.go +++ b/pkg/services/team/teamapi/team_members_test.go @@ -14,6 +14,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" "github.com/grafana/grafana/pkg/services/accesscontrol/actest" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/dashboards/dashboardaccess" "github.com/grafana/grafana/pkg/services/featuremgmt" @@ -37,7 +38,7 @@ func SetupAPITestServer(t *testing.T, opts ...func(a *TeamAPI)) *webtest.Server a := ProvideTeamAPI(router, teamtest.NewFakeService(), actest.FakeService{}, - acimpl.ProvideAccessControl(featuremgmt.WithFeatures()), + acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()), &actest.FakePermissionsService{}, &usertest.FakeUserService{}, &licensing.OSSLicensingService{}, @@ -259,7 +260,7 @@ func Test_getTeamMembershipUpdates(t *testing.T) { tapi := ProvideTeamAPI(routing.NewRouteRegister(), teamSvc, actest.FakeService{}, - acimpl.ProvideAccessControl(featuremgmt.WithFeatures()), + acimpl.ProvideAccessControl(featuremgmt.WithFeatures(), zanzana.NewNoopClient()), &actest.FakePermissionsService{}, userService, &licensing.OSSLicensingService{}, diff --git a/pkg/tests/apis/alerting/notifications/timeinterval/timeinterval_test.go b/pkg/tests/apis/alerting/notifications/timeinterval/timeinterval_test.go index c8141cbcdee..a7312545c2d 100644 --- a/pkg/tests/apis/alerting/notifications/timeinterval/timeinterval_test.go +++ b/pkg/tests/apis/alerting/notifications/timeinterval/timeinterval_test.go @@ -17,6 +17,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/accesscontrol/acimpl" "github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions" + "github.com/grafana/grafana/pkg/services/authz/zanzana" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/folder/foldertest" @@ -348,7 +349,7 @@ func TestIntegrationTimeIntervalProvisioning(t *testing.T) { adminClient := adminK8sClient.NotificationsV0alpha1().TimeIntervals("default") env := helper.GetEnv() - ac := acimpl.ProvideAccessControl(env.FeatureToggles) + ac := acimpl.ProvideAccessControl(env.FeatureToggles, zanzana.NewNoopClient()) db, err := store.ProvideDBStore(env.Cfg, env.FeatureToggles, env.SQLStore, &foldertest.FakeService{}, &dashboards.FakeDashboardService{}, ac) require.NoError(t, err)