RBAC: Rewrite search and plugin list rbac test (#63483)

* API: rewrite rbac tests for search

* API: rewrite rbac tests for listing plugins

* API: remove unused rbac test setup code
This commit is contained in:
Karl Persson
2023-02-21 11:13:35 +01:00
committed by GitHub
parent 984e293d60
commit 5eaaf9b9b7
3 changed files with 103 additions and 275 deletions
-185
View File
@@ -19,29 +19,20 @@ import (
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/infra/db/dbtest"
"github.com/grafana/grafana/pkg/infra/fs"
"github.com/grafana/grafana/pkg/infra/localcache"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/remotecache"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/acimpl"
accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
"github.com/grafana/grafana/pkg/services/accesscontrol/ossaccesscontrol"
"github.com/grafana/grafana/pkg/services/annotations/annotationstest"
"github.com/grafana/grafana/pkg/services/auth/authtest"
"github.com/grafana/grafana/pkg/services/auth/jwt"
"github.com/grafana/grafana/pkg/services/authn/authntest"
"github.com/grafana/grafana/pkg/services/contexthandler"
"github.com/grafana/grafana/pkg/services/contexthandler/authproxy"
"github.com/grafana/grafana/pkg/services/contexthandler/ctxkey"
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
"github.com/grafana/grafana/pkg/services/dashboards"
dashboardsstore "github.com/grafana/grafana/pkg/services/dashboards/database"
dashboardservice "github.com/grafana/grafana/pkg/services/dashboards/service"
dashver "github.com/grafana/grafana/pkg/services/dashboardversion"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/folder/folderimpl"
"github.com/grafana/grafana/pkg/services/folder/foldertest"
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/services/ldap/service"
"github.com/grafana/grafana/pkg/services/licensing"
@@ -50,21 +41,13 @@ import (
"github.com/grafana/grafana/pkg/services/login/logintest"
"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/quotatest"
"github.com/grafana/grafana/pkg/services/rendering"
"github.com/grafana/grafana/pkg/services/search"
"github.com/grafana/grafana/pkg/services/search/model"
"github.com/grafana/grafana/pkg/services/searchusers"
"github.com/grafana/grafana/pkg/services/searchusers/filters"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest"
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
"github.com/grafana/grafana/pkg/services/team"
"github.com/grafana/grafana/pkg/services/team/teamimpl"
"github.com/grafana/grafana/pkg/services/team/teamtest"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/services/user/userimpl"
"github.com/grafana/grafana/pkg/services/user/usertest"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
@@ -255,44 +238,10 @@ func (s *fakeRenderService) Init() error {
return nil
}
// accessControlScenarioContext contains the setups for accesscontrol tests
type accessControlScenarioContext struct {
// server we registered hs routes on.
server *web.Mux
// initCtx is used in a middleware to set the initial context
// of the request server side. Can be used to pretend sign in.
initCtx *contextmodel.ReqContext
// hs is a minimal HTTPServer for the accesscontrol tests to pass.
hs *HTTPServer
// acmock is an accesscontrol mock used to fake users rights.
acmock *accesscontrolmock.Mock
// db is a test database initialized with InitTestDB
db *sqlstore.SQLStore
// cfg is the setting provider
cfg *setting.Cfg
dashboardsStore dashboards.Store
teamService team.Service
userService user.Service
folderPermissionsService *accesscontrolmock.MockPermissionsService
dashboardPermissionsService *accesscontrolmock.MockPermissionsService
}
func userWithPermissions(orgID int64, permissions []accesscontrol.Permission) *user.SignedInUser {
return &user.SignedInUser{OrgID: orgID, OrgRole: org.RoleViewer, Permissions: map[int64]map[string][]string{orgID: accesscontrol.GroupScopesByAction(permissions)}}
}
// setInitCtxSignedInUser sets a copy of the user in initCtx
func setInitCtxSignedInUser(initCtx *contextmodel.ReqContext, user user.SignedInUser) {
initCtx.IsSignedIn = true
initCtx.SignedInUser = &user
}
func setupSimpleHTTPServer(features *featuremgmt.FeatureManager) *HTTPServer {
if features == nil {
features = featuremgmt.WithFeatures()
@@ -313,140 +262,6 @@ func setupSimpleHTTPServer(features *featuremgmt.FeatureManager) *HTTPServer {
}
}
func setupHTTPServer(t *testing.T, useFakeAccessControl bool, options ...APITestServerOption) accessControlScenarioContext {
return setupHTTPServerWithCfg(t, useFakeAccessControl, setting.NewCfg(), options...)
}
func setupHTTPServerWithCfg(t *testing.T, useFakeAccessControl bool, cfg *setting.Cfg, options ...APITestServerOption) accessControlScenarioContext {
db := db.InitTestDB(t, db.InitTestDBOpt{})
return setupHTTPServerWithCfgDb(t, useFakeAccessControl, cfg, db, db, featuremgmt.WithFeatures(), options...)
}
func setupHTTPServerWithCfgDb(
t *testing.T, useFakeAccessControl bool, cfg *setting.Cfg, db *sqlstore.SQLStore,
store db.DB, features *featuremgmt.FeatureManager, options ...APITestServerOption,
) accessControlScenarioContext {
t.Helper()
license := &licensing.OSSLicensingService{}
routeRegister := routing.NewRouteRegister()
teamService := teamimpl.ProvideService(db, cfg)
cfg.IsFeatureToggleEnabled = features.IsEnabled
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
var acService accesscontrol.Service
var userSvc user.Service
userMock := usertest.NewUserServiceFake()
userMock.ExpectedUser = &user.User{ID: 1}
orgMock := orgtest.NewOrgServiceFake()
orgMock.ExpectedOrg = &org.Org{}
orgMock.ExpectedSearchOrgUsersResult = &org.SearchOrgUsersQueryResult{}
// Defining the accesscontrol service has to be done before registering routes
if useFakeAccessControl {
acmock = accesscontrolmock.New()
if !cfg.RBACEnabled {
acmock = acmock.WithDisabled()
}
ac = acmock
acService = acmock
userSvc = userMock
} else {
var err error
ac = acimpl.ProvideAccessControl(cfg)
userSvc, err = userimpl.ProvideService(db, nil, cfg, teamimpl.ProvideService(db, cfg), localcache.ProvideService(), quotatest.New(false, nil), supportbundlestest.NewFakeBundleService())
require.NoError(t, err)
acService, err = acimpl.ProvideService(cfg, db, routeRegister, localcache.ProvideService(), ac, featuremgmt.WithFeatures())
require.NoError(t, err)
}
teamPermissionService, err := ossaccesscontrol.ProvideTeamPermissions(cfg, routeRegister, db, ac, license, acService, teamService, userSvc)
require.NoError(t, err)
folderPermissionsService := accesscontrolmock.NewMockedPermissionsService()
dashboardPermissionsService := accesscontrolmock.NewMockedPermissionsService()
folderSvc := foldertest.NewFakeService()
// Create minimal HTTP Server
hs := &HTTPServer{
Cfg: cfg,
Features: features,
Live: newTestLive(t, db),
QuotaService: quotaService,
RouteRegister: routeRegister,
SQLStore: store,
License: &licensing.OSSLicensingService{},
AccessControl: ac,
accesscontrolService: acService,
teamPermissionsService: teamPermissionService,
searchUsersService: searchusers.ProvideUsersService(filters.ProvideOSSSearchUserFilter(), usertest.NewUserServiceFake()),
DashboardService: dashboardservice.ProvideDashboardService(
cfg, dashboardsStore, folderimpl.ProvideDashboardFolderStore(db), nil, features,
folderPermissionsService, dashboardPermissionsService, ac,
folderSvc,
),
preferenceService: preftest.NewPreferenceServiceFake(),
userService: userSvc,
orgService: orgMock,
teamService: teamService,
annotationsRepo: annotationstest.NewFakeAnnotationsRepo(),
authInfoService: &logintest.AuthInfoServiceFake{
ExpectedLabels: map[int64]string{int64(1): login.GetAuthProviderLabel(login.LDAPAuthModule)},
},
}
for _, o := range options {
o(hs)
}
require.NoError(t, hs.declareFixedRoles())
require.NoError(t, hs.accesscontrolService.(accesscontrol.RoleRegistry).RegisterFixedRoles(context.Background()))
// Instantiate a new Server
m := web.New()
// middleware to set the test initial context
initCtx := &contextmodel.ReqContext{}
m.Use(func(c *web.Context) {
initCtx.Context = c
initCtx.Logger = log.New("api-test")
c.Req = c.Req.WithContext(ctxkey.Set(c.Req.Context(), initCtx))
})
m.Use(accesscontrol.LoadPermissionsMiddleware(hs.accesscontrolService))
// Register all routes
hs.registerRoutes()
hs.RouteRegister.Register(m.Router)
return accessControlScenarioContext{
server: m,
initCtx: initCtx,
hs: hs,
acmock: acmock,
db: db,
cfg: cfg,
dashboardsStore: dashboardsStore,
teamService: teamService,
userService: userSvc,
dashboardPermissionsService: dashboardPermissionsService,
folderPermissionsService: folderPermissionsService,
}
}
func callAPI(server *web.Mux, method, path string, body io.Reader, t *testing.T) *httptest.ResponseRecorder {
req, err := http.NewRequest(method, path, body)
require.NoError(t, err)
req.Header.Set("Content-Type", "application/json")
recorder := httptest.NewRecorder()
server.ServeHTTP(recorder, req)
return recorder
}
func mockRequestBody(v interface{}) io.ReadCloser {
b, _ := json.Marshal(v)
return io.NopCloser(bytes.NewReader(b))