FeatureToggles: Add context and and an explicit global check (#78081)
This commit is contained in:
+9
-9
@@ -108,13 +108,13 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
r.Get("/admin/orgs/edit/:id", authorizeInOrg(ac.UseGlobalOrg, ac.OrgsAccessEvaluator), hs.Index)
|
||||
r.Get("/admin/stats", authorize(ac.EvalPermission(ac.ActionServerStatsRead)), hs.Index)
|
||||
r.Get("/admin/authentication/ldap", authorize(ac.EvalPermission(ac.ActionLDAPStatusRead)), hs.Index)
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagStorage) {
|
||||
if hs.Features.IsEnabledGlobally(featuremgmt.FlagStorage) {
|
||||
r.Get("/admin/storage", reqSignedIn, hs.Index)
|
||||
r.Get("/admin/storage/*", reqSignedIn, hs.Index)
|
||||
}
|
||||
|
||||
// feature toggle admin page
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagFeatureToggleAdminPage) {
|
||||
if hs.Features.IsEnabledGlobally(featuremgmt.FlagFeatureToggleAdminPage) {
|
||||
r.Get("/admin/featuretoggles", authorize(ac.EvalPermission(ac.ActionFeatureManagementRead)), hs.Index)
|
||||
}
|
||||
|
||||
@@ -156,11 +156,11 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
r.Get("/dashboards/*", reqSignedIn, hs.Index)
|
||||
r.Get("/goto/:uid", reqSignedIn, hs.redirectFromShortURL, hs.Index)
|
||||
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagDashboardEmbed) {
|
||||
if hs.Features.IsEnabledGlobally(featuremgmt.FlagDashboardEmbed) {
|
||||
r.Get("/d-embed", reqSignedIn, middleware.AddAllowEmbeddingHeader(), hs.Index)
|
||||
}
|
||||
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagPublicDashboards) {
|
||||
if hs.Features.IsEnabledGlobally(featuremgmt.FlagPublicDashboards) {
|
||||
// list public dashboards
|
||||
r.Get("/public-dashboards/list", reqSignedIn, hs.Index)
|
||||
|
||||
@@ -216,7 +216,7 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
r.Get("/swagger-ui", swaggerUI)
|
||||
r.Get("/openapi3", openapi3)
|
||||
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagClientTokenRotation) {
|
||||
if hs.Features.IsEnabledGlobally(featuremgmt.FlagClientTokenRotation) {
|
||||
r.Post("/api/user/auth-tokens/rotate", routing.Wrap(hs.RotateUserAuthToken))
|
||||
r.Get("/user/auth-tokens/rotate", routing.Wrap(hs.RotateUserAuthTokenRedirect))
|
||||
}
|
||||
@@ -277,12 +277,12 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
orgRoute.Get("/quotas", authorize(ac.EvalPermission(ac.ActionOrgsQuotasRead)), routing.Wrap(hs.GetCurrentOrgQuotas))
|
||||
})
|
||||
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagStorage) {
|
||||
if hs.Features.IsEnabledGlobally(featuremgmt.FlagStorage) {
|
||||
// Will eventually be replaced with the 'object' route
|
||||
apiRoute.Group("/storage", hs.StorageService.RegisterHTTPRoutes)
|
||||
}
|
||||
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagPanelTitleSearch) {
|
||||
if hs.Features.IsEnabledGlobally(featuremgmt.FlagPanelTitleSearch) {
|
||||
apiRoute.Group("/search-v2", hs.SearchV2HTTPService.RegisterHTTPRoutes)
|
||||
}
|
||||
|
||||
@@ -392,7 +392,7 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
apiRoute.Any("/plugin-proxy/:pluginId/*", requestmeta.SetSLOGroup(requestmeta.SLOGroupHighSlow), authorize(ac.EvalPermission(pluginaccesscontrol.ActionAppAccess, pluginIDScope)), hs.ProxyPluginRequest)
|
||||
apiRoute.Any("/plugin-proxy/:pluginId", requestmeta.SetSLOGroup(requestmeta.SLOGroupHighSlow), authorize(ac.EvalPermission(pluginaccesscontrol.ActionAppAccess, pluginIDScope)), hs.ProxyPluginRequest)
|
||||
|
||||
if hs.Cfg.PluginAdminEnabled && (hs.Features.IsEnabled(featuremgmt.FlagManagedPluginsInstall) || !hs.Cfg.PluginAdminExternalManageEnabled) {
|
||||
if hs.Cfg.PluginAdminEnabled && (hs.Features.IsEnabledGlobally(featuremgmt.FlagManagedPluginsInstall) || !hs.Cfg.PluginAdminExternalManageEnabled) {
|
||||
apiRoute.Group("/plugins", func(pluginRoute routing.RouteRegister) {
|
||||
pluginRoute.Post("/:pluginId/install", authorize(ac.EvalPermission(pluginaccesscontrol.ActionInstall)), routing.Wrap(hs.InstallPlugin))
|
||||
pluginRoute.Post("/:pluginId/uninstall", authorize(ac.EvalPermission(pluginaccesscontrol.ActionInstall)), routing.Wrap(hs.UninstallPlugin))
|
||||
@@ -405,7 +405,7 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
pluginRoute.Get("/:pluginId/metrics", reqOrgAdmin, routing.Wrap(hs.CollectPluginMetrics))
|
||||
})
|
||||
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagFeatureToggleAdminPage) {
|
||||
if hs.Features.IsEnabledGlobally(featuremgmt.FlagFeatureToggleAdminPage) {
|
||||
apiRoute.Group("/featuremgmt", func(featuremgmtRoute routing.RouteRegister) {
|
||||
featuremgmtRoute.Get("/state", authorize(ac.EvalPermission(ac.ActionFeatureManagementRead)), hs.GetFeatureMgmtState)
|
||||
featuremgmtRoute.Get("/", authorize(ac.EvalPermission(ac.ActionFeatureManagementRead)), hs.GetFeatureToggles)
|
||||
|
||||
@@ -228,7 +228,7 @@ func setupSimpleHTTPServer(features *featuremgmt.FeatureManager) *HTTPServer {
|
||||
features = featuremgmt.WithFeatures()
|
||||
}
|
||||
// nolint:staticcheck
|
||||
cfg := setting.NewCfgWithFeatures(features.IsEnabled)
|
||||
cfg := setting.NewCfgWithFeatures(features.IsEnabledGlobally)
|
||||
|
||||
return &HTTPServer{
|
||||
Cfg: cfg,
|
||||
|
||||
@@ -94,7 +94,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 hs.Features.IsEnabled(featuremgmt.FlagPublicDashboards) {
|
||||
if hs.Features.IsEnabledGlobally(featuremgmt.FlagPublicDashboards) {
|
||||
publicDashboard, err := hs.PublicDashboardsApi.PublicDashboardService.FindByDashboardUid(c.Req.Context(), c.SignedInUser.GetOrgID(), dash.UID)
|
||||
if err != nil && !errors.Is(err, publicdashboardModels.ErrPublicDashboardNotFound) {
|
||||
return response.Error(http.StatusInternalServerError, "Error while retrieving public dashboards", err)
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"golang.org/x/exp/slices"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/datasource"
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
@@ -356,7 +357,7 @@ func validateJSONData(ctx context.Context, jsonData *simplejson.Json, cfg *setti
|
||||
}
|
||||
|
||||
// Prevent adding a data source team header with a name that matches the auth proxy header name
|
||||
if features.IsEnabled(featuremgmt.FlagTeamHttpHeaders) {
|
||||
if features.IsEnabled(ctx, featuremgmt.FlagTeamHttpHeaders) {
|
||||
err := validateTeamHTTPHeaderJSON(jsonData)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
+4
-4
@@ -43,7 +43,7 @@ const REDACTED = "redacted"
|
||||
func (hs *HTTPServer) GetFolders(c *contextmodel.ReqContext) response.Response {
|
||||
var folders []*folder.Folder
|
||||
var err error
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagNestedFolders) {
|
||||
if hs.Features.IsEnabled(c.Req.Context(), featuremgmt.FlagNestedFolders) {
|
||||
folders, err = hs.folderService.GetChildren(c.Req.Context(), &folder.GetChildrenQuery{
|
||||
OrgID: c.SignedInUser.GetOrgID(),
|
||||
Limit: c.QueryInt64("limit"),
|
||||
@@ -190,7 +190,7 @@ func (hs *HTTPServer) setDefaultFolderPermissions(ctx context.Context, orgID int
|
||||
}
|
||||
|
||||
isNested := folder.ParentUID != ""
|
||||
if !isNested || !hs.Features.IsEnabled(featuremgmt.FlagNestedFolders) {
|
||||
if !isNested || !hs.Features.IsEnabled(ctx, featuremgmt.FlagNestedFolders) {
|
||||
permissions = append(permissions, []accesscontrol.SetResourcePermissionCommand{
|
||||
{BuiltinRole: string(org.RoleEditor), Permission: dashboards.PERMISSION_EDIT.String()},
|
||||
{BuiltinRole: string(org.RoleViewer), Permission: dashboards.PERMISSION_VIEW.String()},
|
||||
@@ -212,7 +212,7 @@ func (hs *HTTPServer) setDefaultFolderPermissions(ctx context.Context, orgID int
|
||||
// 404: notFoundError
|
||||
// 500: internalServerError
|
||||
func (hs *HTTPServer) MoveFolder(c *contextmodel.ReqContext) response.Response {
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagNestedFolders) {
|
||||
if hs.Features.IsEnabled(c.Req.Context(), featuremgmt.FlagNestedFolders) {
|
||||
cmd := folder.MoveFolderCommand{}
|
||||
if err := web.Bind(c.Req, &cmd); err != nil {
|
||||
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||
@@ -390,7 +390,7 @@ func (hs *HTTPServer) newToFolderDto(c *contextmodel.ReqContext, f *folder.Folde
|
||||
return dtos.Folder{}, err
|
||||
}
|
||||
|
||||
if !hs.Features.IsEnabled(featuremgmt.FlagNestedFolders) {
|
||||
if !hs.Features.IsEnabled(c.Req.Context(), featuremgmt.FlagNestedFolders) {
|
||||
return folderDTO, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.Fro
|
||||
continue
|
||||
}
|
||||
|
||||
if panel.ID == "datagrid" && !hs.Features.IsEnabled(featuremgmt.FlagEnableDatagridEditing) {
|
||||
if panel.ID == "datagrid" && !hs.Features.IsEnabled(c.Req.Context(), featuremgmt.FlagEnableDatagridEditing) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ func setupTestEnvironment(t *testing.T, cfg *setting.Cfg, features *featuremgmt.
|
||||
t.Helper()
|
||||
db.InitTestDB(t)
|
||||
// nolint:staticcheck
|
||||
cfg.IsFeatureToggleEnabled = features.IsEnabled
|
||||
cfg.IsFeatureToggleEnabled = features.IsEnabledGlobally
|
||||
|
||||
{
|
||||
oldVersion := setting.BuildVersion
|
||||
|
||||
+3
-3
@@ -38,7 +38,7 @@ func (hs *HTTPServer) setIndexViewData(c *contextmodel.ReqContext) (*dtos.IndexV
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagIndividualCookiePreferences) {
|
||||
if hs.Features.IsEnabled(c.Req.Context(), featuremgmt.FlagIndividualCookiePreferences) {
|
||||
if !prefs.Cookies("analytics") {
|
||||
settings.GoogleAnalytics4Id = ""
|
||||
settings.GoogleAnalyticsId = ""
|
||||
@@ -166,7 +166,7 @@ func (hs *HTTPServer) setIndexViewData(c *contextmodel.ReqContext) (*dtos.IndexV
|
||||
|
||||
hs.HooksService.RunIndexDataHooks(&data, c)
|
||||
|
||||
data.NavTree.ApplyAdminIA(hs.Features.IsEnabled(featuremgmt.FlagNavAdminSubsections))
|
||||
data.NavTree.ApplyAdminIA(hs.Features.IsEnabled(c.Req.Context(), featuremgmt.FlagNavAdminSubsections))
|
||||
data.NavTree.Sort()
|
||||
|
||||
return &data, nil
|
||||
@@ -244,7 +244,7 @@ func (hs *HTTPServer) getThemeForIndexData(themePrefId string, themeURLParam str
|
||||
|
||||
if pref.IsValidThemeID(themePrefId) {
|
||||
theme := pref.GetThemeByID(themePrefId)
|
||||
if !theme.IsExtra || hs.Features.IsEnabled(featuremgmt.FlagExtraThemes) {
|
||||
if !theme.IsExtra || hs.Features.IsEnabledGlobally(featuremgmt.FlagExtraThemes) {
|
||||
return theme
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -91,7 +91,7 @@ func (hs *HTTPServer) CookieOptionsFromCfg() cookies.CookieOptions {
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) LoginView(c *contextmodel.ReqContext) {
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagClientTokenRotation) {
|
||||
if hs.Features.IsEnabled(c.Req.Context(), featuremgmt.FlagClientTokenRotation) {
|
||||
if errors.Is(c.LookupTokenErr, authn.ErrTokenNeedsRotation) {
|
||||
c.Redirect(hs.Cfg.AppSubURL + "/")
|
||||
return
|
||||
@@ -334,7 +334,7 @@ func (hs *HTTPServer) RedirectResponseWithError(c *contextmodel.ReqContext, err
|
||||
|
||||
func (hs *HTTPServer) redirectURLWithErrorCookie(c *contextmodel.ReqContext, err error) string {
|
||||
setCookie := true
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagIndividualCookiePreferences) {
|
||||
if hs.Features.IsEnabled(c.Req.Context(), featuremgmt.FlagIndividualCookiePreferences) {
|
||||
var userID int64
|
||||
if c.SignedInUser != nil && !c.SignedInUser.IsNil() {
|
||||
var errID error
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ func (hs *HTTPServer) QueryMetricsV2(c *contextmodel.ReqContext) response.Respon
|
||||
|
||||
func (hs *HTTPServer) toJsonStreamingResponse(ctx context.Context, qdr *backend.QueryDataResponse) response.Response {
|
||||
statusWhenError := http.StatusBadRequest
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagDatasourceQueryMultiStatus) {
|
||||
if hs.Features.IsEnabled(ctx, featuremgmt.FlagDatasourceQueryMultiStatus) {
|
||||
statusWhenError = http.StatusMultiStatus
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ import (
|
||||
func (hs *HTTPServer) registerPlaylistAPI(apiRoute routing.RouteRegister) {
|
||||
// Register the actual handlers
|
||||
apiRoute.Group("/playlists", func(playlistRoute routing.RouteRegister) {
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagKubernetesPlaylists) {
|
||||
if hs.Features.IsEnabledGlobally(featuremgmt.FlagKubernetesPlaylists) {
|
||||
// Use k8s client to implement legacy API
|
||||
handler := newPlaylistK8sHandler(hs)
|
||||
playlistRoute.Get("/", handler.searchPlaylists)
|
||||
|
||||
@@ -270,7 +270,7 @@ func (proxy *DataSourceProxy) director(req *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
if proxy.features.IsEnabled(featuremgmt.FlagIdForwarding) && auth.IsIDForwardingEnabledForDataSource(proxy.ds) {
|
||||
if proxy.features.IsEnabled(req.Context(), featuremgmt.FlagIdForwarding) && auth.IsIDForwardingEnabledForDataSource(proxy.ds) {
|
||||
proxyutil.ApplyForwardIDHeader(req, proxy.ctx.SignedInUser)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
||||
@@ -17,7 +19,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
"github.com/grafana/grafana/pkg/util/proxyutil"
|
||||
"github.com/grafana/grafana/pkg/web"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
)
|
||||
|
||||
type PluginProxy struct {
|
||||
@@ -161,7 +162,7 @@ func (proxy PluginProxy) director(req *http.Request) {
|
||||
|
||||
proxyutil.ApplyUserHeader(proxy.cfg.SendUserHeader, req, proxy.ctx.SignedInUser)
|
||||
|
||||
if proxy.features.IsEnabled(featuremgmt.FlagIdForwarding) {
|
||||
if proxy.features.IsEnabled(req.Context(), featuremgmt.FlagIdForwarding) {
|
||||
proxyutil.ApplyForwardIDHeader(req, proxy.ctx.SignedInUser)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user