Chore: Refactor quota service (#58643)

Chore: Refactor quota service (#57586)

* Chore: refactore quota service

* Apply suggestions from code review
This commit is contained in:
Sofia Papagiannaki
2022-11-14 21:08:10 +02:00
committed by GitHub
parent dd0d034796
commit 9855e74b92
99 changed files with 2596 additions and 1398 deletions
+1 -1
View File
@@ -250,7 +250,7 @@ func (hs *HTTPServer) AdminDeleteUser(c *models.ReqContext) response.Response {
return nil
})
g.Go(func() error {
if err := hs.QuotaService.DeleteByUser(ctx, cmd.UserID); err != nil {
if err := hs.QuotaService.DeleteQuotaForUser(ctx, cmd.UserID); err != nil {
return err
}
return nil
+13 -9
View File
@@ -36,12 +36,16 @@ 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/apikey"
"github.com/grafana/grafana/pkg/services/auth"
"github.com/grafana/grafana/pkg/services/correlations"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/org"
publicdashboardsapi "github.com/grafana/grafana/pkg/services/publicdashboards/api"
"github.com/grafana/grafana/pkg/services/serviceaccounts"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
)
@@ -69,8 +73,8 @@ func (hs *HTTPServer) registerRoutes() {
// not logged in views
r.Get("/logout", hs.Logout)
r.Post("/login", quota("session"), routing.Wrap(hs.LoginPost))
r.Get("/login/:name", quota("session"), hs.OAuthLogin)
r.Post("/login", quota(string(auth.QuotaTargetSrv)), routing.Wrap(hs.LoginPost))
r.Get("/login/:name", quota(string(auth.QuotaTargetSrv)), hs.OAuthLogin)
r.Get("/login", hs.LoginView)
r.Get("/invite/:code", hs.Index)
@@ -173,7 +177,7 @@ func (hs *HTTPServer) registerRoutes() {
r.Get("/verify", hs.Index)
r.Get("/signup", hs.Index)
r.Get("/api/user/signup/options", routing.Wrap(GetSignUpOptions))
r.Post("/api/user/signup", quota("user"), routing.Wrap(hs.SignUp))
r.Post("/api/user/signup", quota(user.QuotaTargetSrv), quota(org.QuotaTargetSrv), routing.Wrap(hs.SignUp))
r.Post("/api/user/signup/step2", routing.Wrap(hs.SignUpStep2))
// invited
@@ -192,7 +196,7 @@ func (hs *HTTPServer) registerRoutes() {
r.Get("/dashboard/snapshots/", reqSignedIn, hs.Index)
// api renew session based on cookie
r.Get("/api/login/ping", quota("session"), routing.Wrap(hs.LoginAPIPing))
r.Get("/api/login/ping", quota(string(auth.QuotaTargetSrv)), routing.Wrap(hs.LoginAPIPing))
// expose plugin file system assets
r.Get("/public/plugins/:pluginId/*", hs.getPluginAssets)
@@ -298,13 +302,13 @@ func (hs *HTTPServer) registerRoutes() {
orgRoute.Put("/address", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionOrgsWrite)), routing.Wrap(hs.UpdateCurrentOrgAddress))
orgRoute.Get("/users", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionOrgUsersRead)), routing.Wrap(hs.GetOrgUsersForCurrentOrg))
orgRoute.Get("/users/search", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionOrgUsersRead)), routing.Wrap(hs.SearchOrgUsersWithPaging))
orgRoute.Post("/users", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionOrgUsersAdd, ac.ScopeUsersAll)), quota("user"), routing.Wrap(hs.AddOrgUserToCurrentOrg))
orgRoute.Post("/users", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionOrgUsersAdd, ac.ScopeUsersAll)), quota(user.QuotaTargetSrv), quota(org.QuotaTargetSrv), routing.Wrap(hs.AddOrgUserToCurrentOrg))
orgRoute.Patch("/users/:userId", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionOrgUsersWrite, userIDScope)), routing.Wrap(hs.UpdateOrgUserForCurrentOrg))
orgRoute.Delete("/users/:userId", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionOrgUsersRemove, userIDScope)), routing.Wrap(hs.RemoveOrgUserForCurrentOrg))
// invites
orgRoute.Get("/invites", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionOrgUsersAdd)), routing.Wrap(hs.GetPendingOrgInvites))
orgRoute.Post("/invites", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionOrgUsersAdd)), quota("user"), routing.Wrap(hs.AddOrgInvite))
orgRoute.Post("/invites", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionOrgUsersAdd)), quota(user.QuotaTargetSrv), quota(user.QuotaTargetSrv), routing.Wrap(hs.AddOrgInvite))
orgRoute.Patch("/invites/:code/revoke", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionOrgUsersAdd)), routing.Wrap(hs.RevokeInvite))
// prefs
@@ -331,7 +335,7 @@ func (hs *HTTPServer) registerRoutes() {
})
// create new org
apiRoute.Post("/orgs", authorizeInOrg(reqSignedIn, ac.UseGlobalOrg, ac.EvalPermission(ac.ActionOrgsCreate)), quota("org"), routing.Wrap(hs.CreateOrg))
apiRoute.Post("/orgs", authorizeInOrg(reqSignedIn, ac.UseGlobalOrg, ac.EvalPermission(ac.ActionOrgsCreate)), quota(org.QuotaTargetSrv), routing.Wrap(hs.CreateOrg))
// search all orgs
apiRoute.Get("/orgs", authorizeInOrg(reqGrafanaAdmin, ac.UseGlobalOrg, ac.EvalPermission(ac.ActionOrgsRead)), routing.Wrap(hs.SearchOrgs))
@@ -358,7 +362,7 @@ func (hs *HTTPServer) registerRoutes() {
apiRoute.Group("/auth/keys", func(keysRoute routing.RouteRegister) {
apikeyIDScope := ac.Scope("apikeys", "id", ac.Parameter(":id"))
keysRoute.Get("/", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionAPIKeyRead)), routing.Wrap(hs.GetAPIKeys))
keysRoute.Post("/", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionAPIKeyCreate)), quota("api_key"), routing.Wrap(hs.AddAPIKey))
keysRoute.Post("/", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionAPIKeyCreate)), quota(string(apikey.QuotaTargetSrv)), routing.Wrap(hs.AddAPIKey))
keysRoute.Delete("/:id", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionAPIKeyDelete, apikeyIDScope)), routing.Wrap(hs.DeleteAPIKey))
})
@@ -373,7 +377,7 @@ func (hs *HTTPServer) registerRoutes() {
uidScope := datasources.ScopeProvider.GetResourceScopeUID(ac.Parameter(":uid"))
nameScope := datasources.ScopeProvider.GetResourceScopeName(ac.Parameter(":name"))
datasourceRoute.Get("/", authorize(reqOrgAdmin, ac.EvalPermission(datasources.ActionRead)), routing.Wrap(hs.GetDataSources))
datasourceRoute.Post("/", authorize(reqOrgAdmin, ac.EvalPermission(datasources.ActionCreate)), quota("data_source"), routing.Wrap(hs.AddDataSource))
datasourceRoute.Post("/", authorize(reqOrgAdmin, ac.EvalPermission(datasources.ActionCreate)), quota(string(datasources.QuotaTargetSrv)), routing.Wrap(hs.AddDataSource))
datasourceRoute.Put("/:id", authorize(reqOrgAdmin, ac.EvalPermission(datasources.ActionWrite, idScope)), routing.Wrap(hs.UpdateDataSourceByID))
datasourceRoute.Put("/uid/:uid", authorize(reqOrgAdmin, ac.EvalPermission(datasources.ActionWrite, uidScope)), routing.Wrap(hs.UpdateDataSourceByUID))
datasourceRoute.Delete("/:id", authorize(reqOrgAdmin, ac.EvalPermission(datasources.ActionDelete, idScope)), routing.Wrap(hs.DeleteDataSourceById))
+9 -9
View File
@@ -45,7 +45,6 @@ import (
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/org/orgtest"
"github.com/grafana/grafana/pkg/services/preference/preftest"
"github.com/grafana/grafana/pkg/services/quota/quotaimpl"
"github.com/grafana/grafana/pkg/services/quota/quotatest"
"github.com/grafana/grafana/pkg/services/rendering"
"github.com/grafana/grafana/pkg/services/search"
@@ -249,15 +248,13 @@ func (s *fakeRenderService) Init() error {
}
func setupAccessControlScenarioContext(t *testing.T, cfg *setting.Cfg, url string, permissions []accesscontrol.Permission) (*scenarioContext, *HTTPServer) {
cfg.Quota.Enabled = false
store := db.InitTestDB(t)
store := sqlstore.InitTestDB(t)
hs := &HTTPServer{
Cfg: cfg,
Live: newTestLive(t, store),
License: &licensing.OSSLicensingService{},
Features: featuremgmt.WithFeatures(),
QuotaService: &quotaimpl.Service{Cfg: cfg},
QuotaService: quotatest.New(false, nil),
RouteRegister: routing.NewRouteRegister(),
AccessControl: accesscontrolmock.New().WithPermissions(permissions),
searchUsersService: searchusers.ProvideUsersService(filters.ProvideOSSSearchUserFilter(), usertest.NewUserServiceFake()),
@@ -376,7 +373,9 @@ func setupHTTPServerWithCfgDb(
routeRegister := routing.NewRouteRegister()
teamService := teamimpl.ProvideService(db, cfg)
cfg.IsFeatureToggleEnabled = features.IsEnabled
dashboardsStore := dashboardsstore.ProvideDashboardStore(db, cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(db, cfg))
quotaService := quotatest.New(false, nil)
dashboardsStore, err := dashboardsstore.ProvideDashboardStore(db, cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(db, cfg), quotaService)
require.NoError(t, err)
var acmock *accesscontrolmock.Mock
var ac accesscontrol.AccessControl
@@ -402,7 +401,8 @@ func setupHTTPServerWithCfgDb(
acService, err = acimpl.ProvideService(cfg, db, routeRegister, localcache.ProvideService(), featuremgmt.WithFeatures())
require.NoError(t, err)
ac = acimpl.ProvideAccessControl(cfg)
userSvc = userimpl.ProvideService(db, nil, cfg, teamimpl.ProvideService(db, cfg), localcache.ProvideService())
userSvc, err = userimpl.ProvideService(db, nil, cfg, teamimpl.ProvideService(db, cfg), localcache.ProvideService(), quotatest.New(false, nil))
require.NoError(t, err)
}
teamPermissionService, err := ossaccesscontrol.ProvideTeamPermissions(cfg, routeRegister, db, ac, license, acService, teamService, userSvc)
require.NoError(t, err)
@@ -412,7 +412,7 @@ func setupHTTPServerWithCfgDb(
Cfg: cfg,
Features: features,
Live: newTestLive(t, db),
QuotaService: &quotaimpl.Service{Cfg: cfg},
QuotaService: quotaService,
RouteRegister: routeRegister,
SQLStore: store,
License: &licensing.OSSLicensingService{},
@@ -497,7 +497,7 @@ func SetupAPITestServer(t *testing.T, opts ...APITestServerOption) *webtest.Serv
RouteRegister: routing.NewRouteRegister(),
License: &licensing.OSSLicensingService{},
Features: featuremgmt.WithFeatures(),
QuotaService: quotatest.NewQuotaServiceFake(),
QuotaService: quotatest.New(false, nil),
searchUsersService: &searchusers.OSSService{},
}
+1 -1
View File
@@ -411,7 +411,7 @@ func (hs *HTTPServer) postDashboard(c *models.ReqContext, cmd models.SaveDashboa
dash := cmd.GetDashboardModel()
newDashboard := dash.Id == 0
if newDashboard {
limitReached, err := hs.QuotaService.QuotaReached(c, "dashboard")
limitReached, err := hs.QuotaService.QuotaReached(c, dashboards.QuotaTargetSrv)
if err != nil {
return response.Error(500, "failed to get quota", err)
}
+14 -12
View File
@@ -40,7 +40,7 @@ import (
pref "github.com/grafana/grafana/pkg/services/preference"
"github.com/grafana/grafana/pkg/services/preference/preftest"
"github.com/grafana/grafana/pkg/services/provisioning"
"github.com/grafana/grafana/pkg/services/quota/quotaimpl"
"github.com/grafana/grafana/pkg/services/quota/quotatest"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
@@ -151,6 +151,7 @@ func TestDashboardAPIEndpoint(t *testing.T) {
DashboardService: dashboardService,
dashboardVersionService: fakeDashboardVersionService,
Kinds: corekind.NewBase(nil),
QuotaService: quotatest.New(false, nil),
}
setUp := func() {
@@ -991,9 +992,12 @@ func getDashboardShouldReturn200WithConfig(t *testing.T, sc *scenarioContext, pr
provisioningService = provisioning.NewProvisioningServiceMock(context.Background())
}
var err error
if dashboardStore == nil {
sql := db.InitTestDB(t)
dashboardStore = database.ProvideDashboardStore(sql, sql.Cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sql, sql.Cfg))
quotaService := quotatest.New(false, nil)
dashboardStore, err = database.ProvideDashboardStore(sql, sql.Cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sql, sql.Cfg), quotaService)
require.NoError(t, err)
}
libraryPanelsService := mockLibraryPanelService{}
@@ -1032,7 +1036,7 @@ func getDashboardShouldReturn200WithConfig(t *testing.T, sc *scenarioContext, pr
require.Equal(sc.t, 200, sc.resp.Code)
dash := dtos.DashboardFullWithMeta{}
err := json.NewDecoder(sc.resp.Body).Decode(&dash)
err = json.NewDecoder(sc.resp.Body).Decode(&dash)
require.NoError(sc.t, err)
return dash
@@ -1078,12 +1082,10 @@ func postDashboardScenario(t *testing.T, desc string, url string, routePattern s
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
cfg := setting.NewCfg()
hs := HTTPServer{
Cfg: cfg,
ProvisioningService: provisioning.NewProvisioningServiceMock(context.Background()),
Live: newTestLive(t, db.InitTestDB(t)),
QuotaService: &quotaimpl.Service{
Cfg: cfg,
},
Cfg: cfg,
ProvisioningService: provisioning.NewProvisioningServiceMock(context.Background()),
Live: newTestLive(t, db.InitTestDB(t)),
QuotaService: quotatest.New(false, nil),
pluginStore: &plugins.FakePluginStore{},
LibraryPanelService: &mockLibraryPanelService{},
LibraryElementService: &mockLibraryElementService{},
@@ -1117,7 +1119,7 @@ func postValidateScenario(t *testing.T, desc string, url string, routePattern st
Cfg: cfg,
ProvisioningService: provisioning.NewProvisioningServiceMock(context.Background()),
Live: newTestLive(t, db.InitTestDB(t)),
QuotaService: &quotaimpl.Service{Cfg: cfg},
QuotaService: quotatest.New(false, nil),
LibraryPanelService: &mockLibraryPanelService{},
LibraryElementService: &mockLibraryElementService{},
SQLStore: sqlmock,
@@ -1153,7 +1155,7 @@ func postDiffScenario(t *testing.T, desc string, url string, routePattern string
Cfg: cfg,
ProvisioningService: provisioning.NewProvisioningServiceMock(context.Background()),
Live: newTestLive(t, db.InitTestDB(t)),
QuotaService: &quotaimpl.Service{Cfg: cfg},
QuotaService: quotatest.New(false, nil),
LibraryPanelService: &mockLibraryPanelService{},
LibraryElementService: &mockLibraryElementService{},
SQLStore: sqlmock,
@@ -1191,7 +1193,7 @@ func restoreDashboardVersionScenario(t *testing.T, desc string, url string, rout
Cfg: cfg,
ProvisioningService: provisioning.NewProvisioningServiceMock(context.Background()),
Live: newTestLive(t, db.InitTestDB(t)),
QuotaService: &quotaimpl.Service{Cfg: cfg},
QuotaService: quotatest.New(false, nil),
LibraryPanelService: &mockLibraryPanelService{},
LibraryElementService: &mockLibraryElementService{},
DashboardService: mock,
+1 -1
View File
@@ -145,7 +145,7 @@ func TestHTTPServer_FolderMetadata(t *testing.T) {
server := SetupAPITestServer(t, func(hs *HTTPServer) {
hs.folderService = folderService
hs.AccessControl = acmock.New()
hs.QuotaService = quotatest.NewQuotaServiceFake()
hs.QuotaService = quotatest.New(false, nil)
})
t.Run("Should attach access control metadata to multiple folders", func(t *testing.T) {
+4 -4
View File
@@ -94,12 +94,12 @@ func TestAPIEndpoint_Metrics_QueryMetricsV2(t *testing.T) {
serverFeatureEnabled := SetupAPITestServer(t, func(hs *HTTPServer) {
hs.queryDataService = qds
hs.Features = featuremgmt.WithFeatures(featuremgmt.FlagDatasourceQueryMultiStatus, true)
hs.QuotaService = quotatest.NewQuotaServiceFake()
hs.QuotaService = quotatest.New(false, nil)
})
serverFeatureDisabled := SetupAPITestServer(t, func(hs *HTTPServer) {
hs.queryDataService = qds
hs.Features = featuremgmt.WithFeatures(featuremgmt.FlagDatasourceQueryMultiStatus, false)
hs.QuotaService = quotatest.NewQuotaServiceFake()
hs.QuotaService = quotatest.New(false, nil)
})
t.Run("Status code is 400 when data source response has an error and feature toggle is disabled", func(t *testing.T) {
@@ -142,7 +142,7 @@ func TestAPIEndpoint_Metrics_PluginDecryptionFailure(t *testing.T) {
)
httpServer := SetupAPITestServer(t, func(hs *HTTPServer) {
hs.queryDataService = qds
hs.QuotaService = quotatest.NewQuotaServiceFake()
hs.QuotaService = quotatest.New(false, nil)
})
t.Run("Status code is 500 and a secrets plugin error is returned if there is a problem getting secrets from the remote plugin", func(t *testing.T) {
@@ -294,7 +294,7 @@ func TestDataSourceQueryError(t *testing.T) {
pluginClient.ProvideService(r, &config.Cfg{}),
&fakeOAuthTokenService{},
)
hs.QuotaService = quotatest.NewQuotaServiceFake()
hs.QuotaService = quotatest.New(false, nil)
})
req := srv.NewPostRequest("/api/ds/query", strings.NewReader(tc.request))
webtest.RequestWithSignedInUser(req, &user.SignedInUser{UserID: 1, OrgID: 1, OrgRole: org.RoleViewer})
+11 -4
View File
@@ -11,6 +11,7 @@ import (
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/org/orgimpl"
"github.com/grafana/grafana/pkg/services/quota/quotatest"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user/usertest"
"github.com/grafana/grafana/pkg/setting"
@@ -104,7 +105,8 @@ func TestAPIEndpoint_PutCurrentOrg_LegacyAccessControl(t *testing.T) {
})
setInitCtxSignedInOrgAdmin(sc.initCtx)
sc.hs.orgService = orgimpl.ProvideService(sc.db, sc.cfg)
sc.hs.orgService, err = orgimpl.ProvideService(sc.db, sc.cfg, quotatest.New(false, nil))
require.NoError(t, err)
t.Run("Admin can update current org", func(t *testing.T) {
response := callAPI(sc.server, http.MethodPut, putCurrentOrgURL, input, t)
assert.Equal(t, http.StatusOK, response.Code)
@@ -118,7 +120,8 @@ func TestAPIEndpoint_PutCurrentOrg_AccessControl(t *testing.T) {
_, err := sc.db.CreateOrgWithMember("TestOrg", sc.initCtx.UserID)
require.NoError(t, err)
sc.hs.orgService = orgimpl.ProvideService(sc.db, sc.cfg)
sc.hs.orgService, err = orgimpl.ProvideService(sc.db, sc.cfg, quotatest.New(false, nil))
require.NoError(t, err)
input := strings.NewReader(testUpdateOrgNameForm)
t.Run("AccessControl allows updating current org with correct permissions", func(t *testing.T) {
@@ -436,7 +439,9 @@ func TestAPIEndpoint_PutOrg_LegacyAccessControl(t *testing.T) {
cfg.RBACEnabled = false
sc := setupHTTPServerWithCfg(t, true, cfg)
setInitCtxSignedInViewer(sc.initCtx)
sc.hs.orgService = orgimpl.ProvideService(sc.db, sc.cfg)
var err error
sc.hs.orgService, err = orgimpl.ProvideService(sc.db, sc.cfg, quotatest.New(false, nil))
require.NoError(t, err)
// Create two orgs, to update another one than the logged in one
setupOrgsDBForAccessControlTests(t, sc.db, sc, 2)
@@ -456,7 +461,9 @@ func TestAPIEndpoint_PutOrg_LegacyAccessControl(t *testing.T) {
func TestAPIEndpoint_PutOrg_AccessControl(t *testing.T) {
sc := setupHTTPServer(t, true)
sc.hs.orgService = orgimpl.ProvideService(sc.db, sc.cfg)
var err error
sc.hs.orgService, err = orgimpl.ProvideService(sc.db, sc.cfg, quotatest.New(false, nil))
require.NoError(t, err)
// Create two orgs, to update another one than the logged in one
setupOrgsDBForAccessControlTests(t, sc.db, sc, 2)
+37 -23
View File
@@ -22,6 +22,7 @@ import (
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/org/orgimpl"
"github.com/grafana/grafana/pkg/services/org/orgtest"
"github.com/grafana/grafana/pkg/services/quota/quotatest"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/team/teamimpl"
@@ -389,11 +390,13 @@ func TestGetOrgUsersAPIEndpoint_AccessControlMetadata(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
cfg := setting.NewCfg()
cfg.RBACEnabled = tc.enableAccessControl
var err error
sc := setupHTTPServerWithCfg(t, false, cfg, func(hs *HTTPServer) {
hs.userService = userimpl.ProvideService(
hs.SQLStore, nil, cfg, teamimpl.ProvideService(hs.SQLStore.(*sqlstore.SQLStore), cfg), localcache.ProvideService(),
)
hs.orgService = orgimpl.ProvideService(hs.SQLStore, cfg)
hs.userService, err = userimpl.ProvideService(
hs.SQLStore, nil, cfg, teamimpl.ProvideService(hs.SQLStore.(*sqlstore.SQLStore), cfg), localcache.ProvideService(), quotatest.New(false, nil))
require.NoError(t, err)
hs.orgService, err = orgimpl.ProvideService(hs.SQLStore, cfg, quotatest.New(false, nil))
require.NoError(t, err)
})
setupOrgUsersDBForAccessControlTests(t, sc.db)
setInitCtxSignedInUser(sc.initCtx, tc.user)
@@ -403,7 +406,7 @@ func TestGetOrgUsersAPIEndpoint_AccessControlMetadata(t *testing.T) {
require.Equal(t, tc.expectedCode, response.Code)
var userList []*models.OrgUserDTO
err := json.NewDecoder(response.Body).Decode(&userList)
err = json.NewDecoder(response.Body).Decode(&userList)
require.NoError(t, err)
if tc.expectedMetadata != nil {
@@ -493,11 +496,14 @@ func TestGetOrgUsersAPIEndpoint_AccessControl(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
cfg := setting.NewCfg()
cfg.RBACEnabled = tc.enableAccessControl
var err error
sc := setupHTTPServerWithCfg(t, false, cfg, func(hs *HTTPServer) {
hs.userService = userimpl.ProvideService(
hs.SQLStore, nil, cfg, teamimpl.ProvideService(hs.SQLStore.(*sqlstore.SQLStore), cfg), localcache.ProvideService(),
)
hs.orgService = orgimpl.ProvideService(hs.SQLStore, cfg)
quotaService := quotatest.New(false, nil)
hs.userService, err = userimpl.ProvideService(
hs.SQLStore, nil, cfg, teamimpl.ProvideService(hs.SQLStore.(*sqlstore.SQLStore), cfg), localcache.ProvideService(), quotaService)
require.NoError(t, err)
hs.orgService, err = orgimpl.ProvideService(hs.SQLStore, cfg, quotaService)
require.NoError(t, err)
})
setInitCtxSignedInUser(sc.initCtx, tc.user)
setupOrgUsersDBForAccessControlTests(t, sc.db)
@@ -598,10 +604,11 @@ func TestPostOrgUsersAPIEndpoint_AccessControl(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
cfg := setting.NewCfg()
cfg.RBACEnabled = tc.enableAccessControl
var err error
sc := setupHTTPServerWithCfg(t, false, cfg, func(hs *HTTPServer) {
hs.userService = userimpl.ProvideService(
hs.SQLStore, nil, cfg, teamimpl.ProvideService(hs.SQLStore.(*sqlstore.SQLStore), cfg), localcache.ProvideService(),
)
hs.userService, err = userimpl.ProvideService(
hs.SQLStore, nil, cfg, teamimpl.ProvideService(hs.SQLStore.(*sqlstore.SQLStore), cfg), localcache.ProvideService(), quotatest.New(false, nil))
require.NoError(t, err)
})
setupOrgUsersDBForAccessControlTests(t, sc.db)
@@ -716,11 +723,12 @@ func TestOrgUsersAPIEndpointWithSetPerms_AccessControl(t *testing.T) {
for _, test := range tests {
t.Run(test.desc, func(t *testing.T) {
var err error
sc := setupHTTPServer(t, true, func(hs *HTTPServer) {
hs.tempUserService = tempuserimpl.ProvideService(hs.SQLStore)
hs.userService = userimpl.ProvideService(
hs.SQLStore, nil, setting.NewCfg(), teamimpl.ProvideService(hs.SQLStore.(*sqlstore.SQLStore), setting.NewCfg()), localcache.ProvideService(),
)
hs.userService, err = userimpl.ProvideService(
hs.SQLStore, nil, setting.NewCfg(), teamimpl.ProvideService(hs.SQLStore.(*sqlstore.SQLStore), setting.NewCfg()), localcache.ProvideService(), quotatest.New(false, nil))
require.NoError(t, err)
})
setInitCtxSignedInViewer(sc.initCtx)
setupOrgUsersDBForAccessControlTests(t, sc.db)
@@ -835,11 +843,14 @@ func TestPatchOrgUsersAPIEndpoint_AccessControl(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
cfg := setting.NewCfg()
cfg.RBACEnabled = tc.enableAccessControl
var err error
sc := setupHTTPServerWithCfg(t, false, cfg, func(hs *HTTPServer) {
hs.userService = userimpl.ProvideService(
hs.SQLStore, nil, cfg, teamimpl.ProvideService(hs.SQLStore.(*sqlstore.SQLStore), cfg), localcache.ProvideService(),
)
hs.orgService = orgimpl.ProvideService(hs.SQLStore, cfg)
quotaService := quotatest.New(false, nil)
hs.userService, err = userimpl.ProvideService(
hs.SQLStore, nil, cfg, teamimpl.ProvideService(hs.SQLStore.(*sqlstore.SQLStore), cfg), localcache.ProvideService(), quotaService)
require.NoError(t, err)
hs.orgService, err = orgimpl.ProvideService(hs.SQLStore, cfg, quotaService)
require.NoError(t, err)
})
setupOrgUsersDBForAccessControlTests(t, sc.db)
setInitCtxSignedInUser(sc.initCtx, tc.user)
@@ -962,11 +973,14 @@ func TestDeleteOrgUsersAPIEndpoint_AccessControl(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
cfg := setting.NewCfg()
cfg.RBACEnabled = tc.enableAccessControl
var err error
sc := setupHTTPServerWithCfg(t, false, cfg, func(hs *HTTPServer) {
hs.userService = userimpl.ProvideService(
hs.SQLStore, nil, cfg, teamimpl.ProvideService(hs.SQLStore.(*sqlstore.SQLStore), cfg), localcache.ProvideService(),
)
hs.orgService = orgimpl.ProvideService(hs.SQLStore, cfg)
quotaService := quotatest.New(false, nil)
hs.userService, err = userimpl.ProvideService(
hs.SQLStore, nil, cfg, teamimpl.ProvideService(hs.SQLStore.(*sqlstore.SQLStore), cfg), localcache.ProvideService(), quotaService)
require.NoError(t, err)
hs.orgService, err = orgimpl.ProvideService(hs.SQLStore, cfg, quotaService)
require.NoError(t, err)
})
setupOrgUsersDBForAccessControlTests(t, sc.db)
setInitCtxSignedInUser(sc.initCtx, tc.user)
+1 -1
View File
@@ -41,7 +41,7 @@ func TestGetPluginDashboards(t *testing.T) {
s := SetupAPITestServer(t, func(hs *HTTPServer) {
hs.pluginDashboardService = pluginDashboardService
hs.QuotaService = quotatest.NewQuotaServiceFake()
hs.QuotaService = quotatest.New(false, nil)
})
t.Run("Not signed in should return 404 Not Found", func(t *testing.T) {
+88 -30
View File
@@ -32,6 +32,7 @@ import (
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/oauthtoken"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/quota/quotatest"
"github.com/grafana/grafana/pkg/services/secrets"
"github.com/grafana/grafana/pkg/services/secrets/fakes"
secretskvs "github.com/grafana/grafana/pkg/services/secrets/kvstore"
@@ -138,7 +139,9 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
t.Run("When matching route path", func(t *testing.T) {
ctx, req := setUp()
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
proxy, err := NewDataSourceProxy(ds, routes, ctx, "api/v4/some/method", cfg, httpClientProvider,
&oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
@@ -151,7 +154,9 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
t.Run("When matching route path and has dynamic url", func(t *testing.T) {
ctx, req := setUp()
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
proxy, err := NewDataSourceProxy(ds, routes, ctx, "api/common/some/method", cfg, httpClientProvider, &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
proxy.matchedRoute = routes[3]
@@ -163,7 +168,9 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
t.Run("When matching route path with no url", func(t *testing.T) {
ctx, req := setUp()
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
proxy, err := NewDataSourceProxy(ds, routes, ctx, "", cfg, httpClientProvider, &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
proxy.matchedRoute = routes[4]
@@ -174,7 +181,9 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
t.Run("When matching route path and has dynamic body", func(t *testing.T) {
ctx, req := setUp()
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
proxy, err := NewDataSourceProxy(ds, routes, ctx, "api/body", cfg, httpClientProvider, &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
proxy.matchedRoute = routes[5]
@@ -188,7 +197,9 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
t.Run("Validating request", func(t *testing.T) {
t.Run("plugin route with valid role", func(t *testing.T) {
ctx, _ := setUp()
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
proxy, err := NewDataSourceProxy(ds, routes, ctx, "api/v4/some/method", cfg, httpClientProvider, &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
err = proxy.validateRequest()
@@ -197,7 +208,9 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
t.Run("plugin route with admin role and user is editor", func(t *testing.T) {
ctx, _ := setUp()
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
proxy, err := NewDataSourceProxy(ds, routes, ctx, "api/admin", cfg, httpClientProvider, &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
err = proxy.validateRequest()
@@ -207,7 +220,9 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
t.Run("plugin route with admin role and user is admin", func(t *testing.T) {
ctx, _ := setUp()
ctx.SignedInUser.OrgRole = org.RoleAdmin
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
proxy, err := NewDataSourceProxy(ds, routes, ctx, "api/admin", cfg, httpClientProvider, &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
err = proxy.validateRequest()
@@ -298,7 +313,9 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
},
}
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
proxy, err := NewDataSourceProxy(ds, routes, ctx, "pathwithtoken1", cfg, httpClientProvider, &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
ApplyRoute(proxy.ctx.Req.Context(), req, proxy.proxyPath, routes[0], dsInfo, cfg)
@@ -314,7 +331,9 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
req, err := http.NewRequest("GET", "http://localhost/asd", nil)
require.NoError(t, err)
client = newFakeHTTPClient(t, json2)
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
proxy, err := NewDataSourceProxy(ds, routes, ctx, "pathwithtoken2", cfg, httpClientProvider, &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
ApplyRoute(proxy.ctx.Req.Context(), req, proxy.proxyPath, routes[1], dsInfo, cfg)
@@ -331,7 +350,9 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
require.NoError(t, err)
client = newFakeHTTPClient(t, []byte{})
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
proxy, err := NewDataSourceProxy(ds, routes, ctx, "pathwithtoken1", cfg, httpClientProvider, &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
ApplyRoute(proxy.ctx.Req.Context(), req, proxy.proxyPath, routes[0], dsInfo, cfg)
@@ -355,7 +376,9 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
sqlStore := db.InitTestDB(t)
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
proxy, err := NewDataSourceProxy(ds, routes, ctx, "/render", &setting.Cfg{BuildVersion: "5.3.0"}, httpClientProvider, &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
req, err := http.NewRequest(http.MethodGet, "http://grafana.com/sub", nil)
@@ -382,7 +405,9 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
sqlStore := db.InitTestDB(t)
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
proxy, err := NewDataSourceProxy(ds, routes, ctx, "", &setting.Cfg{}, httpClientProvider, &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
@@ -408,7 +433,9 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
sqlStore := db.InitTestDB(t)
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
proxy, err := NewDataSourceProxy(ds, routes, ctx, "", &setting.Cfg{}, httpClientProvider, &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
@@ -438,7 +465,9 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
sqlStore := db.InitTestDB(t)
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
proxy, err := NewDataSourceProxy(ds, pluginRoutes, ctx, "", &setting.Cfg{}, httpClientProvider, &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
@@ -463,7 +492,9 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
sqlStore := db.InitTestDB(t)
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
proxy, err := NewDataSourceProxy(ds, routes, ctx, "/path/to/folder/", &setting.Cfg{}, httpClientProvider, &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
req, err := http.NewRequest(http.MethodGet, "http://grafana.com/sub", nil)
@@ -514,7 +545,9 @@ func TestDataSourceProxy_routeRule(t *testing.T) {
sqlStore := db.InitTestDB(t)
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
proxy, err := NewDataSourceProxy(ds, routes, ctx, "/path/to/folder/", &setting.Cfg{}, httpClientProvider, &mockAuthToken, dsService, tracer)
require.NoError(t, err)
req, err = http.NewRequest(http.MethodGet, "http://grafana.com/sub", nil)
@@ -651,7 +684,9 @@ func TestDataSourceProxy_requestHandling(t *testing.T) {
sqlStore := db.InitTestDB(t)
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
proxy, err := NewDataSourceProxy(ds, routes, ctx, "/render", &setting.Cfg{}, httpClientProvider, &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
@@ -671,7 +706,9 @@ func TestDataSourceProxy_requestHandling(t *testing.T) {
sqlStore := db.InitTestDB(t)
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
proxy, err := NewDataSourceProxy(ds, routes, ctx, "/render", &setting.Cfg{}, httpClientProvider, &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
@@ -687,7 +724,9 @@ func TestDataSourceProxy_requestHandling(t *testing.T) {
sqlStore := db.InitTestDB(t)
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
proxy, err := NewDataSourceProxy(ds, routes, ctx, "/render", &setting.Cfg{}, httpClientProvider, &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
@@ -711,7 +750,9 @@ func TestDataSourceProxy_requestHandling(t *testing.T) {
sqlStore := db.InitTestDB(t)
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
proxy, err := NewDataSourceProxy(ds, routes, ctx, "/render", &setting.Cfg{}, httpClientProvider, &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
@@ -738,7 +779,9 @@ func TestDataSourceProxy_requestHandling(t *testing.T) {
sqlStore := db.InitTestDB(t)
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
proxy, err := NewDataSourceProxy(ds, routes, ctx, "/path/%2Ftest%2Ftest%2F", &setting.Cfg{}, httpClientProvider, &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
@@ -764,7 +807,9 @@ func TestDataSourceProxy_requestHandling(t *testing.T) {
sqlStore := db.InitTestDB(t)
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
proxy, err := NewDataSourceProxy(ds, routes, ctx, "/path/%2Ftest%2Ftest%2F", &setting.Cfg{}, httpClientProvider, &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
@@ -790,8 +835,11 @@ func TestNewDataSourceProxy_InvalidURL(t *testing.T) {
sqlStore := db.InitTestDB(t)
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
_, err := NewDataSourceProxy(&ds, routes, &ctx, "api/method", cfg, httpclient.NewProvider(), &oauthtoken.Service{}, dsService, tracer)
quotaService := quotatest.New(false, nil)
var err error
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
_, err = NewDataSourceProxy(&ds, routes, &ctx, "api/method", cfg, httpclient.NewProvider(), &oauthtoken.Service{}, dsService, tracer)
require.Error(t, err)
assert.True(t, strings.HasPrefix(err.Error(), `validation of data source URL "://host/root" failed`))
}
@@ -812,8 +860,10 @@ func TestNewDataSourceProxy_ProtocolLessURL(t *testing.T) {
sqlStore := db.InitTestDB(t)
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
_, err := NewDataSourceProxy(&ds, routes, &ctx, "api/method", cfg, httpclient.NewProvider(), &oauthtoken.Service{}, dsService, tracer)
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
_, err = NewDataSourceProxy(&ds, routes, &ctx, "api/method", cfg, httpclient.NewProvider(), &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
}
@@ -856,7 +906,9 @@ func TestNewDataSourceProxy_MSSQL(t *testing.T) {
sqlStore := db.InitTestDB(t)
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
p, err := NewDataSourceProxy(&ds, routes, &ctx, "api/method", cfg, httpclient.NewProvider(), &oauthtoken.Service{}, dsService, tracer)
if tc.err == nil {
require.NoError(t, err)
@@ -884,7 +936,9 @@ func getDatasourceProxiedRequest(t *testing.T, ctx *models.ReqContext, cfg *sett
sqlStore := db.InitTestDB(t)
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
proxy, err := NewDataSourceProxy(ds, routes, ctx, "", cfg, httpclient.NewProvider(), &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
req, err := http.NewRequest(http.MethodGet, "http://grafana.com/sub", nil)
@@ -1001,7 +1055,9 @@ func runDatasourceAuthTest(t *testing.T, secretsService secrets.Service, secrets
tracer := tracing.InitializeTracerForTest()
var routes []*plugins.Route
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
proxy, err := NewDataSourceProxy(test.datasource, routes, ctx, "", &setting.Cfg{}, httpclient.NewProvider(), &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
@@ -1045,7 +1101,9 @@ func Test_PathCheck(t *testing.T) {
sqlStore := db.InitTestDB(t)
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
dsService := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService())
quotaService := quotatest.New(false, nil)
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), acmock.New(), acmock.NewMockedPermissionsService(), quotaService)
require.NoError(t, err)
proxy, err := NewDataSourceProxy(&datasources.DataSource{}, routes, ctx, "b", &setting.Cfg{}, httpclient.NewProvider(), &oauthtoken.Service{}, dsService, tracer)
require.NoError(t, err)
+1 -1
View File
@@ -60,7 +60,7 @@ func Test_PluginsInstallAndUninstall(t *testing.T) {
PluginAdminExternalManageEnabled: tc.pluginAdminExternalManageEnabled,
}
hs.pluginInstaller = inst
hs.QuotaService = quotatest.NewQuotaServiceFake()
hs.QuotaService = quotatest.New(false, nil)
})
t.Run(testName("Install", tc), func(t *testing.T) {
+38 -50
View File
@@ -6,10 +6,22 @@ import (
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/services/quota"
"github.com/grafana/grafana/pkg/web"
)
// swagger:route GET /org/quotas getCurrentOrg getCurrentOrgQuota
//
// Fetch Organization quota.
//
// If you are running Grafana Enterprise and have Fine-grained access control enabled, you need to have a permission with action `orgs.quotas:read` and scope `org:id:1` (orgIDScope).
//
// Responses:
// 200: getQuotaResponse
// 401: unauthorisedError
// 403: forbiddenError
// 404: notFoundError
// 500: internalServerError
func (hs *HTTPServer) GetCurrentOrgQuotas(c *models.ReqContext) response.Response {
return hs.getOrgQuotasHelper(c, c.OrgID)
}
@@ -29,22 +41,17 @@ func (hs *HTTPServer) GetCurrentOrgQuotas(c *models.ReqContext) response.Respons
func (hs *HTTPServer) GetOrgQuotas(c *models.ReqContext) response.Response {
orgId, err := strconv.ParseInt(web.Params(c.Req)[":orgId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "orgId is invalid", err)
return response.Err(quota.ErrBadRequest.Errorf("orgId is invalid: %w", err))
}
return hs.getOrgQuotasHelper(c, orgId)
}
func (hs *HTTPServer) getOrgQuotasHelper(c *models.ReqContext, orgID int64) response.Response {
if !hs.Cfg.Quota.Enabled {
return response.Error(404, "Quotas not enabled", nil)
q, err := hs.QuotaService.GetQuotasByScope(c.Req.Context(), quota.OrgScope, orgID)
if err != nil {
return response.ErrOrFallback(http.StatusInternalServerError, "failed to get quota", err)
}
query := models.GetOrgQuotasQuery{OrgId: orgID}
if err := hs.SQLStore.GetOrgQuotas(c.Req.Context(), &query); err != nil {
return response.Error(500, "Failed to get org quotas", err)
}
return response.JSON(http.StatusOK, query.Result)
return response.JSON(http.StatusOK, q)
}
// swagger:route PUT /orgs/{org_id}/quotas/{quota_target} orgs updateOrgQuota
@@ -63,26 +70,19 @@ func (hs *HTTPServer) getOrgQuotasHelper(c *models.ReqContext, orgID int64) resp
// 404: notFoundError
// 500: internalServerError
func (hs *HTTPServer) UpdateOrgQuota(c *models.ReqContext) response.Response {
cmd := models.UpdateOrgQuotaCmd{}
cmd := quota.UpdateQuotaCmd{}
var err error
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
return response.Err(quota.ErrBadRequest.Errorf("bad request data: %w", err))
}
if !hs.Cfg.Quota.Enabled {
return response.Error(404, "Quotas not enabled", nil)
}
cmd.OrgId, err = strconv.ParseInt(web.Params(c.Req)[":orgId"], 10, 64)
cmd.OrgID, err = strconv.ParseInt(web.Params(c.Req)[":orgId"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "orgId is invalid", err)
return response.Err(quota.ErrBadRequest.Errorf("orgId is invalid: %w", err))
}
cmd.Target = web.Params(c.Req)[":target"]
if _, ok := hs.Cfg.Quota.Org.ToMap()[cmd.Target]; !ok {
return response.Error(404, "Invalid quota target", nil)
}
if err := hs.SQLStore.UpdateOrgQuota(c.Req.Context(), &cmd); err != nil {
return response.Error(500, "Failed to update org quotas", err)
if err := hs.QuotaService.Update(c.Req.Context(), &cmd); err != nil {
return response.ErrOrFallback(http.StatusInternalServerError, "Failed to update org quotas", err)
}
return response.Success("Organization quota updated")
}
@@ -114,22 +114,17 @@ func (hs *HTTPServer) UpdateOrgQuota(c *models.ReqContext) response.Response {
// 404: notFoundError
// 500: internalServerError
func (hs *HTTPServer) GetUserQuotas(c *models.ReqContext) response.Response {
if !setting.Quota.Enabled {
return response.Error(404, "Quotas not enabled", nil)
}
id, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
return response.Err(quota.ErrBadRequest.Errorf("id is invalid: %w", err))
}
query := models.GetUserQuotasQuery{UserId: id}
if err := hs.SQLStore.GetUserQuotas(c.Req.Context(), &query); err != nil {
return response.Error(500, "Failed to get org quotas", err)
q, err := hs.QuotaService.GetQuotasByScope(c.Req.Context(), quota.UserScope, id)
if err != nil {
return response.ErrOrFallback(http.StatusInternalServerError, "Failed to get org quotas", err)
}
return response.JSON(http.StatusOK, query.Result)
return response.JSON(http.StatusOK, q)
}
// swagger:route PUT /admin/users/{user_id}/quotas/{quota_target} admin_users updateUserQuota
@@ -148,26 +143,19 @@ func (hs *HTTPServer) GetUserQuotas(c *models.ReqContext) response.Response {
// 404: notFoundError
// 500: internalServerError
func (hs *HTTPServer) UpdateUserQuota(c *models.ReqContext) response.Response {
cmd := models.UpdateUserQuotaCmd{}
cmd := quota.UpdateQuotaCmd{}
var err error
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
return response.Err(quota.ErrBadRequest.Errorf("bad request data: %w", err))
}
if !setting.Quota.Enabled {
return response.Error(404, "Quotas not enabled", nil)
}
cmd.UserId, err = strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
cmd.UserID, err = strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
return response.Err(quota.ErrBadRequest.Errorf("id is invalid: %w", err))
}
cmd.Target = web.Params(c.Req)[":target"]
if _, ok := setting.Quota.User.ToMap()[cmd.Target]; !ok {
return response.Error(404, "Invalid quota target", nil)
}
if err := hs.SQLStore.UpdateUserQuota(c.Req.Context(), &cmd); err != nil {
return response.Error(500, "Failed to update org quotas", err)
if err := hs.QuotaService.Update(c.Req.Context(), &cmd); err != nil {
return response.ErrOrFallback(http.StatusInternalServerError, "Failed to update org quotas", err)
}
return response.Success("Organization quota updated")
}
@@ -176,7 +164,7 @@ func (hs *HTTPServer) UpdateUserQuota(c *models.ReqContext) response.Response {
type UpdateUserQuotaParams struct {
// in:body
// required:true
Body models.UpdateUserQuotaCmd `json:"body"`
Body quota.UpdateQuotaCmd `json:"body"`
// in:path
// required:true
QuotaTarget string `json:"quota_target"`
@@ -203,7 +191,7 @@ type GetOrgQuotaParams struct {
type UpdateOrgQuotaParam struct {
// in:body
// required:true
Body models.UpdateOrgQuotaCmd `json:"body"`
Body quota.UpdateQuotaCmd `json:"body"`
// in:path
// required:true
QuotaTarget string `json:"quota_target"`
@@ -215,5 +203,5 @@ type UpdateOrgQuotaParam struct {
// swagger:response getQuotaResponse
type GetQuotaResponseResponse struct {
// in:body
Body []*models.UserQuotaDTO `json:"body"`
Body []*quota.QuotaDTO `json:"body"`
}
+23 -8
View File
@@ -32,17 +32,13 @@ var testOrgQuota = setting.OrgQuota{
func setupDBAndSettingsForAccessControlQuotaTests(t *testing.T, sc accessControlScenarioContext) {
t.Helper()
sc.hs.Cfg.Quota.Enabled = true
sc.hs.Cfg.Quota.Org = &testOrgQuota
// Required while sqlstore quota.go relies on setting global variables
setting.Quota = sc.hs.Cfg.Quota
// Create two orgs with the context user
setupOrgsDBForAccessControlTests(t, sc.db, sc, 2)
}
func TestAPIEndpoint_GetCurrentOrgQuotas_LegacyAccessControl(t *testing.T) {
cfg := setting.NewCfg()
cfg.Quota.Enabled = true
cfg.RBACEnabled = false
sc := setupHTTPServerWithCfg(t, true, cfg)
setInitCtxSignedInViewer(sc.initCtx)
@@ -62,7 +58,9 @@ func TestAPIEndpoint_GetCurrentOrgQuotas_LegacyAccessControl(t *testing.T) {
}
func TestAPIEndpoint_GetCurrentOrgQuotas_AccessControl(t *testing.T) {
sc := setupHTTPServer(t, true)
cfg := setting.NewCfg()
cfg.Quota.Enabled = true
sc := setupHTTPServerWithCfg(t, true, cfg)
setInitCtxSignedInViewer(sc.initCtx)
setupDBAndSettingsForAccessControlQuotaTests(t, sc)
@@ -86,6 +84,7 @@ func TestAPIEndpoint_GetCurrentOrgQuotas_AccessControl(t *testing.T) {
func TestAPIEndpoint_GetOrgQuotas_LegacyAccessControl(t *testing.T) {
cfg := setting.NewCfg()
cfg.Quota.Enabled = true
cfg.RBACEnabled = false
sc := setupHTTPServerWithCfg(t, true, cfg)
setInitCtxSignedInViewer(sc.initCtx)
@@ -105,7 +104,9 @@ func TestAPIEndpoint_GetOrgQuotas_LegacyAccessControl(t *testing.T) {
}
func TestAPIEndpoint_GetOrgQuotas_AccessControl(t *testing.T) {
sc := setupHTTPServer(t, true)
cfg := setting.NewCfg()
cfg.Quota.Enabled = true
sc := setupHTTPServerWithCfg(t, true, cfg)
setupDBAndSettingsForAccessControlQuotaTests(t, sc)
t.Run("AccessControl allows viewing another org quotas with correct permissions", func(t *testing.T) {
@@ -130,6 +131,7 @@ func TestAPIEndpoint_GetOrgQuotas_AccessControl(t *testing.T) {
func TestAPIEndpoint_PutOrgQuotas_LegacyAccessControl(t *testing.T) {
cfg := setting.NewCfg()
cfg.Quota.Enabled = true
cfg.RBACEnabled = false
sc := setupHTTPServerWithCfg(t, true, cfg)
setInitCtxSignedInViewer(sc.initCtx)
@@ -151,7 +153,20 @@ func TestAPIEndpoint_PutOrgQuotas_LegacyAccessControl(t *testing.T) {
}
func TestAPIEndpoint_PutOrgQuotas_AccessControl(t *testing.T) {
sc := setupHTTPServer(t, true)
cfg := setting.NewCfg()
cfg.Quota = setting.QuotaSettings{
Enabled: true,
Global: setting.GlobalQuota{
Org: 5,
},
Org: setting.OrgQuota{
User: 5,
},
User: setting.UserQuota{
Org: 5,
},
}
sc := setupHTTPServerWithCfg(t, true, cfg)
setupDBAndSettingsForAccessControlQuotaTests(t, sc)
input := strings.NewReader(testUpdateOrgQuotaCmd)
+3 -1
View File
@@ -23,6 +23,7 @@ import (
"github.com/grafana/grafana/pkg/services/login/authinfoservice"
authinfostore "github.com/grafana/grafana/pkg/services/login/authinfoservice/database"
"github.com/grafana/grafana/pkg/services/login/logintest"
"github.com/grafana/grafana/pkg/services/quota/quotatest"
"github.com/grafana/grafana/pkg/services/searchusers"
"github.com/grafana/grafana/pkg/services/searchusers/filters"
"github.com/grafana/grafana/pkg/services/secrets/database"
@@ -71,7 +72,8 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) {
}
user, err := sqlStore.CreateUser(context.Background(), createUserCmd)
require.Nil(t, err)
hs.userService = userimpl.ProvideService(sqlStore, nil, sc.cfg, nil, nil)
hs.userService, err = userimpl.ProvideService(sqlStore, nil, sc.cfg, nil, nil, quotatest.New(false, nil))
require.NoError(t, err)
sc.handlerFunc = hs.GetUserByID