diff --git a/pkg/middleware/auth.go b/pkg/middleware/auth.go index f013d9d2bfa..719d2ab5cb5 100644 --- a/pkg/middleware/auth.go +++ b/pkg/middleware/auth.go @@ -1,7 +1,6 @@ package middleware import ( - "context" "errors" "net/http" "net/url" @@ -22,13 +21,6 @@ import ( "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/web" - "github.com/open-feature/go-sdk/openfeature" -) - -var openfeatureClient = openfeature.NewDefaultClient() - -const ( - pluginPageFeatureFlagPrefix = "plugin-page-visible." ) type AuthOptions struct { @@ -154,12 +146,6 @@ func RoleAppPluginAuth(accessControl ac.AccessControl, ps pluginstore.Store, log return } - if !PageIsFeatureToggleEnabled(c.Req.Context(), c.Req.URL.Path) { - logger.Debug("Forbidden experimental plugin page", "plugin", pluginID, "path", c.Req.URL.Path) - accessForbidden(c) - return - } - permitted := true path := normalizeIncludePath(c.Req.URL.Path) hasAccess := ac.HasAccess(accessControl, c) @@ -308,18 +294,3 @@ func shouldForceLogin(c *contextmodel.ReqContext) bool { return forceLogin } - -// PageIsFeatureToggleEnabled checks if a page is enabled via OpenFeature feature flags. -// It returns false if the feature flag is set and set to false. -// The feature flag key format is: "plugin-page-visible." -func PageIsFeatureToggleEnabled(ctx context.Context, path string) bool { - flagKey := pluginPageFeatureFlagPrefix + filepath.Clean(path) - enabled := openfeatureClient.Boolean( - ctx, - flagKey, - true, - openfeature.TransactionContext(ctx), - ) - - return enabled -} diff --git a/pkg/middleware/auth_test.go b/pkg/middleware/auth_test.go index 19a7d68559e..fdca1d04ee3 100644 --- a/pkg/middleware/auth_test.go +++ b/pkg/middleware/auth_test.go @@ -1,17 +1,12 @@ package middleware import ( - "context" "errors" "fmt" "net/http" "net/http/httptest" - "sync" "testing" - "github.com/open-feature/go-sdk/openfeature" - "github.com/open-feature/go-sdk/openfeature/memprovider" - oftesting "github.com/open-feature/go-sdk/openfeature/testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -33,8 +28,6 @@ import ( "github.com/grafana/grafana/pkg/web" ) -var openfeatureTestMutex sync.Mutex - func setupAuthMiddlewareTest(t *testing.T, identity *authn.Identity, authErr error) *contexthandler.ContextHandler { return contexthandler.ProvideService(setting.NewCfg(), &authntest.FakeService{ ExpectedErr: authErr, @@ -429,60 +422,6 @@ func TestCanAdminPlugin(t *testing.T) { } } -func TestPageIsFeatureToggleEnabled(t *testing.T) { - type testCase struct { - desc string - path string - flags map[string]bool - expectedResult bool - } - - tests := []testCase{ - { - desc: "returns true when feature flag is enabled", - path: "/a/my-plugin/settings", - flags: map[string]bool{ - pluginPageFeatureFlagPrefix + "/a/my-plugin/settings": true, - }, - expectedResult: true, - }, - { - desc: "returns false when feature flag is disabled", - path: "/a/my-plugin/settings", - flags: map[string]bool{ - pluginPageFeatureFlagPrefix + "/a/my-plugin/settings": false, - }, - expectedResult: false, - }, - { - desc: "returns false when feature flag is disabled with trailing slash", - path: "/a/my-plugin/settings/", - flags: map[string]bool{ - pluginPageFeatureFlagPrefix + "/a/my-plugin/settings": false, - }, - expectedResult: false, - }, - { - desc: "returns true when feature flag does not exist", - path: "/a/my-plugin/settings", - flags: map[string]bool{}, - expectedResult: true, - }, - } - - for _, tt := range tests { - t.Run(tt.desc, func(t *testing.T) { - ctx := context.Background() - - setupTestProvider(t, tt.flags) - - result := PageIsFeatureToggleEnabled(ctx, tt.path) - - assert.Equal(t, tt.expectedResult, result) - }) - } -} - func contextProvider(modifiers ...func(c *contextmodel.ReqContext)) web.Handler { return func(c *web.Context) { reqCtx := &contextmodel.ReqContext{ @@ -498,38 +437,3 @@ func contextProvider(modifiers ...func(c *contextmodel.ReqContext)) web.Handler c.Req = c.Req.WithContext(ctxkey.Set(c.Req.Context(), reqCtx)) } } - -// setupTestProvider creates a test OpenFeature provider with the given flags. -// Uses a global lock to prevent concurrent provider changes across tests. -func setupTestProvider(t *testing.T, flags map[string]bool) oftesting.TestProvider { - t.Helper() - - // Lock to prevent concurrent provider changes - openfeatureTestMutex.Lock() - - testProvider := oftesting.NewTestProvider() - flagsMap := map[string]memprovider.InMemoryFlag{} - - for key, value := range flags { - flagsMap[key] = memprovider.InMemoryFlag{ - DefaultVariant: "defaultVariant", - Variants: map[string]any{ - "defaultVariant": value, - }, - } - } - - testProvider.UsingFlags(t, flagsMap) - - err := openfeature.SetProviderAndWait(testProvider) - require.NoError(t, err) - - t.Cleanup(func() { - testProvider.Cleanup() - _ = openfeature.SetProviderAndWait(openfeature.NoopProvider{}) - // Unlock after cleanup to allow other tests to run - openfeatureTestMutex.Unlock() - }) - - return testProvider -} diff --git a/pkg/services/navtree/navtreeimpl/applinks.go b/pkg/services/navtree/navtreeimpl/applinks.go index 0b03357b5a8..e061b71e684 100644 --- a/pkg/services/navtree/navtreeimpl/applinks.go +++ b/pkg/services/navtree/navtreeimpl/applinks.go @@ -6,7 +6,6 @@ import ( "strconv" "strings" - "github.com/grafana/grafana/pkg/middleware" "github.com/grafana/grafana/pkg/plugins" ac "github.com/grafana/grafana/pkg/services/accesscontrol" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" @@ -129,10 +128,6 @@ func (s *ServiceImpl) processAppPlugin(plugin pluginstore.Plugin, c *contextmode } if include.Type == "page" { - if !middleware.PageIsFeatureToggleEnabled(c.Req.Context(), include.Path) { - s.log.Debug("Skipping page", "plugin", plugin.ID, "path", include.Path) - continue - } link := &navtree.NavLink{ Text: include.Name, Icon: include.Icon,