RBAC: Improve performance of dashboard filter query (#56813)

* RBAC: Move UserRolesFilter to domain package

* Dashboard Permissions: Rewrite rbac filter to check access in sql

* RBAC: Add break when wildcard is found

* RBAC: Add tests for dashboard filter

* RBAC: Update tests

* RBAC: Cover more test cases

Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>
This commit is contained in:
Karl Persson
2022-10-25 11:14:27 +02:00
committed by GitHub
co-authored by Ieva
parent d2a70bc42d
commit 7386f8652c
6 changed files with 525 additions and 199 deletions
@@ -5,7 +5,9 @@ import (
"fmt"
"strings"
"testing"
"time"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -407,13 +409,15 @@ func TestIntegrationAnnotationListingWithRBAC(t *testing.T) {
t.Skip("skipping integration test")
}
sql := db.InitTestDB(t)
var maximumTagsLength int64 = 60
repo := xormRepositoryImpl{db: sql, cfg: setting.NewCfg(), log: log.New("annotation.test"), tagService: tagimpl.ProvideService(sql, sql.Cfg), maximumTagsLength: maximumTagsLength}
dashboardStore := dashboardstore.ProvideDashboardStore(sql, sql.Cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sql, sql.Cfg))
testDashboard1 := models.SaveDashboardCommand{
UserId: 1,
OrgId: 1,
UserId: 1,
OrgId: 1,
IsFolder: false,
Dashboard: simplejson.NewFromAny(map[string]interface{}{
"title": "Dashboard 1",
}),
@@ -459,6 +463,7 @@ func TestIntegrationAnnotationListingWithRBAC(t *testing.T) {
UserID: 1,
OrgID: 1,
}
role := setupRBACRole(t, repo, user)
type testStruct struct {
description string
@@ -519,6 +524,8 @@ func TestIntegrationAnnotationListingWithRBAC(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) {
user.Permissions = map[int64]map[string][]string{1: tc.permissions}
setupRBACPermission(t, repo, role, user)
results, err := repo.Get(context.Background(), &annotations.ItemQuery{
OrgId: 1,
SignedInUser: user,
@@ -535,3 +542,61 @@ func TestIntegrationAnnotationListingWithRBAC(t *testing.T) {
})
}
}
func setupRBACRole(t *testing.T, repo xormRepositoryImpl, user *user.SignedInUser) *accesscontrol.Role {
t.Helper()
var role *accesscontrol.Role
err := repo.db.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
role = &accesscontrol.Role{
OrgID: user.OrgID,
UID: "test_role",
Name: "test:role",
Updated: time.Now(),
Created: time.Now(),
}
_, err := sess.Insert(role)
if err != nil {
return err
}
_, err = sess.Insert(accesscontrol.UserRole{
OrgID: role.OrgID,
RoleID: role.ID,
UserID: user.UserID,
Created: time.Now(),
})
if err != nil {
return err
}
return nil
})
require.NoError(t, err)
return role
}
func setupRBACPermission(t *testing.T, repo xormRepositoryImpl, role *accesscontrol.Role, user *user.SignedInUser) {
t.Helper()
err := repo.db.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
if _, err := sess.Exec("DELETE FROM permission WHERE role_id = ?", role.ID); err != nil {
return err
}
var acPermission []accesscontrol.Permission
for action, scopes := range user.Permissions[user.OrgID] {
for _, scope := range scopes {
acPermission = append(acPermission, accesscontrol.Permission{
RoleID: role.ID, Action: action, Scope: scope, Created: time.Now(), Updated: time.Now(),
})
}
}
if _, err := sess.InsertMulti(&acPermission); err != nil {
return err
}
return nil
})
require.NoError(t, err)
}