From fe11a31175574be96acaa29e740df9e58bb9e859 Mon Sep 17 00:00:00 2001 From: Marcus Andersson Date: Tue, 26 Oct 2021 15:18:12 +0200 Subject: [PATCH] PluginsCatalog: disable post-installation steps if user does not have sufficient permissions (#40853) * added missing permissions check * moved the permission check to the datasource component. * added test for checking permissions. * added tests with different permissions. * minor refactoring so the mockUserPermisson can be reused. --- public/app/features/live/pages/routes.ts | 2 +- .../plugins/admin/__mocks__/mockHelpers.ts | 17 + .../GetStartedWithDataSource.tsx | 7 +- .../components/InstallControls/index.tsx | 3 +- public/app/features/plugins/admin/helpers.ts | 9 - .../admin/hooks/usePluginDetailsTabs.tsx | 2 +- .../admin/pages/PluginDetails.test.tsx | 688 ++++++++++-------- .../app/features/plugins/admin/permissions.ts | 18 + public/app/features/plugins/routes.ts | 2 +- 9 files changed, 426 insertions(+), 322 deletions(-) create mode 100644 public/app/features/plugins/admin/permissions.ts diff --git a/public/app/features/live/pages/routes.ts b/public/app/features/live/pages/routes.ts index d95721107e4..7620f07c10e 100644 --- a/public/app/features/live/pages/routes.ts +++ b/public/app/features/live/pages/routes.ts @@ -1,7 +1,7 @@ import { SafeDynamicImport } from 'app/core/components/DynamicImports/SafeDynamicImport'; import { config } from 'app/core/config'; import { RouteDescriptor } from 'app/core/navigation/types'; -import { isGrafanaAdmin } from 'app/features/plugins/admin/helpers'; +import { isGrafanaAdmin } from 'app/features/plugins/admin/permissions'; const liveRoutes = [ { diff --git a/public/app/features/plugins/admin/__mocks__/mockHelpers.ts b/public/app/features/plugins/admin/__mocks__/mockHelpers.ts index 23d586ba269..14e31fae777 100644 --- a/public/app/features/plugins/admin/__mocks__/mockHelpers.ts +++ b/public/app/features/plugins/admin/__mocks__/mockHelpers.ts @@ -1,3 +1,4 @@ +import { mocked } from 'ts-jest/utils'; import { setBackendSrv } from '@grafana/runtime'; import { API_ROOT, GRAFANA_API_ROOT } from '../constants'; import { @@ -9,6 +10,7 @@ import { RequestStatus, PluginListDisplayMode, } from '../types'; +import * as permissions from '../permissions'; import remotePluginMock from './remotePlugin.mock'; import localPluginMock from './localPlugin.mock'; import catalogPluginMock from './catalogPlugin.mock'; @@ -98,3 +100,18 @@ export const mockPluginApis = ({ }, }); }; + +type UserAccessTestContext = { + isAdmin: boolean; + isOrgAdmin: boolean; + isDataSourceEditor: boolean; +}; + +jest.mock('../permissions'); + +export function mockUserPermissions(options: UserAccessTestContext): void { + const mock = mocked(permissions); + mock.isDataSourceEditor.mockReturnValue(options.isDataSourceEditor); + mock.isOrgAdmin.mockReturnValue(options.isOrgAdmin); + mock.isGrafanaAdmin.mockReturnValue(options.isAdmin); +} diff --git a/public/app/features/plugins/admin/components/GetStartedWithPlugin/GetStartedWithDataSource.tsx b/public/app/features/plugins/admin/components/GetStartedWithPlugin/GetStartedWithDataSource.tsx index 65bb88ed27f..55e7c3f29ae 100644 --- a/public/app/features/plugins/admin/components/GetStartedWithPlugin/GetStartedWithDataSource.tsx +++ b/public/app/features/plugins/admin/components/GetStartedWithPlugin/GetStartedWithDataSource.tsx @@ -3,13 +3,14 @@ import { Button } from '@grafana/ui'; import { addDataSource } from 'app/features/datasources/state/actions'; import React, { useCallback } from 'react'; import { useDispatch } from 'react-redux'; +import { isDataSourceEditor } from '../../permissions'; import { CatalogPlugin } from '../../types'; type Props = { plugin: CatalogPlugin; }; -export function GetStartedWithDataSource({ plugin }: Props): React.ReactElement { +export function GetStartedWithDataSource({ plugin }: Props): React.ReactElement | null { const dispatch = useDispatch(); const onAddDataSource = useCallback(() => { const meta = { @@ -20,6 +21,10 @@ export function GetStartedWithDataSource({ plugin }: Props): React.ReactElement dispatch(addDataSource(meta)); }, [dispatch, plugin]); + if (!isDataSourceEditor()) { + return null; + } + return (