Folders: Allow listing folders with write permission (#83527)
* Folders: Allow listing folders with write permission * Check for subfolder access if parent does not have * Add test * GetFolders: fix ordering * Apply suggestion from code review
This commit is contained in:
@@ -22,6 +22,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/auth/identity"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards/dashboardaccess"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/folder"
|
||||
"github.com/grafana/grafana/pkg/services/guardian"
|
||||
@@ -298,12 +299,16 @@ func (s *Service) GetChildren(ctx context.Context, q *folder.GetChildrenQuery) (
|
||||
return nil, err
|
||||
}
|
||||
|
||||
canView, err := g.CanView()
|
||||
guardianFunc := g.CanView
|
||||
if q.Permission == dashboardaccess.PERMISSION_EDIT {
|
||||
guardianFunc = g.CanEdit
|
||||
}
|
||||
|
||||
hasAccess, err := guardianFunc()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !canView {
|
||||
if !hasAccess {
|
||||
return nil, dashboards.ErrFolderAccessDenied
|
||||
}
|
||||
|
||||
@@ -341,8 +346,19 @@ func (s *Service) GetChildren(ctx context.Context, q *folder.GetChildrenQuery) (
|
||||
|
||||
func (s *Service) getRootFolders(ctx context.Context, q *folder.GetChildrenQuery) ([]*folder.Folder, error) {
|
||||
permissions := q.SignedInUser.GetPermissions()
|
||||
folderPermissions := permissions[dashboards.ActionFoldersRead]
|
||||
folderPermissions = append(folderPermissions, permissions[dashboards.ActionDashboardsRead]...)
|
||||
var folderPermissions []string
|
||||
if q.Permission == dashboardaccess.PERMISSION_EDIT {
|
||||
folderPermissions = permissions[dashboards.ActionFoldersWrite]
|
||||
folderPermissions = append(folderPermissions, permissions[dashboards.ActionDashboardsWrite]...)
|
||||
} else {
|
||||
folderPermissions = permissions[dashboards.ActionFoldersRead]
|
||||
folderPermissions = append(folderPermissions, permissions[dashboards.ActionDashboardsRead]...)
|
||||
}
|
||||
|
||||
if len(folderPermissions) == 0 && !q.SignedInUser.GetIsGrafanaAdmin() {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
q.FolderUIDs = make([]string, 0, len(folderPermissions))
|
||||
for _, p := range folderPermissions {
|
||||
if p == dashboards.ScopeFoldersAll {
|
||||
@@ -401,12 +417,12 @@ func (s *Service) getRootFolders(ctx context.Context, q *folder.GetChildrenQuery
|
||||
// GetSharedWithMe returns folders available to user, which cannot be accessed from the root folders
|
||||
func (s *Service) GetSharedWithMe(ctx context.Context, q *folder.GetChildrenQuery) ([]*folder.Folder, error) {
|
||||
start := time.Now()
|
||||
availableNonRootFolders, err := s.getAvailableNonRootFolders(ctx, q.OrgID, q.SignedInUser)
|
||||
availableNonRootFolders, err := s.getAvailableNonRootFolders(ctx, q)
|
||||
if err != nil {
|
||||
s.metrics.sharedWithMeFetchFoldersRequestsDuration.WithLabelValues("failure").Observe(time.Since(start).Seconds())
|
||||
return nil, folder.ErrInternal.Errorf("failed to fetch subfolders to which the user has explicit access: %w", err)
|
||||
}
|
||||
rootFolders, err := s.GetChildren(ctx, &folder.GetChildrenQuery{UID: "", OrgID: q.OrgID, SignedInUser: q.SignedInUser})
|
||||
rootFolders, err := s.GetChildren(ctx, &folder.GetChildrenQuery{UID: "", OrgID: q.OrgID, SignedInUser: q.SignedInUser, Permission: q.Permission})
|
||||
if err != nil {
|
||||
s.metrics.sharedWithMeFetchFoldersRequestsDuration.WithLabelValues("failure").Observe(time.Since(start).Seconds())
|
||||
return nil, folder.ErrInternal.Errorf("failed to fetch root folders to which the user has access: %w", err)
|
||||
@@ -417,10 +433,21 @@ func (s *Service) GetSharedWithMe(ctx context.Context, q *folder.GetChildrenQuer
|
||||
return availableNonRootFolders, nil
|
||||
}
|
||||
|
||||
func (s *Service) getAvailableNonRootFolders(ctx context.Context, orgID int64, user identity.Requester) ([]*folder.Folder, error) {
|
||||
permissions := user.GetPermissions()
|
||||
folderPermissions := permissions[dashboards.ActionFoldersRead]
|
||||
folderPermissions = append(folderPermissions, permissions[dashboards.ActionDashboardsRead]...)
|
||||
func (s *Service) getAvailableNonRootFolders(ctx context.Context, q *folder.GetChildrenQuery) ([]*folder.Folder, error) {
|
||||
permissions := q.SignedInUser.GetPermissions()
|
||||
var folderPermissions []string
|
||||
if q.Permission == dashboardaccess.PERMISSION_EDIT {
|
||||
folderPermissions = permissions[dashboards.ActionFoldersWrite]
|
||||
folderPermissions = append(folderPermissions, permissions[dashboards.ActionDashboardsWrite]...)
|
||||
} else {
|
||||
folderPermissions = permissions[dashboards.ActionFoldersRead]
|
||||
folderPermissions = append(folderPermissions, permissions[dashboards.ActionDashboardsRead]...)
|
||||
}
|
||||
|
||||
if len(folderPermissions) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
nonRootFolders := make([]*folder.Folder, 0)
|
||||
folderUids := make([]string, 0, len(folderPermissions))
|
||||
for _, p := range folderPermissions {
|
||||
@@ -437,8 +464,9 @@ func (s *Service) getAvailableNonRootFolders(ctx context.Context, orgID int64, u
|
||||
|
||||
dashFolders, err := s.GetFolders(ctx, folder.GetFoldersQuery{
|
||||
UIDs: folderUids,
|
||||
OrgID: orgID,
|
||||
SignedInUser: user,
|
||||
OrgID: q.OrgID,
|
||||
SignedInUser: q.SignedInUser,
|
||||
OrderByTitle: true,
|
||||
WithFullpathUIDs: true,
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user