PublicDashboards: Audit table pagination (#69823)
This commit is contained in:
@@ -2,18 +2,24 @@ package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
dashboardsDB "github.com/grafana/grafana/pkg/services/dashboards/database"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
. "github.com/grafana/grafana/pkg/services/publicdashboards/models"
|
||||
"github.com/grafana/grafana/pkg/services/publicdashboards/service"
|
||||
"github.com/grafana/grafana/pkg/services/quota/quotatest"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -34,38 +40,122 @@ func TestIntegrationListPublicDashboard(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping integration test")
|
||||
}
|
||||
sqlStore, cfg := db.InitTestDBwithCfg(t, db.InitTestDBOpt{FeatureFlags: []string{featuremgmt.FlagPublicDashboards}})
|
||||
quotaService := quotatest.New(false, nil)
|
||||
dashboardStore, err := dashboardsDB.ProvideDashboardStore(sqlStore, cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore, cfg), quotaService)
|
||||
require.NoError(t, err)
|
||||
publicdashboardStore := ProvideStore(sqlStore)
|
||||
|
||||
var sqlStore *sqlstore.SQLStore
|
||||
var cfg *setting.Cfg
|
||||
|
||||
var aDash *dashboards.Dashboard
|
||||
var bDash *dashboards.Dashboard
|
||||
var cDash *dashboards.Dashboard
|
||||
|
||||
var aPublicDash *PublicDashboard
|
||||
var bPublicDash *PublicDashboard
|
||||
var cPublicDash *PublicDashboard
|
||||
|
||||
var orgId int64 = 1
|
||||
|
||||
bDash := insertTestDashboard(t, dashboardStore, "b", orgId, 0, true)
|
||||
aDash := insertTestDashboard(t, dashboardStore, "a", orgId, 0, true)
|
||||
cDash := insertTestDashboard(t, dashboardStore, "c", orgId, 0, true)
|
||||
var publicdashboardStore *PublicDashboardStoreImpl
|
||||
|
||||
// these are in order of how they should be returned from ListPUblicDashboards
|
||||
a := insertPublicDashboard(t, publicdashboardStore, aDash.UID, orgId, false, PublicShareType)
|
||||
b := insertPublicDashboard(t, publicdashboardStore, bDash.UID, orgId, true, PublicShareType)
|
||||
c := insertPublicDashboard(t, publicdashboardStore, cDash.UID, orgId, true, PublicShareType)
|
||||
setup := func() {
|
||||
sqlStore, cfg = db.InitTestDBwithCfg(t, db.InitTestDBOpt{FeatureFlags: []string{featuremgmt.FlagPublicDashboards}})
|
||||
quotaService := quotatest.New(false, nil)
|
||||
dashboardStore, err := dashboardsDB.ProvideDashboardStore(sqlStore, cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore, cfg), quotaService)
|
||||
require.NoError(t, err)
|
||||
publicdashboardStore = ProvideStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures())
|
||||
|
||||
// this is case that can happen as of now, however, postgres and mysql sort
|
||||
// null in the exact opposite fashion and there is no shared syntax to sort
|
||||
// nulls in the same way in all 3 db's.
|
||||
//d := insertPublicDashboard(t, publicdashboardStore, "missing", orgId, false)
|
||||
bDash = insertTestDashboard(t, dashboardStore, "b", orgId, 0, false)
|
||||
aDash = insertTestDashboard(t, dashboardStore, "a", orgId, 0, false)
|
||||
cDash = insertTestDashboard(t, dashboardStore, "c", orgId, 0, false)
|
||||
|
||||
// should not be included in response
|
||||
_ = insertPublicDashboard(t, publicdashboardStore, "wrongOrgId", 777, false, PublicShareType)
|
||||
// these are in order of how they should be returned from ListPUblicDashboards
|
||||
aPublicDash = insertPublicDashboard(t, publicdashboardStore, aDash.UID, orgId, false, PublicShareType)
|
||||
bPublicDash = insertPublicDashboard(t, publicdashboardStore, bDash.UID, orgId, true, PublicShareType)
|
||||
cPublicDash = insertPublicDashboard(t, publicdashboardStore, cDash.UID, orgId, true, PublicShareType)
|
||||
}
|
||||
|
||||
resp, err := publicdashboardStore.FindAll(context.Background(), orgId)
|
||||
require.NoError(t, err)
|
||||
t.Run("FindAllWithPagination will return dashboard list based on orgId with pagination", func(t *testing.T) {
|
||||
setup()
|
||||
|
||||
assert.Len(t, resp, 3)
|
||||
assert.Equal(t, resp[0].Uid, a.Uid)
|
||||
assert.Equal(t, resp[1].Uid, b.Uid)
|
||||
assert.Equal(t, resp[2].Uid, c.Uid)
|
||||
// should not be included in response
|
||||
_ = insertPublicDashboard(t, publicdashboardStore, "wrongOrgId", 777, false, PublicShareType)
|
||||
|
||||
permissions := []accesscontrol.Permission{
|
||||
{Action: dashboards.ActionDashboardsRead, Scope: fmt.Sprintf("dashboards:uid:%s", aDash.UID)},
|
||||
{Action: dashboards.ActionDashboardsRead, Scope: fmt.Sprintf("dashboards:uid:%s", bDash.UID)},
|
||||
{Action: dashboards.ActionDashboardsRead, Scope: fmt.Sprintf("dashboards:uid:%s", cDash.UID)},
|
||||
}
|
||||
|
||||
err := insertPermissions(sqlStore, orgId, "viewer", permissions)
|
||||
require.NoError(t, err)
|
||||
|
||||
query := &PublicDashboardListQuery{
|
||||
User: &user.SignedInUser{UserID: 1, OrgID: orgId, Permissions: map[int64]map[string][]string{orgId: accesscontrol.GroupScopesByAction(permissions)}},
|
||||
OrgID: orgId,
|
||||
Page: 1,
|
||||
Limit: 50,
|
||||
Offset: 0,
|
||||
}
|
||||
resp, err := publicdashboardStore.FindAllWithPagination(context.Background(), query)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Len(t, resp.PublicDashboards, 3)
|
||||
assert.Equal(t, resp.PublicDashboards[0].Uid, aPublicDash.Uid)
|
||||
assert.Equal(t, resp.PublicDashboards[1].Uid, bPublicDash.Uid)
|
||||
assert.Equal(t, resp.PublicDashboards[2].Uid, cPublicDash.Uid)
|
||||
assert.Equal(t, resp.TotalCount, int64(3))
|
||||
})
|
||||
|
||||
t.Run("FindAllWithPagination will return dashboard list based on read permissions with pagination", func(t *testing.T) {
|
||||
setup()
|
||||
|
||||
permissions := []accesscontrol.Permission{
|
||||
{Action: dashboards.ActionDashboardsRead, Scope: fmt.Sprintf("dashboards:uid:%s", aDash.UID)},
|
||||
{Action: dashboards.ActionDashboardsRead, Scope: fmt.Sprintf("dashboards:uid:%s", cDash.UID)},
|
||||
}
|
||||
|
||||
err := insertPermissions(sqlStore, orgId, "viewer", permissions)
|
||||
require.NoError(t, err)
|
||||
|
||||
query := &PublicDashboardListQuery{
|
||||
User: &user.SignedInUser{UserID: 1, OrgID: orgId, Permissions: map[int64]map[string][]string{orgId: accesscontrol.GroupScopesByAction(permissions)}},
|
||||
OrgID: orgId,
|
||||
Page: 1,
|
||||
Limit: 50,
|
||||
Offset: 0,
|
||||
}
|
||||
resp, err := publicdashboardStore.FindAllWithPagination(context.Background(), query)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Len(t, resp.PublicDashboards, 2)
|
||||
assert.Equal(t, resp.PublicDashboards[0].Uid, aPublicDash.Uid)
|
||||
assert.Equal(t, resp.PublicDashboards[1].Uid, cPublicDash.Uid)
|
||||
assert.Equal(t, resp.TotalCount, int64(2))
|
||||
})
|
||||
|
||||
t.Run("FindAllWithPagination will return empty dashboard list based on read permissions with pagination", func(t *testing.T) {
|
||||
setup()
|
||||
|
||||
permissions := []accesscontrol.Permission{
|
||||
{Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:another-dashboard-uid"},
|
||||
{Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:another-dashboard-2-uid"},
|
||||
}
|
||||
|
||||
err := insertPermissions(sqlStore, orgId, "viewer", permissions)
|
||||
require.NoError(t, err)
|
||||
|
||||
query := &PublicDashboardListQuery{
|
||||
User: &user.SignedInUser{UserID: 1, OrgID: orgId, Permissions: map[int64]map[string][]string{orgId: accesscontrol.GroupScopesByAction(permissions)}},
|
||||
OrgID: orgId,
|
||||
Page: 1,
|
||||
Limit: 50,
|
||||
Offset: 0,
|
||||
}
|
||||
resp, err := publicdashboardStore.FindAllWithPagination(context.Background(), query)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Len(t, resp.PublicDashboards, 0)
|
||||
assert.Equal(t, resp.TotalCount, int64(0))
|
||||
})
|
||||
}
|
||||
|
||||
func TestIntegrationFindDashboard(t *testing.T) {
|
||||
@@ -84,7 +174,7 @@ func TestIntegrationFindDashboard(t *testing.T) {
|
||||
store, err := dashboardsDB.ProvideDashboardStore(sqlStore, cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore, cfg), quotaService)
|
||||
require.NoError(t, err)
|
||||
dashboardStore = store
|
||||
publicdashboardStore = ProvideStore(sqlStore)
|
||||
publicdashboardStore = ProvideStore(sqlStore, cfg, featuremgmt.WithFeatures())
|
||||
savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
|
||||
}
|
||||
|
||||
@@ -114,7 +204,7 @@ func TestIntegrationExistsEnabledByAccessToken(t *testing.T) {
|
||||
store, err := dashboardsDB.ProvideDashboardStore(sqlStore, cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore, cfg), quotaService)
|
||||
require.NoError(t, err)
|
||||
dashboardStore = store
|
||||
publicdashboardStore = ProvideStore(sqlStore)
|
||||
publicdashboardStore = ProvideStore(sqlStore, cfg, featuremgmt.WithFeatures())
|
||||
savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
|
||||
}
|
||||
t.Run("ExistsEnabledByAccessToken will return true when at least one public dashboard has a matching access token", func(t *testing.T) {
|
||||
@@ -187,7 +277,7 @@ func TestIntegrationExistsEnabledByDashboardUid(t *testing.T) {
|
||||
store, err := dashboardsDB.ProvideDashboardStore(sqlStore, cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore, cfg), quotaService)
|
||||
require.NoError(t, err)
|
||||
dashboardStore = store
|
||||
publicdashboardStore = ProvideStore(sqlStore)
|
||||
publicdashboardStore = ProvideStore(sqlStore, cfg, featuremgmt.WithFeatures())
|
||||
savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
|
||||
}
|
||||
|
||||
@@ -252,7 +342,7 @@ func TestIntegrationFindByDashboardUid(t *testing.T) {
|
||||
store, err := dashboardsDB.ProvideDashboardStore(sqlStore, cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore, cfg), quotaService)
|
||||
require.NoError(t, err)
|
||||
dashboardStore = store
|
||||
publicdashboardStore = ProvideStore(sqlStore)
|
||||
publicdashboardStore = ProvideStore(sqlStore, cfg, featuremgmt.WithFeatures())
|
||||
savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
|
||||
}
|
||||
|
||||
@@ -319,7 +409,7 @@ func TestIntegrationFindByAccessToken(t *testing.T) {
|
||||
sqlStore, cfg = db.InitTestDBwithCfg(t)
|
||||
dashboardStore, err = dashboardsDB.ProvideDashboardStore(sqlStore, cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore, cfg), quotatest.New(false, nil))
|
||||
require.NoError(t, err)
|
||||
publicdashboardStore = ProvideStore(sqlStore)
|
||||
publicdashboardStore = ProvideStore(sqlStore, cfg, featuremgmt.WithFeatures())
|
||||
savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
|
||||
}
|
||||
|
||||
@@ -389,7 +479,7 @@ func TestIntegrationCreatePublicDashboard(t *testing.T) {
|
||||
store, err := dashboardsDB.ProvideDashboardStore(sqlStore, cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore, cfg), quotaService)
|
||||
require.NoError(t, err)
|
||||
dashboardStore = store
|
||||
publicdashboardStore = ProvideStore(sqlStore)
|
||||
publicdashboardStore = ProvideStore(sqlStore, cfg, featuremgmt.WithFeatures())
|
||||
savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
|
||||
savedDashboard2 = insertTestDashboard(t, dashboardStore, "testDashie2", 1, 0, true)
|
||||
insertPublicDashboard(t, publicdashboardStore, savedDashboard2.UID, savedDashboard2.OrgID, false, PublicShareType)
|
||||
@@ -468,7 +558,7 @@ func TestIntegrationUpdatePublicDashboard(t *testing.T) {
|
||||
quotaService := quotatest.New(false, nil)
|
||||
dashboardStore, err = dashboardsDB.ProvideDashboardStore(sqlStore, cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore, cfg), quotaService)
|
||||
require.NoError(t, err)
|
||||
publicdashboardStore = ProvideStore(sqlStore)
|
||||
publicdashboardStore = ProvideStore(sqlStore, cfg, featuremgmt.WithFeatures())
|
||||
savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
|
||||
anotherSavedDashboard = insertTestDashboard(t, dashboardStore, "test another Dashie", 1, 0, true)
|
||||
}
|
||||
@@ -572,7 +662,7 @@ func TestIntegrationGetOrgIdByAccessToken(t *testing.T) {
|
||||
quotaService := quotatest.New(false, nil)
|
||||
dashboardStore, err = dashboardsDB.ProvideDashboardStore(sqlStore, cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore, cfg), quotaService)
|
||||
require.NoError(t, err)
|
||||
publicdashboardStore = ProvideStore(sqlStore)
|
||||
publicdashboardStore = ProvideStore(sqlStore, cfg, featuremgmt.WithFeatures())
|
||||
savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
|
||||
}
|
||||
t.Run("GetOrgIdByAccessToken will OrgId when enabled", func(t *testing.T) {
|
||||
@@ -644,7 +734,7 @@ func TestIntegrationDelete(t *testing.T) {
|
||||
sqlStore, cfg = db.InitTestDBwithCfg(t)
|
||||
dashboardStore, err = dashboardsDB.ProvideDashboardStore(sqlStore, cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore, cfg), quotatest.New(false, nil))
|
||||
require.NoError(t, err)
|
||||
publicdashboardStore = ProvideStore(sqlStore)
|
||||
publicdashboardStore = ProvideStore(sqlStore, cfg, featuremgmt.WithFeatures())
|
||||
savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, true)
|
||||
savedPublicDashboard = insertPublicDashboard(t, publicdashboardStore, savedDashboard.UID, savedDashboard.OrgID, true, PublicShareType)
|
||||
}
|
||||
@@ -675,7 +765,7 @@ func TestGetDashboardByFolder(t *testing.T) {
|
||||
t.Run("returns nil when dashboard is not a folder", func(t *testing.T) {
|
||||
sqlStore, _ := db.InitTestDBwithCfg(t)
|
||||
dashboard := &dashboards.Dashboard{IsFolder: false}
|
||||
store := ProvideStore(sqlStore)
|
||||
store := ProvideStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures())
|
||||
pubdashes, err := store.FindByDashboardFolder(context.Background(), dashboard)
|
||||
|
||||
require.NoError(t, err)
|
||||
@@ -684,7 +774,7 @@ func TestGetDashboardByFolder(t *testing.T) {
|
||||
|
||||
t.Run("returns nil when dashboard is nil", func(t *testing.T) {
|
||||
sqlStore, _ := db.InitTestDBwithCfg(t)
|
||||
store := ProvideStore(sqlStore)
|
||||
store := ProvideStore(sqlStore, sqlStore.Cfg, featuremgmt.WithFeatures())
|
||||
pubdashes, err := store.FindByDashboardFolder(context.Background(), nil)
|
||||
|
||||
require.NoError(t, err)
|
||||
@@ -696,7 +786,7 @@ func TestGetDashboardByFolder(t *testing.T) {
|
||||
quotaService := quotatest.New(false, nil)
|
||||
dashboardStore, err := dashboardsDB.ProvideDashboardStore(sqlStore, cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore, cfg), quotaService)
|
||||
require.NoError(t, err)
|
||||
pubdashStore := ProvideStore(sqlStore)
|
||||
pubdashStore := ProvideStore(sqlStore, cfg, featuremgmt.WithFeatures())
|
||||
dashboard := insertTestDashboard(t, dashboardStore, "title", 1, 1, true, PublicShareType)
|
||||
pubdash := insertPublicDashboard(t, pubdashStore, dashboard.UID, dashboard.OrgID, true, PublicShareType)
|
||||
dashboard2 := insertTestDashboard(t, dashboardStore, "title", 1, 2, true, PublicShareType)
|
||||
@@ -729,7 +819,7 @@ func TestGetMetrics(t *testing.T) {
|
||||
store, err := dashboardsDB.ProvideDashboardStore(sqlStore, cfg, featuremgmt.WithFeatures(), tagimpl.ProvideService(sqlStore, cfg), quotaService)
|
||||
require.NoError(t, err)
|
||||
dashboardStore = store
|
||||
publicdashboardStore = ProvideStore(sqlStore)
|
||||
publicdashboardStore = ProvideStore(sqlStore, cfg, featuremgmt.WithFeatures())
|
||||
savedDashboard = insertTestDashboard(t, dashboardStore, "testDashie", 1, 0, false)
|
||||
savedDashboard2 = insertTestDashboard(t, dashboardStore, "testDashie2", 1, 0, false)
|
||||
savedDashboard3 = insertTestDashboard(t, dashboardStore, "testDashie3", 2, 0, false)
|
||||
@@ -827,3 +917,50 @@ func insertPublicDashboard(t *testing.T, publicdashboardStore *PublicDashboardSt
|
||||
|
||||
return pubdash
|
||||
}
|
||||
|
||||
func insertPermissions(sqlStore *sqlstore.SQLStore, orgId int64, role string, permissions []accesscontrol.Permission) error {
|
||||
return sqlStore.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
|
||||
newRole := &accesscontrol.Role{
|
||||
OrgID: orgId,
|
||||
UID: fmt.Sprintf("basic_%s", role),
|
||||
Name: fmt.Sprintf("basic:%s", role),
|
||||
Updated: time.Now(),
|
||||
Created: time.Now(),
|
||||
}
|
||||
_, err := sess.Insert(newRole)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = sess.Insert(accesscontrol.BuiltinRole{
|
||||
OrgID: orgId,
|
||||
RoleID: newRole.ID,
|
||||
Role: strings.ToUpper(role[:1]) + role[1:],
|
||||
Created: time.Now(),
|
||||
Updated: time.Now(),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := range permissions {
|
||||
permissions[i].RoleID = newRole.ID
|
||||
permissions[i].Created = time.Now()
|
||||
permissions[i].Updated = time.Now()
|
||||
}
|
||||
|
||||
_, err = sess.InsertMulti(&permissions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = sess.Insert(accesscontrol.UserRole{
|
||||
OrgID: orgId,
|
||||
RoleID: newRole.ID,
|
||||
UserID: 1,
|
||||
Created: time.Now(),
|
||||
})
|
||||
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user