Use dashboards service to query for dashboard uid when getting library elements (#99369)

This commit is contained in:
Leonor Oliveira 2025-01-27 14:42:57 +01:00 committed by GitHub
parent e94c9f733b
commit abe2a5370d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 39 additions and 30 deletions

View File

@ -501,7 +501,7 @@ func TestIntegrationNestedFolderService(t *testing.T) {
alertStore, err := ngstore.ProvideDBStore(cfg, featuresFlagOn, db, serviceWithFlagOn, dashSrv, ac, b)
require.NoError(t, err)
elementService := libraryelements.ProvideService(cfg, db, routeRegister, serviceWithFlagOn, featuresFlagOn, ac)
elementService := libraryelements.ProvideService(cfg, db, routeRegister, serviceWithFlagOn, featuresFlagOn, ac, dashSrv)
lps, err := librarypanels.ProvideService(cfg, db, routeRegister, elementService, serviceWithFlagOn)
require.NoError(t, err)
@ -586,7 +586,7 @@ func TestIntegrationNestedFolderService(t *testing.T) {
alertStore, err := ngstore.ProvideDBStore(cfg, featuresFlagOff, db, serviceWithFlagOff, dashSrv, ac, b)
require.NoError(t, err)
elementService := libraryelements.ProvideService(cfg, db, routeRegister, serviceWithFlagOff, featuresFlagOff, ac)
elementService := libraryelements.ProvideService(cfg, db, routeRegister, serviceWithFlagOff, featuresFlagOff, ac, dashSrv)
lps, err := librarypanels.ProvideService(cfg, db, routeRegister, elementService, serviceWithFlagOff)
require.NoError(t, err)
@ -716,10 +716,6 @@ func TestIntegrationNestedFolderService(t *testing.T) {
CanEditValue: true,
})
elementService := libraryelements.ProvideService(cfg, db, routeRegister, tc.service, tc.featuresFlag, ac)
lps, err := librarypanels.ProvideService(cfg, db, routeRegister, elementService, tc.service)
require.NoError(t, err)
dashStore, err := database.ProvideDashboardStore(db, cfg, tc.featuresFlag, tagimpl.ProvideService(db))
require.NoError(t, err)
nestedFolderStore := ProvideStore(db)
@ -731,6 +727,10 @@ func TestIntegrationNestedFolderService(t *testing.T) {
require.NoError(t, err)
dashSrv.RegisterDashboardPermissions(dashboardPermissions)
elementService := libraryelements.ProvideService(cfg, db, routeRegister, tc.service, tc.featuresFlag, ac, dashSrv)
lps, err := librarypanels.ProvideService(cfg, db, routeRegister, elementService, tc.service)
require.NoError(t, err)
alertStore, err := ngstore.ProvideDBStore(cfg, tc.featuresFlag, db, tc.service, dashSrv, ac, b)
require.NoError(t, err)

View File

@ -695,14 +695,15 @@ func (l *LibraryElementService) getConnections(c context.Context, signedInUser i
}
var libraryElementConnections []model.LibraryElementConnectionWithMeta
builder := db.NewSqlBuilder(l.Cfg, l.features, l.SQLStore.GetDialect(), recursiveQueriesAreSupported)
builder.Write("SELECT lec.*, u1.login AS created_by_name, u1.email AS created_by_email, dashboard.uid AS connection_uid")
builder.Write("SELECT lec.*, u1.login AS created_by_name, u1.email AS created_by_email")
builder.Write(" FROM " + model.LibraryElementConnectionTableName + " AS lec")
builder.Write(" LEFT JOIN " + l.SQLStore.GetDialect().Quote("user") + " AS u1 ON lec.created_by = u1.id")
builder.Write(" INNER JOIN dashboard AS dashboard on lec.connection_id = dashboard.id")
builder.Write(` WHERE lec.element_id=?`, element.ID)
if err := session.SQL(builder.GetSQLString(), builder.GetParams()...).Find(&libraryElementConnections); err != nil {
return err
}
// getting all folders a user can see
fs, err := l.folderService.GetFolders(c, folder.GetFoldersQuery{OrgID: signedInUser.GetOrgID(), SignedInUser: signedInUser})
if err != nil {
return err
@ -712,19 +713,23 @@ func (l *LibraryElementService) getConnections(c context.Context, signedInUser i
for _, f := range fs {
folderUIDS = append(folderUIDS, f.UID)
}
// if the user is not an admin, we need to filter out elements that are not in folders the user can see
for _, connection := range libraryElementConnections {
if !signedInUser.HasRole(org.RoleAdmin) {
if !contains(folderUIDS, element.FolderUID) {
continue
}
}
ds, err := l.dashboardsService.GetDashboardUIDByID(c, &dashboards.GetDashboardRefByIDQuery{ID: connection.ConnectionID})
if err != nil {
return err
}
connections = append(connections, model.LibraryElementConnectionDTO{
ID: connection.ID,
Kind: connection.Kind,
ElementID: connection.ElementID,
ConnectionID: connection.ConnectionID,
ConnectionUID: connection.ConnectionUID,
ConnectionUID: ds.UID,
Created: connection.Created,
CreatedBy: librarypanel.LibraryElementDTOMetaUser{
Id: connection.CreatedBy,

View File

@ -9,21 +9,23 @@ import (
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/folder"
"github.com/grafana/grafana/pkg/services/libraryelements/model"
"github.com/grafana/grafana/pkg/setting"
)
func ProvideService(cfg *setting.Cfg, sqlStore db.DB, routeRegister routing.RouteRegister, folderService folder.Service, features featuremgmt.FeatureToggles, ac accesscontrol.AccessControl) *LibraryElementService {
func ProvideService(cfg *setting.Cfg, sqlStore db.DB, routeRegister routing.RouteRegister, folderService folder.Service, features featuremgmt.FeatureToggles, ac accesscontrol.AccessControl, dashboardsService dashboards.DashboardService) *LibraryElementService {
l := &LibraryElementService{
Cfg: cfg,
SQLStore: sqlStore,
RouteRegister: routeRegister,
folderService: folderService,
log: log.New("library-elements"),
features: features,
AccessControl: ac,
Cfg: cfg,
SQLStore: sqlStore,
RouteRegister: routeRegister,
folderService: folderService,
dashboardsService: dashboardsService,
log: log.New("library-elements"),
features: features,
AccessControl: ac,
}
l.registerAPIEndpoints()
@ -45,13 +47,14 @@ type Service interface {
// LibraryElementService is the service for the Library Element feature.
type LibraryElementService struct {
Cfg *setting.Cfg
SQLStore db.DB
RouteRegister routing.RouteRegister
folderService folder.Service
log log.Logger
features featuremgmt.FeatureToggles
AccessControl accesscontrol.AccessControl
Cfg *setting.Cfg
SQLStore db.DB
RouteRegister routing.RouteRegister
folderService folder.Service
dashboardsService dashboards.DashboardService
log log.Logger
features featuremgmt.FeatureToggles
AccessControl accesscontrol.AccessControl
}
var _ Service = (*LibraryElementService)(nil)

View File

@ -486,10 +486,11 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
dashService.RegisterDashboardPermissions(dashboardPermissions)
guardian.InitAccessControlGuardian(cfg, ac, dashService, folderSvc, log.NewNopLogger())
service := LibraryElementService{
Cfg: cfg,
features: featuremgmt.WithFeatures(),
SQLStore: sqlStore,
folderService: folderSvc,
Cfg: cfg,
features: featuremgmt.WithFeatures(),
SQLStore: sqlStore,
folderService: folderSvc,
dashboardsService: dashService,
}
// deliberate difference between signed in user and user in db to make it crystal clear

View File

@ -847,7 +847,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
fStore, ac, bus.ProvideBus(tracing.InitializeTracerForTest()), dashboardStore, folderStore,
nil, sqlStore, features, supportbundlestest.NewFakeBundleService(), nil, cfg, nil, tracing.InitializeTracerForTest())
elementService := libraryelements.ProvideService(cfg, sqlStore, routing.NewRouteRegister(), folderService, features, ac)
elementService := libraryelements.ProvideService(cfg, sqlStore, routing.NewRouteRegister(), folderService, features, ac, dashService)
service := LibraryPanelService{
Cfg: cfg,
SQLStore: sqlStore,