[v11.2.x] MigrationAssistant: Restrict dashboards, folders and datasources by the org id of the signed in user (#96344)

apply security patch: v11.2.x/195-202410172117.patch
This commit is contained in:
lean.dev
2024-11-12 16:33:06 -03:00
committed by GitHub
parent 21679c7c25
commit b10a2dc68c
12 changed files with 206 additions and 126 deletions
@@ -8,6 +8,7 @@ import (
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/services/cloudmigration"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/secrets"
secretskv "github.com/grafana/grafana/pkg/services/secrets/kvstore"
"github.com/grafana/grafana/pkg/services/sqlstore"
@@ -28,10 +29,10 @@ const (
GetAllSnapshots = -1
)
func (ss *sqlStore) GetMigrationSessionByUID(ctx context.Context, uid string) (*cloudmigration.CloudMigrationSession, error) {
func (ss *sqlStore) GetMigrationSessionByUID(ctx context.Context, orgID int64, uid string) (*cloudmigration.CloudMigrationSession, error) {
var cm cloudmigration.CloudMigrationSession
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
exist, err := sess.Where("uid=?", uid).Get(&cm)
exist, err := sess.Where("org_id=? AND uid=?", orgID, uid).Get(&cm)
if err != nil {
return err
}
@@ -89,11 +90,10 @@ func (ss *sqlStore) CreateMigrationSession(ctx context.Context, migration cloudm
return &migration, nil
}
func (ss *sqlStore) GetCloudMigrationSessionList(ctx context.Context) ([]*cloudmigration.CloudMigrationSession, error) {
func (ss *sqlStore) GetCloudMigrationSessionList(ctx context.Context, orgID int64) ([]*cloudmigration.CloudMigrationSession, error) {
var migrations = make([]*cloudmigration.CloudMigrationSession, 0)
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
sess.OrderBy("created DESC")
return sess.Find(&migrations)
return sess.Where("org_id=?", orgID).OrderBy("created DESC").Find(&migrations)
})
if err != nil {
return nil, err
@@ -110,10 +110,10 @@ func (ss *sqlStore) GetCloudMigrationSessionList(ctx context.Context) ([]*cloudm
return migrations, nil
}
func (ss *sqlStore) DeleteMigrationSessionByUID(ctx context.Context, uid string) (*cloudmigration.CloudMigrationSession, []cloudmigration.CloudMigrationSnapshot, error) {
func (ss *sqlStore) DeleteMigrationSessionByUID(ctx context.Context, orgID int64, uid string) (*cloudmigration.CloudMigrationSession, []cloudmigration.CloudMigrationSnapshot, error) {
var c cloudmigration.CloudMigrationSession
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
exist, err := sess.Where("uid=?", uid).Get(&c)
exist, err := sess.Where("org_id=? AND uid=?", orgID, uid).Get(&c)
if err != nil {
return err
}
@@ -139,11 +139,11 @@ func (ss *sqlStore) DeleteMigrationSessionByUID(ctx context.Context, uid string)
err = ss.db.InTransaction(ctx, func(ctx context.Context) error {
for _, snapshot := range snapshots {
err := ss.DeleteSnapshotResources(ctx, snapshot.UID)
err := ss.deleteSnapshotResources(ctx, snapshot.UID)
if err != nil {
return fmt.Errorf("deleting snapshot resource from db: %w", err)
}
err = ss.DeleteSnapshot(ctx, snapshot.UID)
err = ss.deleteSnapshot(ctx, orgID, snapshot.UID)
if err != nil {
return fmt.Errorf("deleting snapshot from db: %w", err)
}
@@ -257,7 +257,7 @@ func (ss *sqlStore) UpdateSnapshot(ctx context.Context, update cloudmigration.Up
// Update resources if set
if len(update.Resources) > 0 {
if err := ss.CreateUpdateSnapshotResources(ctx, update.UID, update.Resources); err != nil {
if err := ss.createUpdateSnapshotResources(ctx, update.UID, update.Resources); err != nil {
return err
}
}
@@ -267,7 +267,7 @@ func (ss *sqlStore) UpdateSnapshot(ctx context.Context, update cloudmigration.Up
return err
}
func (ss *sqlStore) DeleteSnapshot(ctx context.Context, snapshotUid string) error {
func (ss *sqlStore) deleteSnapshot(ctx context.Context, orgID int64, snapshotUid string) error {
return ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
_, err := sess.Delete(cloudmigration.CloudMigrationSnapshot{
UID: snapshotUid,
@@ -276,9 +276,16 @@ func (ss *sqlStore) DeleteSnapshot(ctx context.Context, snapshotUid string) erro
})
}
func (ss *sqlStore) GetSnapshotByUID(ctx context.Context, sessionUid, uid string, resultPage int, resultLimit int) (*cloudmigration.CloudMigrationSnapshot, error) {
func (ss *sqlStore) GetSnapshotByUID(ctx context.Context, orgID int64, sessionUid, uid string, resultPage int, resultLimit int) (*cloudmigration.CloudMigrationSnapshot, error) {
// first we check if the session exists, using orgId and sessionUid
session, err := ss.GetMigrationSessionByUID(ctx, orgID, sessionUid)
if err != nil || session == nil {
return nil, err
}
// now we get the snapshot
var snapshot cloudmigration.CloudMigrationSnapshot
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
err = ss.db.WithDbSession(ctx, func(sess *db.Session) error {
exist, err := sess.Where("session_uid=? AND uid=?", sessionUid, uid).Get(&snapshot)
if err != nil {
return err
@@ -300,11 +307,11 @@ func (ss *sqlStore) GetSnapshotByUID(ctx context.Context, sessionUid, uid string
snapshot.EncryptionKey = []byte(secret)
}
resources, err := ss.GetSnapshotResources(ctx, uid, resultPage, resultLimit)
resources, err := ss.getSnapshotResources(ctx, uid, resultPage, resultLimit)
if err == nil {
snapshot.Resources = resources
}
stats, err := ss.GetSnapshotResourceStats(ctx, uid)
stats, err := ss.getSnapshotResourceStats(ctx, uid)
if err == nil {
snapshot.StatsRollup = *stats
}
@@ -317,7 +324,9 @@ func (ss *sqlStore) GetSnapshotByUID(ctx context.Context, sessionUid, uid string
func (ss *sqlStore) GetSnapshotList(ctx context.Context, query cloudmigration.ListSnapshotsQuery) ([]cloudmigration.CloudMigrationSnapshot, error) {
var snapshots = make([]cloudmigration.CloudMigrationSnapshot, 0)
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
sess.Join("INNER", "cloud_migration_session", "cloud_migration_session.uid = cloud_migration_snapshot.session_uid")
sess.Join("INNER", "cloud_migration_session",
"cloud_migration_session.uid = cloud_migration_snapshot.session_uid AND cloud_migration_session.org_id = ?", query.OrgID,
)
if query.Limit != GetAllSnapshots {
offset := (query.Page - 1) * query.Limit
sess.Limit(query.Limit, offset)
@@ -339,7 +348,7 @@ func (ss *sqlStore) GetSnapshotList(ctx context.Context, query cloudmigration.Li
snapshot.EncryptionKey = []byte(secret)
}
if stats, err := ss.GetSnapshotResourceStats(ctx, snapshot.UID); err != nil {
if stats, err := ss.getSnapshotResourceStats(ctx, snapshot.UID); err != nil {
return nil, err
} else {
snapshot.StatsRollup = *stats
@@ -351,7 +360,7 @@ func (ss *sqlStore) GetSnapshotList(ctx context.Context, query cloudmigration.Li
// CreateUpdateSnapshotResources either updates a migration resource for a snapshot, or creates it if it does not exist
// If the uid is not known, it uses snapshot_uid + resource_uid as a lookup
func (ss *sqlStore) CreateUpdateSnapshotResources(ctx context.Context, snapshotUid string, resources []cloudmigration.CloudMigrationResource) error {
func (ss *sqlStore) createUpdateSnapshotResources(ctx context.Context, snapshotUid string, resources []cloudmigration.CloudMigrationResource) error {
return ss.db.InTransaction(ctx, func(ctx context.Context) error {
sql := "UPDATE cloud_migration_resource SET status=?, error_string=? WHERE uid=? OR (snapshot_uid=? AND resource_uid=?)"
err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
@@ -385,7 +394,7 @@ func (ss *sqlStore) CreateUpdateSnapshotResources(ctx context.Context, snapshotU
})
}
func (ss *sqlStore) GetSnapshotResources(ctx context.Context, snapshotUid string, page int, limit int) ([]cloudmigration.CloudMigrationResource, error) {
func (ss *sqlStore) getSnapshotResources(ctx context.Context, snapshotUid string, page int, limit int) ([]cloudmigration.CloudMigrationResource, error) {
if page < 1 {
page = 1
}
@@ -407,7 +416,7 @@ func (ss *sqlStore) GetSnapshotResources(ctx context.Context, snapshotUid string
return resources, nil
}
func (ss *sqlStore) GetSnapshotResourceStats(ctx context.Context, snapshotUid string) (*cloudmigration.SnapshotResourceStats, error) {
func (ss *sqlStore) getSnapshotResourceStats(ctx context.Context, snapshotUid string) (*cloudmigration.SnapshotResourceStats, error) {
typeCounts := make([]struct {
Count int `json:"count"`
Type string `json:"type"`
@@ -454,7 +463,7 @@ func (ss *sqlStore) GetSnapshotResourceStats(ctx context.Context, snapshotUid st
return stats, nil
}
func (ss *sqlStore) DeleteSnapshotResources(ctx context.Context, snapshotUid string) error {
func (ss *sqlStore) deleteSnapshotResources(ctx context.Context, snapshotUid string) error {
return ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
_, err := sess.Delete(cloudmigration.CloudMigrationResource{
SnapshotUID: snapshotUid,
@@ -497,3 +506,19 @@ func (ss *sqlStore) decryptToken(ctx context.Context, cm *cloudmigration.CloudMi
return nil
}
// TODO move this function dashboards/databases/databases.go
func (ss *sqlStore) GetAllDashboardsByOrgId(ctx context.Context, orgID int64) ([]*dashboards.Dashboard, error) {
//ctx, span := tracer.Start(ctx, "dashboards.database.GetAllDashboardsByOrgId")
//defer span.End()
var dashs = make([]*dashboards.Dashboard, 0)
err := ss.db.WithDbSession(ctx, func(session *db.Session) error {
// "deleted IS NULL" is to avoid deleted dashboards
return session.Where("org_id = ? AND deleted IS NULL", orgID).Find(&dashs)
})
if err != nil {
return nil, err
}
return dashs, nil
}