mirror of
https://github.com/grafana/grafana.git
synced 2025-08-06 02:23:28 +08:00
Chore: Drop dashboard service dependency from folder service (#61614)
* Chore: Drop dashboard dependency from folder service
This commit is contained in:

committed by
GitHub

parent
a1f2d0e205
commit
b80c9bb974
@ -5,6 +5,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/events"
|
||||
@ -29,14 +30,13 @@ import (
|
||||
type Service struct {
|
||||
store store
|
||||
|
||||
log log.Logger
|
||||
cfg *setting.Cfg
|
||||
dashboardService dashboards.DashboardService
|
||||
dashboardStore dashboards.Store
|
||||
searchService *search.SearchService
|
||||
features featuremgmt.FeatureToggles
|
||||
permissions accesscontrol.FolderPermissionsService
|
||||
accessControl accesscontrol.AccessControl
|
||||
log log.Logger
|
||||
cfg *setting.Cfg
|
||||
dashboardStore dashboards.Store
|
||||
searchService *search.SearchService
|
||||
features featuremgmt.FeatureToggles
|
||||
permissions accesscontrol.FolderPermissionsService
|
||||
accessControl accesscontrol.AccessControl
|
||||
|
||||
// bus is currently used to publish events that cause scheduler to update rules.
|
||||
bus bus.Bus
|
||||
@ -46,7 +46,6 @@ func ProvideService(
|
||||
ac accesscontrol.AccessControl,
|
||||
bus bus.Bus,
|
||||
cfg *setting.Cfg,
|
||||
dashboardService dashboards.DashboardService,
|
||||
dashboardStore dashboards.Store,
|
||||
db db.DB, // DB for the (new) nested folder store
|
||||
features featuremgmt.FeatureToggles,
|
||||
@ -57,16 +56,15 @@ func ProvideService(
|
||||
ac.RegisterScopeAttributeResolver(dashboards.NewFolderIDScopeResolver(dashboardStore))
|
||||
store := ProvideStore(db, cfg, features)
|
||||
svr := &Service{
|
||||
cfg: cfg,
|
||||
log: log.New("folder-service"),
|
||||
dashboardService: dashboardService,
|
||||
dashboardStore: dashboardStore,
|
||||
store: store,
|
||||
searchService: searchService,
|
||||
features: features,
|
||||
permissions: folderPermissionsService,
|
||||
accessControl: ac,
|
||||
bus: bus,
|
||||
cfg: cfg,
|
||||
log: log.New("folder-service"),
|
||||
dashboardStore: dashboardStore,
|
||||
store: store,
|
||||
searchService: searchService,
|
||||
features: features,
|
||||
permissions: folderPermissionsService,
|
||||
accessControl: ac,
|
||||
bus: bus,
|
||||
}
|
||||
if features.IsEnabled(featuremgmt.FlagNestedFolders) {
|
||||
svr.DBMigration(db)
|
||||
@ -321,7 +319,7 @@ func (s *Service) Create(ctx context.Context, cmd *folder.CreateFolderCommand) (
|
||||
User: user,
|
||||
}
|
||||
|
||||
saveDashboardCmd, err := s.dashboardService.BuildSaveDashboardCommand(ctx, dto, false, false)
|
||||
saveDashboardCmd, err := s.BuildSaveDashboardCommand(ctx, dto)
|
||||
if err != nil {
|
||||
return nil, toFolderError(err)
|
||||
}
|
||||
@ -466,7 +464,7 @@ func (s *Service) legacyUpdate(ctx context.Context, cmd *folder.UpdateFolderComm
|
||||
Overwrite: cmd.Overwrite,
|
||||
}
|
||||
|
||||
saveDashboardCmd, err := s.dashboardService.BuildSaveDashboardCommand(ctx, dto, false, false)
|
||||
saveDashboardCmd, err := s.BuildSaveDashboardCommand(ctx, dto)
|
||||
if err != nil {
|
||||
return nil, toFolderError(err)
|
||||
}
|
||||
@ -648,8 +646,154 @@ func (s *Service) nestedFolderDelete(ctx context.Context, cmd *folder.DeleteFold
|
||||
return nil
|
||||
}
|
||||
|
||||
// MakeUserAdmin is copy of DashboardServiceImpl.MakeUserAdmin
|
||||
func (s *Service) MakeUserAdmin(ctx context.Context, orgID int64, userID, folderID int64, setViewAndEditPermissions bool) error {
|
||||
return s.dashboardService.MakeUserAdmin(ctx, orgID, userID, folderID, setViewAndEditPermissions)
|
||||
rtEditor := org.RoleEditor
|
||||
rtViewer := org.RoleViewer
|
||||
|
||||
items := []*models.DashboardACL{
|
||||
{
|
||||
OrgID: orgID,
|
||||
DashboardID: folderID,
|
||||
UserID: userID,
|
||||
Permission: models.PERMISSION_ADMIN,
|
||||
Created: time.Now(),
|
||||
Updated: time.Now(),
|
||||
},
|
||||
}
|
||||
|
||||
if setViewAndEditPermissions {
|
||||
items = append(items,
|
||||
&models.DashboardACL{
|
||||
OrgID: orgID,
|
||||
DashboardID: folderID,
|
||||
Role: &rtEditor,
|
||||
Permission: models.PERMISSION_EDIT,
|
||||
Created: time.Now(),
|
||||
Updated: time.Now(),
|
||||
},
|
||||
&models.DashboardACL{
|
||||
OrgID: orgID,
|
||||
DashboardID: folderID,
|
||||
Role: &rtViewer,
|
||||
Permission: models.PERMISSION_VIEW,
|
||||
Created: time.Now(),
|
||||
Updated: time.Now(),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
if err := s.dashboardStore.UpdateDashboardACL(ctx, folderID, items); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// BuildSaveDashboardCommand is a simplified version on DashboardServiceImpl.BuildSaveDashboardCommand
|
||||
// keeping only the meaningful functionality for folders
|
||||
func (s *Service) BuildSaveDashboardCommand(ctx context.Context, dto *dashboards.SaveDashboardDTO) (*dashboards.SaveDashboardCommand, error) {
|
||||
dash := dto.Dashboard
|
||||
|
||||
dash.OrgID = dto.OrgID
|
||||
dash.Title = strings.TrimSpace(dash.Title)
|
||||
dash.Data.Set("title", dash.Title)
|
||||
dash.SetUID(strings.TrimSpace(dash.UID))
|
||||
|
||||
if dash.Title == "" {
|
||||
return nil, dashboards.ErrDashboardTitleEmpty
|
||||
}
|
||||
|
||||
if dash.IsFolder && dash.FolderID > 0 {
|
||||
return nil, dashboards.ErrDashboardFolderCannotHaveParent
|
||||
}
|
||||
|
||||
if dash.IsFolder && strings.EqualFold(dash.Title, dashboards.RootFolderName) {
|
||||
return nil, dashboards.ErrDashboardFolderNameExists
|
||||
}
|
||||
|
||||
if !util.IsValidShortUID(dash.UID) {
|
||||
return nil, dashboards.ErrDashboardInvalidUid
|
||||
} else if util.IsShortUIDTooLong(dash.UID) {
|
||||
return nil, dashboards.ErrDashboardUidTooLong
|
||||
}
|
||||
|
||||
isParentFolderChanged, err := s.dashboardStore.ValidateDashboardBeforeSave(ctx, dash, dto.Overwrite)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if isParentFolderChanged {
|
||||
// Check that the user is allowed to add a dashboard to the folder
|
||||
guardian, err := guardian.NewByDashboard(ctx, dash, dto.OrgID, dto.User)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if canSave, err := guardian.CanCreate(dash.FolderID, dash.IsFolder); err != nil || !canSave {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, dashboards.ErrDashboardUpdateAccessDenied
|
||||
}
|
||||
}
|
||||
|
||||
guard, err := getGuardianForSavePermissionCheck(ctx, dash, dto.User)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if dash.ID == 0 {
|
||||
if canCreate, err := guard.CanCreate(dash.FolderID, dash.IsFolder); err != nil || !canCreate {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, dashboards.ErrDashboardUpdateAccessDenied
|
||||
}
|
||||
} else {
|
||||
if canSave, err := guard.CanSave(); err != nil || !canSave {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, dashboards.ErrDashboardUpdateAccessDenied
|
||||
}
|
||||
}
|
||||
|
||||
cmd := &dashboards.SaveDashboardCommand{
|
||||
Dashboard: dash.Data,
|
||||
Message: dto.Message,
|
||||
OrgID: dto.OrgID,
|
||||
Overwrite: dto.Overwrite,
|
||||
UserID: dto.User.UserID,
|
||||
FolderID: dash.FolderID,
|
||||
IsFolder: dash.IsFolder,
|
||||
PluginID: dash.PluginID,
|
||||
}
|
||||
|
||||
if !dto.UpdatedAt.IsZero() {
|
||||
cmd.UpdatedAt = dto.UpdatedAt
|
||||
}
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// getGuardianForSavePermissionCheck returns the guardian to be used for checking permission of dashboard
|
||||
// It replaces deleted Dashboard.GetDashboardIdForSavePermissionCheck()
|
||||
func getGuardianForSavePermissionCheck(ctx context.Context, d *dashboards.Dashboard, user *user.SignedInUser) (guardian.DashboardGuardian, error) {
|
||||
newDashboard := d.ID == 0
|
||||
|
||||
if newDashboard {
|
||||
// if it's a new dashboard/folder check the parent folder permissions
|
||||
guard, err := guardian.New(ctx, d.FolderID, d.OrgID, user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return guard, nil
|
||||
}
|
||||
guard, err := guardian.NewByDashboard(ctx, d, d.OrgID, user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return guard, nil
|
||||
}
|
||||
|
||||
func (s *Service) nestedFolderCreate(ctx context.Context, cmd *folder.CreateFolderCommand) (*folder.Folder, error) {
|
||||
|
Reference in New Issue
Block a user