From b4559b41c297795e9bb98c0077b53db0e61db644 Mon Sep 17 00:00:00 2001 From: Karl Persson Date: Fri, 10 Jun 2022 15:26:00 +0200 Subject: [PATCH] RBAC: fix access control check in both new navivation and new search view (#50596) * check access control permissions for new navigation * check access control actions in new search view --- pkg/api/index.go | 28 +++++++++++++------ .../search/components/DashboardActions.tsx | 12 ++++---- .../search/components/ManageDashboards.tsx | 13 +++++++-- .../search/components/ManageDashboardsNew.tsx | 11 ++++++-- 4 files changed, 45 insertions(+), 19 deletions(-) diff --git a/pkg/api/index.go b/pkg/api/index.go index c288c653817..945840a2936 100644 --- a/pkg/api/index.go +++ b/pkg/api/index.go @@ -460,6 +460,11 @@ func (hs *HTTPServer) buildStarredItemsNavLinks(c *models.ReqContext, prefs *pre } func (hs *HTTPServer) buildDashboardNavLinks(c *models.ReqContext, hasEditPerm bool) []*dtos.NavLink { + hasAccess := ac.HasAccess(hs.AccessControl, c) + hasEditPermInAnyFolder := func(c *models.ReqContext) bool { + return hasEditPerm + } + dashboardChildNavs := []*dtos.NavLink{} if !hs.Features.IsEnabled(featuremgmt.FlagNewNavigation) { dashboardChildNavs = append(dashboardChildNavs, &dtos.NavLink{ @@ -496,19 +501,26 @@ func (hs *HTTPServer) buildDashboardNavLinks(c *models.ReqContext, hasEditPerm b dashboardChildNavs = append(dashboardChildNavs, &dtos.NavLink{ Text: "Divider", Divider: true, Id: "divider", HideFromTabs: true, }) - dashboardChildNavs = append(dashboardChildNavs, &dtos.NavLink{ - Text: "New dashboard", Icon: "plus", Url: hs.Cfg.AppSubURL + "/dashboard/new", HideFromTabs: true, Id: "new-dashboard", ShowIconInNavbar: true, - }) - if c.OrgRole == models.ROLE_ADMIN || c.OrgRole == models.ROLE_EDITOR { + + if hasAccess(hasEditPermInAnyFolder, ac.EvalPermission(dashboards.ActionDashboardsCreate)) { + dashboardChildNavs = append(dashboardChildNavs, &dtos.NavLink{ + Text: "New dashboard", Icon: "plus", Url: hs.Cfg.AppSubURL + "/dashboard/new", HideFromTabs: true, Id: "new-dashboard", ShowIconInNavbar: true, + }) + } + + if hasAccess(ac.ReqOrgAdminOrEditor, ac.EvalPermission(dashboards.ActionFoldersCreate)) { dashboardChildNavs = append(dashboardChildNavs, &dtos.NavLink{ Text: "New folder", SubTitle: "Create a new folder to organize your dashboards", Id: "new-folder", Icon: "plus", Url: hs.Cfg.AppSubURL + "/dashboards/folder/new", HideFromTabs: true, ShowIconInNavbar: true, }) } - dashboardChildNavs = append(dashboardChildNavs, &dtos.NavLink{ - Text: "Import", SubTitle: "Import dashboard from file or Grafana.com", Id: "import", Icon: "plus", - Url: hs.Cfg.AppSubURL + "/dashboard/import", HideFromTabs: true, ShowIconInNavbar: true, - }) + + if hasAccess(hasEditPermInAnyFolder, ac.EvalPermission(dashboards.ActionDashboardsCreate)) { + dashboardChildNavs = append(dashboardChildNavs, &dtos.NavLink{ + Text: "Import", SubTitle: "Import dashboard from file or Grafana.com", Id: "import", Icon: "plus", + Url: hs.Cfg.AppSubURL + "/dashboard/import", HideFromTabs: true, ShowIconInNavbar: true, + }) + } } return dashboardChildNavs } diff --git a/public/app/features/search/components/DashboardActions.tsx b/public/app/features/search/components/DashboardActions.tsx index 95b8f6e04b9..945cf39e67d 100644 --- a/public/app/features/search/components/DashboardActions.tsx +++ b/public/app/features/search/components/DashboardActions.tsx @@ -4,11 +4,11 @@ import { HorizontalGroup, LinkButton } from '@grafana/ui'; export interface Props { folderId?: number; - isEditor: boolean; - canEdit?: boolean; + canCreateFolders?: boolean; + canCreateDashboards?: boolean; } -export const DashboardActions: FC = ({ folderId, isEditor, canEdit }) => { +export const DashboardActions: FC = ({ folderId, canCreateFolders = false, canCreateDashboards = false }) => { const actionUrl = (type: string) => { let url = `dashboard/${type}`; @@ -22,9 +22,9 @@ export const DashboardActions: FC = ({ folderId, isEditor, canEdit }) => return (
- {canEdit && New Dashboard} - {!folderId && isEditor && New Folder} - {canEdit && Import} + {canCreateDashboards && New Dashboard} + {!folderId && canCreateFolders && New Folder} + {canCreateDashboards && Import}
); diff --git a/public/app/features/search/components/ManageDashboards.tsx b/public/app/features/search/components/ManageDashboards.tsx index 0a5737ae657..01b201f98bc 100644 --- a/public/app/features/search/components/ManageDashboards.tsx +++ b/public/app/features/search/components/ManageDashboards.tsx @@ -5,7 +5,7 @@ import { GrafanaTheme } from '@grafana/data'; import { FilterInput, Spinner, stylesFactory, useTheme } from '@grafana/ui'; import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; import { contextSrv } from 'app/core/services/context_srv'; -import { FolderDTO } from 'app/types'; +import { FolderDTO, AccessControlAction } from 'app/types'; import { useManageDashboards } from '../hooks/useManageDashboards'; import { useSearchQuery } from '../hooks/useSearchQuery'; @@ -53,10 +53,10 @@ export const ManageDashboards: FC = memo(({ folder }) => { results, loading, initialLoading, - canSave, allChecked, hasEditPermissionInFolders, canMove, + canSave, canDelete, onToggleSection, onToggleChecked, @@ -101,7 +101,14 @@ export const ManageDashboards: FC = memo(({ folder }) => {
- +
diff --git a/public/app/features/search/components/ManageDashboardsNew.tsx b/public/app/features/search/components/ManageDashboardsNew.tsx index 8c40c37f389..8bb968176e3 100644 --- a/public/app/features/search/components/ManageDashboardsNew.tsx +++ b/public/app/features/search/components/ManageDashboardsNew.tsx @@ -6,7 +6,7 @@ import { GrafanaTheme2 } from '@grafana/data'; import { config } from '@grafana/runtime'; import { Input, useStyles2, Spinner } from '@grafana/ui'; import { contextSrv } from 'app/core/services/context_srv'; -import { FolderDTO } from 'app/types'; +import { FolderDTO, AccessControlAction } from 'app/types'; import { SEARCH_PANELS_LOCAL_STORAGE_KEY } from '../constants'; import { useSearchQuery } from '../hooks/useSearchQuery'; @@ -57,7 +57,14 @@ export const ManageDashboardsNew = React.memo(({ folder }: Props) => { suffix={false ? : null} />
- +