FeatureFlags: define features outside settings.Cfg (take 3) (#44443)
This commit is contained in:
+5
-1
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
acmiddleware "github.com/grafana/grafana/pkg/services/accesscontrol/middleware"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
sa "github.com/grafana/grafana/pkg/services/serviceaccounts/manager"
|
||||
)
|
||||
|
||||
@@ -437,7 +438,7 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
// Some channels may have info
|
||||
liveRoute.Get("/info/*", routing.Wrap(hs.Live.HandleInfoHTTP))
|
||||
|
||||
if hs.Cfg.FeatureToggles["live-pipeline"] {
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagLivePipeline) {
|
||||
// POST Live data to be processed according to channel rules.
|
||||
liveRoute.Post("/pipeline/push/*", hs.LivePushGateway.HandlePipelinePush)
|
||||
liveRoute.Post("/pipeline-convert-test", routing.Wrap(hs.Live.HandlePipelineConvertTestHTTP), reqOrgAdmin)
|
||||
@@ -460,6 +461,9 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
// admin api
|
||||
r.Group("/api/admin", func(adminRoute routing.RouteRegister) {
|
||||
adminRoute.Get("/settings", authorize(reqGrafanaAdmin, ac.EvalPermission(ac.ActionSettingsRead)), routing.Wrap(hs.AdminGetSettings))
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagShowFeatureFlagsInUI) {
|
||||
adminRoute.Get("/settings/features", authorize(reqGrafanaAdmin, ac.EvalPermission(ac.ActionSettingsRead)), hs.Features.HandleGetSettings)
|
||||
}
|
||||
adminRoute.Get("/stats", authorize(reqGrafanaAdmin, ac.EvalPermission(ac.ActionServerStatsRead)), routing.Wrap(AdminGetStats))
|
||||
adminRoute.Post("/pause-all-alerts", reqGrafanaAdmin, routing.Wrap(PauseAllAlerts))
|
||||
|
||||
|
||||
+3
-2
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/components/apikeygen"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/web"
|
||||
)
|
||||
|
||||
@@ -83,7 +84,7 @@ func (hs *HTTPServer) AddAPIKey(c *models.ReqContext) response.Response {
|
||||
}
|
||||
cmd.OrgId = c.OrgId
|
||||
var err error
|
||||
if hs.Cfg.FeatureToggles["service-accounts"] {
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagServiceAccounts) {
|
||||
// Api keys should now be created with addadditionalapikey endpoint
|
||||
return response.Error(400, "API keys should now be added via the AdditionalAPIKey endpoint.", err)
|
||||
}
|
||||
@@ -120,7 +121,7 @@ func (hs *HTTPServer) AdditionalAPIKey(c *models.ReqContext) response.Response {
|
||||
if err := web.Bind(c.Req, &cmd); err != nil {
|
||||
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||
}
|
||||
if !hs.Cfg.FeatureToggles["service-accounts"] {
|
||||
if !hs.Features.IsEnabled(featuremgmt.FlagServiceAccounts) {
|
||||
return response.Error(500, "Requires services-accounts feature", errors.New("feature missing"))
|
||||
}
|
||||
|
||||
|
||||
+25
-7
@@ -30,6 +30,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol/resourceservices"
|
||||
"github.com/grafana/grafana/pkg/services/auth"
|
||||
"github.com/grafana/grafana/pkg/services/contexthandler"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/quota"
|
||||
"github.com/grafana/grafana/pkg/services/rendering"
|
||||
"github.com/grafana/grafana/pkg/services/searchusers"
|
||||
@@ -215,8 +216,8 @@ func (s *fakeRenderService) Init() error {
|
||||
}
|
||||
|
||||
func setupAccessControlScenarioContext(t *testing.T, cfg *setting.Cfg, url string, permissions []*accesscontrol.Permission) (*scenarioContext, *HTTPServer) {
|
||||
cfg.FeatureToggles = make(map[string]bool)
|
||||
cfg.FeatureToggles["accesscontrol"] = true
|
||||
features := featuremgmt.WithFeatures(featuremgmt.FlagAccesscontrol)
|
||||
cfg.IsFeatureToggleEnabled = features.IsEnabled
|
||||
cfg.Quota.Enabled = false
|
||||
|
||||
bus := bus.GetBus()
|
||||
@@ -224,6 +225,7 @@ func setupAccessControlScenarioContext(t *testing.T, cfg *setting.Cfg, url strin
|
||||
Cfg: cfg,
|
||||
Bus: bus,
|
||||
Live: newTestLive(t),
|
||||
Features: features,
|
||||
QuotaService: "a.QuotaService{Cfg: cfg},
|
||||
RouteRegister: routing.NewRouteRegister(),
|
||||
AccessControl: accesscontrolmock.New().WithPermissions(permissions),
|
||||
@@ -298,13 +300,25 @@ func setInitCtxSignedInOrgAdmin(initCtx *models.ReqContext) {
|
||||
initCtx.SignedInUser = &models.SignedInUser{UserId: testUserID, OrgId: 1, OrgRole: models.ROLE_ADMIN, Login: testUserLogin}
|
||||
}
|
||||
|
||||
func setupSimpleHTTPServer(features *featuremgmt.FeatureManager) *HTTPServer {
|
||||
if features == nil {
|
||||
features = featuremgmt.WithFeatures()
|
||||
}
|
||||
cfg := setting.NewCfg()
|
||||
cfg.IsFeatureToggleEnabled = features.IsEnabled
|
||||
|
||||
return &HTTPServer{
|
||||
Cfg: cfg,
|
||||
Features: features,
|
||||
Bus: bus.GetBus(),
|
||||
}
|
||||
}
|
||||
|
||||
func setupHTTPServer(t *testing.T, useFakeAccessControl bool, enableAccessControl bool) accessControlScenarioContext {
|
||||
// Use a new conf
|
||||
features := featuremgmt.WithFeatures("accesscontrol", enableAccessControl)
|
||||
cfg := setting.NewCfg()
|
||||
cfg.FeatureToggles = make(map[string]bool)
|
||||
if enableAccessControl {
|
||||
cfg.FeatureToggles["accesscontrol"] = enableAccessControl
|
||||
}
|
||||
cfg.IsFeatureToggleEnabled = features.IsEnabled
|
||||
|
||||
return setupHTTPServerWithCfg(t, useFakeAccessControl, enableAccessControl, cfg)
|
||||
}
|
||||
@@ -312,6 +326,9 @@ func setupHTTPServer(t *testing.T, useFakeAccessControl bool, enableAccessContro
|
||||
func setupHTTPServerWithCfg(t *testing.T, useFakeAccessControl, enableAccessControl bool, cfg *setting.Cfg) accessControlScenarioContext {
|
||||
t.Helper()
|
||||
|
||||
features := featuremgmt.WithFeatures("accesscontrol", enableAccessControl)
|
||||
cfg.IsFeatureToggleEnabled = features.IsEnabled
|
||||
|
||||
var acmock *accesscontrolmock.Mock
|
||||
var ac *ossaccesscontrol.OSSAccessControlService
|
||||
|
||||
@@ -325,6 +342,7 @@ func setupHTTPServerWithCfg(t *testing.T, useFakeAccessControl, enableAccessCont
|
||||
// Create minimal HTTP Server
|
||||
hs := &HTTPServer{
|
||||
Cfg: cfg,
|
||||
Features: features,
|
||||
Bus: bus,
|
||||
Live: newTestLive(t),
|
||||
QuotaService: "a.QuotaService{Cfg: cfg},
|
||||
@@ -344,7 +362,7 @@ func setupHTTPServerWithCfg(t *testing.T, useFakeAccessControl, enableAccessCont
|
||||
require.NoError(t, err)
|
||||
hs.TeamPermissionsService = teamPermissionService
|
||||
} else {
|
||||
ac = ossaccesscontrol.ProvideService(cfg, &usagestats.UsageStatsMock{T: t})
|
||||
ac = ossaccesscontrol.ProvideService(hs.Features, &usagestats.UsageStatsMock{T: t})
|
||||
hs.AccessControl = ac
|
||||
// Perform role registration
|
||||
err := hs.declareFixedRoles()
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/alerting"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/libraryelements"
|
||||
"github.com/grafana/grafana/pkg/services/live"
|
||||
"github.com/grafana/grafana/pkg/services/provisioning"
|
||||
@@ -88,8 +89,17 @@ type testState struct {
|
||||
}
|
||||
|
||||
func newTestLive(t *testing.T) *live.GrafanaLive {
|
||||
features := featuremgmt.WithFeatures()
|
||||
cfg := &setting.Cfg{AppURL: "http://localhost:3000/"}
|
||||
gLive, err := live.ProvideService(nil, cfg, routing.NewRouteRegister(), nil, nil, nil, sqlstore.InitTestDB(t), nil, &usagestats.UsageStatsMock{T: t}, nil)
|
||||
cfg.IsFeatureToggleEnabled = features.IsEnabled
|
||||
gLive, err := live.ProvideService(nil, cfg,
|
||||
routing.NewRouteRegister(),
|
||||
nil, nil, nil,
|
||||
sqlstore.InitTestDB(t),
|
||||
nil,
|
||||
&usagestats.UsageStatsMock{T: t},
|
||||
nil,
|
||||
features)
|
||||
require.NoError(t, err)
|
||||
return gLive
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *models.ReqContext) (map[string]i
|
||||
"edition": hs.License.Edition(),
|
||||
"enabledFeatures": hs.License.EnabledFeatures(),
|
||||
},
|
||||
"featureToggles": hs.Cfg.FeatureToggles,
|
||||
"featureToggles": hs.Features.GetEnabled(c.Req.Context()),
|
||||
"rendererAvailable": hs.RenderService.IsAvailable(),
|
||||
"rendererVersion": hs.RenderService.Version(),
|
||||
"http2Enabled": hs.Cfg.Protocol == setting.HTTP2Scheme,
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/licensing"
|
||||
"github.com/grafana/grafana/pkg/services/rendering"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
@@ -19,9 +20,10 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func setupTestEnvironment(t *testing.T, cfg *setting.Cfg) (*web.Mux, *HTTPServer) {
|
||||
func setupTestEnvironment(t *testing.T, cfg *setting.Cfg, features *featuremgmt.FeatureManager) (*web.Mux, *HTTPServer) {
|
||||
t.Helper()
|
||||
sqlstore.InitTestDB(t)
|
||||
cfg.IsFeatureToggleEnabled = features.IsEnabled
|
||||
|
||||
{
|
||||
oldVersion := setting.BuildVersion
|
||||
@@ -37,9 +39,10 @@ func setupTestEnvironment(t *testing.T, cfg *setting.Cfg) (*web.Mux, *HTTPServer
|
||||
sqlStore := sqlstore.InitTestDB(t)
|
||||
|
||||
hs := &HTTPServer{
|
||||
Cfg: cfg,
|
||||
Bus: bus.GetBus(),
|
||||
License: &licensing.OSSLicensingService{Cfg: cfg},
|
||||
Cfg: cfg,
|
||||
Features: features,
|
||||
Bus: bus.GetBus(),
|
||||
License: &licensing.OSSLicensingService{Cfg: cfg},
|
||||
RenderService: &rendering.RenderingService{
|
||||
Cfg: cfg,
|
||||
RendererPluginManager: &fakeRendererManager{},
|
||||
@@ -73,7 +76,8 @@ func TestHTTPServer_GetFrontendSettings_hideVersionAnonymous(t *testing.T) {
|
||||
cfg.Env = "testing"
|
||||
cfg.BuildVersion = "7.8.9"
|
||||
cfg.BuildCommit = "01234567"
|
||||
m, hs := setupTestEnvironment(t, cfg)
|
||||
|
||||
m, hs := setupTestEnvironment(t, cfg, featuremgmt.WithFeatures())
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/frontend/settings", nil)
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/datasourceproxy"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
"github.com/grafana/grafana/pkg/services/encryption"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/hooks"
|
||||
"github.com/grafana/grafana/pkg/services/libraryelements"
|
||||
"github.com/grafana/grafana/pkg/services/librarypanels"
|
||||
@@ -77,6 +78,7 @@ type HTTPServer struct {
|
||||
Bus bus.Bus
|
||||
RenderService rendering.Service
|
||||
Cfg *setting.Cfg
|
||||
Features *featuremgmt.FeatureManager
|
||||
SettingsProvider setting.Provider
|
||||
HooksService *hooks.HooksService
|
||||
CacheService *localcache.CacheService
|
||||
@@ -138,7 +140,7 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
|
||||
loginService login.Service, accessControl accesscontrol.AccessControl,
|
||||
dataSourceProxy *datasourceproxy.DataSourceProxyService, searchService *search.SearchService,
|
||||
live *live.GrafanaLive, livePushGateway *pushhttp.Gateway, plugCtxProvider *plugincontext.Provider,
|
||||
contextHandler *contexthandler.ContextHandler,
|
||||
contextHandler *contexthandler.ContextHandler, features *featuremgmt.FeatureManager,
|
||||
schemaService *schemaloader.SchemaLoaderService, alertNG *ngalert.AlertNG,
|
||||
libraryPanelService librarypanels.Service, libraryElementService libraryelements.Service,
|
||||
quotaService *quota.QuotaService, socialService social.Service, tracer tracing.Tracer,
|
||||
@@ -171,6 +173,7 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
|
||||
AuthTokenService: userTokenService,
|
||||
cleanUpService: cleanUpService,
|
||||
ShortURLService: shortURLService,
|
||||
Features: features,
|
||||
ThumbService: thumbService,
|
||||
RemoteCacheService: remoteCache,
|
||||
ProvisioningService: provisioningService,
|
||||
|
||||
+14
-11
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
@@ -85,7 +86,7 @@ func (hs *HTTPServer) getAppLinks(c *models.ReqContext) ([]*dtos.NavLink, error)
|
||||
SortWeight: dtos.WeightPlugin,
|
||||
}
|
||||
|
||||
if hs.Cfg.IsNewNavigationEnabled() {
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagNewNavigation) {
|
||||
appLink.Section = dtos.NavSectionPlugin
|
||||
} else {
|
||||
appLink.Section = dtos.NavSectionCore
|
||||
@@ -143,7 +144,9 @@ func (hs *HTTPServer) getAppLinks(c *models.ReqContext) ([]*dtos.NavLink, error)
|
||||
}
|
||||
|
||||
func enableServiceAccount(hs *HTTPServer, c *models.ReqContext) bool {
|
||||
return c.OrgRole == models.ROLE_ADMIN && hs.Cfg.IsServiceAccountEnabled() && hs.serviceAccountsService.Migrated(c.Req.Context(), c.OrgId)
|
||||
return c.OrgRole == models.ROLE_ADMIN &&
|
||||
hs.Features.IsEnabled(featuremgmt.FlagServiceAccounts) &&
|
||||
hs.serviceAccountsService.Migrated(c.Req.Context(), c.OrgId)
|
||||
}
|
||||
|
||||
func enableTeams(hs *HTTPServer, c *models.ReqContext) bool {
|
||||
@@ -154,7 +157,7 @@ func (hs *HTTPServer) getNavTree(c *models.ReqContext, hasEditPerm bool) ([]*dto
|
||||
hasAccess := ac.HasAccess(hs.AccessControl, c)
|
||||
navTree := []*dtos.NavLink{}
|
||||
|
||||
if hs.Cfg.IsNewNavigationEnabled() {
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagNewNavigation) {
|
||||
navTree = append(navTree, &dtos.NavLink{
|
||||
Text: "Home",
|
||||
Id: "home",
|
||||
@@ -165,7 +168,7 @@ func (hs *HTTPServer) getNavTree(c *models.ReqContext, hasEditPerm bool) ([]*dto
|
||||
})
|
||||
}
|
||||
|
||||
if hasEditPerm && !hs.Cfg.IsNewNavigationEnabled() {
|
||||
if hasEditPerm && !hs.Features.IsEnabled(featuremgmt.FlagNewNavigation) {
|
||||
children := hs.buildCreateNavLinks(c)
|
||||
navTree = append(navTree, &dtos.NavLink{
|
||||
Text: "Create",
|
||||
@@ -181,7 +184,7 @@ func (hs *HTTPServer) getNavTree(c *models.ReqContext, hasEditPerm bool) ([]*dto
|
||||
dashboardChildLinks := hs.buildDashboardNavLinks(c, hasEditPerm)
|
||||
|
||||
dashboardsUrl := "/"
|
||||
if hs.Cfg.IsNewNavigationEnabled() {
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagNewNavigation) {
|
||||
dashboardsUrl = "/dashboards"
|
||||
}
|
||||
|
||||
@@ -312,7 +315,7 @@ func (hs *HTTPServer) getNavTree(c *models.ReqContext, hasEditPerm bool) ([]*dto
|
||||
})
|
||||
}
|
||||
|
||||
if hs.Cfg.FeatureToggles["live-pipeline"] {
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagLivePipeline) {
|
||||
liveNavLinks := []*dtos.NavLink{}
|
||||
|
||||
liveNavLinks = append(liveNavLinks, &dtos.NavLink{
|
||||
@@ -346,7 +349,7 @@ func (hs *HTTPServer) getNavTree(c *models.ReqContext, hasEditPerm bool) ([]*dto
|
||||
SortWeight: dtos.WeightConfig,
|
||||
Children: configNodes,
|
||||
}
|
||||
if hs.Cfg.IsNewNavigationEnabled() {
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagNewNavigation) {
|
||||
configNode.Section = dtos.NavSectionConfig
|
||||
} else {
|
||||
configNode.Section = dtos.NavSectionCore
|
||||
@@ -358,7 +361,7 @@ func (hs *HTTPServer) getNavTree(c *models.ReqContext, hasEditPerm bool) ([]*dto
|
||||
|
||||
if len(adminNavLinks) > 0 {
|
||||
navSection := dtos.NavSectionCore
|
||||
if hs.Cfg.IsNewNavigationEnabled() {
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagNewNavigation) {
|
||||
navSection = dtos.NavSectionConfig
|
||||
}
|
||||
serverAdminNode := navlinks.GetServerAdminNode(adminNavLinks, navSection)
|
||||
@@ -386,7 +389,7 @@ func (hs *HTTPServer) getNavTree(c *models.ReqContext, hasEditPerm bool) ([]*dto
|
||||
|
||||
func (hs *HTTPServer) buildDashboardNavLinks(c *models.ReqContext, hasEditPerm bool) []*dtos.NavLink {
|
||||
dashboardChildNavs := []*dtos.NavLink{}
|
||||
if !hs.Cfg.IsNewNavigationEnabled() {
|
||||
if !hs.Features.IsEnabled(featuremgmt.FlagNewNavigation) {
|
||||
dashboardChildNavs = append(dashboardChildNavs, &dtos.NavLink{
|
||||
Text: "Home", Id: "home", Url: hs.Cfg.AppSubURL + "/", Icon: "home-alt", HideFromTabs: true,
|
||||
})
|
||||
@@ -417,7 +420,7 @@ func (hs *HTTPServer) buildDashboardNavLinks(c *models.ReqContext, hasEditPerm b
|
||||
})
|
||||
}
|
||||
|
||||
if hasEditPerm && hs.Cfg.IsNewNavigationEnabled() {
|
||||
if hasEditPerm && hs.Features.IsEnabled(featuremgmt.FlagNewNavigation) {
|
||||
dashboardChildNavs = append(dashboardChildNavs, &dtos.NavLink{
|
||||
Text: "Divider", Divider: true, Id: "divider", HideFromTabs: true,
|
||||
})
|
||||
@@ -622,7 +625,7 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat
|
||||
LoadingLogo: "public/img/grafana_icon.svg",
|
||||
}
|
||||
|
||||
if hs.Cfg.FeatureToggles["accesscontrol"] {
|
||||
if hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) {
|
||||
userPermissions, err := hs.AccessControl.GetUserPermissions(c.Req.Context(), c.SignedInUser)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
+2
-1
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
@@ -89,7 +90,7 @@ func (hs *HTTPServer) CreateOrg(c *models.ReqContext) response.Response {
|
||||
if err := web.Bind(c.Req, &cmd); err != nil {
|
||||
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||
}
|
||||
acEnabled := hs.Cfg.FeatureToggles["accesscontrol"]
|
||||
acEnabled := hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol)
|
||||
if !acEnabled && !(setting.AllowUserOrgCreate || c.IsGrafanaAdmin) {
|
||||
return response.Error(403, "Access denied", nil)
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
@@ -34,8 +35,8 @@ func setUpGetOrgUsersDB(t *testing.T, sqlStore *sqlstore.SQLStore) {
|
||||
}
|
||||
|
||||
func TestOrgUsersAPIEndpoint_userLoggedIn(t *testing.T) {
|
||||
settings := setting.NewCfg()
|
||||
hs := &HTTPServer{Cfg: settings}
|
||||
hs := setupSimpleHTTPServer(featuremgmt.WithFeatures())
|
||||
settings := hs.Cfg
|
||||
|
||||
sqlStore := sqlstore.InitTestDB(t)
|
||||
sqlStore.Cfg = settings
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/middleware"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/web"
|
||||
)
|
||||
|
||||
@@ -52,8 +52,8 @@ type RouteRegister interface {
|
||||
|
||||
type RegisterNamedMiddleware func(name string) web.Handler
|
||||
|
||||
func ProvideRegister(cfg *setting.Cfg) *RouteRegisterImpl {
|
||||
return NewRouteRegister(middleware.ProvideRouteOperationName, middleware.RequestMetrics(cfg))
|
||||
func ProvideRegister(features featuremgmt.FeatureToggles) *RouteRegisterImpl {
|
||||
return NewRouteRegister(middleware.ProvideRouteOperationName, middleware.RequestMetrics(features))
|
||||
}
|
||||
|
||||
// NewRouteRegister creates a new RouteRegister with all middlewares sent as params
|
||||
|
||||
+2
-1
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
"github.com/grafana/grafana/pkg/web"
|
||||
@@ -19,7 +20,7 @@ func (hs *HTTPServer) CreateTeam(c *models.ReqContext) response.Response {
|
||||
if err := web.Bind(c.Req, &cmd); err != nil {
|
||||
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||
}
|
||||
accessControlEnabled := hs.Cfg.FeatureToggles["accesscontrol"]
|
||||
accessControlEnabled := hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol)
|
||||
if !accessControlEnabled && c.OrgRole == models.ROLE_VIEWER {
|
||||
return response.Error(403, "Not allowed to create team.", nil)
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
"github.com/grafana/grafana/pkg/web"
|
||||
)
|
||||
@@ -61,7 +62,7 @@ func (hs *HTTPServer) AddTeamMember(c *models.ReqContext) response.Response {
|
||||
return response.Error(http.StatusBadRequest, "teamId is invalid", err)
|
||||
}
|
||||
|
||||
if !hs.Cfg.FeatureToggles["accesscontrol"] {
|
||||
if !hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) {
|
||||
if err := hs.teamGuardian.CanAdmin(c.Req.Context(), cmd.OrgId, cmd.TeamId, c.SignedInUser); err != nil {
|
||||
return response.Error(403, "Not allowed to add team member", err)
|
||||
}
|
||||
@@ -101,7 +102,7 @@ func (hs *HTTPServer) UpdateTeamMember(c *models.ReqContext) response.Response {
|
||||
}
|
||||
orgId := c.OrgId
|
||||
|
||||
if !hs.Cfg.FeatureToggles["accesscontrol"] {
|
||||
if !hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) {
|
||||
if err := hs.teamGuardian.CanAdmin(c.Req.Context(), orgId, teamId, c.SignedInUser); err != nil {
|
||||
return response.Error(403, "Not allowed to update team member", err)
|
||||
}
|
||||
@@ -144,7 +145,7 @@ func (hs *HTTPServer) RemoveTeamMember(c *models.ReqContext) response.Response {
|
||||
return response.Error(http.StatusBadRequest, "userId is invalid", err)
|
||||
}
|
||||
|
||||
if !hs.Cfg.FeatureToggles["accesscontrol"] {
|
||||
if !hs.Features.IsEnabled(featuremgmt.FlagAccesscontrol) {
|
||||
if err := hs.teamGuardian.CanAdmin(c.Req.Context(), orgId, teamId, c.SignedInUser); err != nil {
|
||||
return response.Error(403, "Not allowed to remove team member", err)
|
||||
}
|
||||
|
||||
@@ -32,9 +32,7 @@ func (stub *testLogger) Warn(testMessage string, ctx ...interface{}) {
|
||||
|
||||
func TestTeamAPIEndpoint(t *testing.T) {
|
||||
t.Run("Given two teams", func(t *testing.T) {
|
||||
hs := &HTTPServer{
|
||||
Cfg: setting.NewCfg(),
|
||||
}
|
||||
hs := setupSimpleHTTPServer(nil)
|
||||
hs.SQLStore = sqlstore.InitTestDB(t)
|
||||
|
||||
loggedInUserScenario(t, "When calling GET on", "/api/teams/search", "/api/teams/search", func(sc *scenarioContext) {
|
||||
@@ -73,9 +71,7 @@ func TestTeamAPIEndpoint(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("When creating team with API key", func(t *testing.T) {
|
||||
hs := &HTTPServer{
|
||||
Cfg: setting.NewCfg(),
|
||||
}
|
||||
hs := setupSimpleHTTPServer(nil)
|
||||
hs.Cfg.EditorsCanAdmin = true
|
||||
|
||||
teamName := "team foo"
|
||||
|
||||
Reference in New Issue
Block a user