From 0d2683d1e199e1638264ca7d4da0e943c8f7cc31 Mon Sep 17 00:00:00 2001 From: Michael Myers Date: Fri, 13 Dec 2024 14:59:57 -0600 Subject: [PATCH] [v16] Disable Enroll New Integration button on missing permissions Backport https://github.com/gravitational/teleport/pull/50173 --- .../MissingPermissionsTooltip.tsx | 10 +++- .../src/Integrations/Integrations.tsx | 12 +++-- .../IntegrationsAddButton.test.tsx | 54 +++++++++++++++++++ .../Integrations/IntegrationsAddButton.tsx | 48 ++++++++++++----- web/packages/teleport/src/features.tsx | 14 ++++- 5 files changed, 120 insertions(+), 18 deletions(-) create mode 100644 web/packages/teleport/src/Integrations/IntegrationsAddButton.test.tsx diff --git a/web/packages/shared/components/MissingPermissionsTooltip/MissingPermissionsTooltip.tsx b/web/packages/shared/components/MissingPermissionsTooltip/MissingPermissionsTooltip.tsx index aaef46ec0baf6..f414c2526318f 100644 --- a/web/packages/shared/components/MissingPermissionsTooltip/MissingPermissionsTooltip.tsx +++ b/web/packages/shared/components/MissingPermissionsTooltip/MissingPermissionsTooltip.tsx @@ -20,14 +20,22 @@ import { Box, Text, Flex } from 'design'; export const MissingPermissionsTooltip = ({ missingPermissions, + requiresAll = true, }: { missingPermissions: string[]; + requiresAll?: boolean; }) => { return ( You do not have all of the required permissions. - Missing permissions: + {requiresAll ? ( + Missing permissions: + ) : ( + + You must have at least one of these role permissions: + + )} {missingPermissions.map(perm => ( {perm} diff --git a/web/packages/teleport/src/Integrations/Integrations.tsx b/web/packages/teleport/src/Integrations/Integrations.tsx index e528a252db7d0..619bb791a0acc 100644 --- a/web/packages/teleport/src/Integrations/Integrations.tsx +++ b/web/packages/teleport/src/Integrations/Integrations.tsx @@ -41,7 +41,6 @@ export function Integrations() { const { attempt, run } = useAttempt('processing'); const ctx = useTeleport(); - const canCreateIntegrations = ctx.storeUser.getIntegrationsAccess().create; useEffect(() => { // TODO(lisa): handle paginating as a follow up polish. @@ -80,9 +79,16 @@ export function Integrations() { return ( <> - + Integrations - + {attempt.status === 'failed' && } {attempt.status === 'processing' && ( diff --git a/web/packages/teleport/src/Integrations/IntegrationsAddButton.test.tsx b/web/packages/teleport/src/Integrations/IntegrationsAddButton.test.tsx new file mode 100644 index 0000000000000..6021f79e52a96 --- /dev/null +++ b/web/packages/teleport/src/Integrations/IntegrationsAddButton.test.tsx @@ -0,0 +1,54 @@ +/** + * Teleport + * Copyright (C) 2024 Gravitational, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { MemoryRouter } from 'react-router'; +import { render, screen } from 'design/utils/testing'; + +import { IntegrationsAddButton } from './IntegrationsAddButton'; + +test('is disables if all permissions are missing', async () => { + render( + + + + ); + + expect( + screen.getByTitle('You do not have access to add new integrations') + ).toBeInTheDocument(); +}); + +test('is enabled if at least one permission is true', async () => { + render( + + + + ); + + expect(screen.getByText('Enroll New Integration')).toBeEnabled(); +}); diff --git a/web/packages/teleport/src/Integrations/IntegrationsAddButton.tsx b/web/packages/teleport/src/Integrations/IntegrationsAddButton.tsx index d3dc829690a28..443df9285c0bc 100644 --- a/web/packages/teleport/src/Integrations/IntegrationsAddButton.tsx +++ b/web/packages/teleport/src/Integrations/IntegrationsAddButton.tsx @@ -18,25 +18,49 @@ import React from 'react'; import { Link } from 'react-router-dom'; -import { ButtonPrimary } from 'design'; +import { Button } from 'design'; +import { HoverTooltip } from 'shared/components/ToolTip'; +import { MissingPermissionsTooltip } from 'shared/components/MissingPermissionsTooltip'; import cfg from 'teleport/config'; export function IntegrationsAddButton({ - canCreate = false, + requiredPermissions, }: { - canCreate: boolean; + requiredPermissions: { value: boolean; label: string }[]; }) { + const canCreateIntegrations = requiredPermissions.some(v => v.value); + const missingPermissions = requiredPermissions + .filter(perm => !perm.value) + .map(perm => perm.label); + return ( - + ) + } > - Enroll new integration - + + ); } diff --git a/web/packages/teleport/src/features.tsx b/web/packages/teleport/src/features.tsx index b6a698645b336..f042f2b0bfb73 100644 --- a/web/packages/teleport/src/features.tsx +++ b/web/packages/teleport/src/features.tsx @@ -221,7 +221,12 @@ export class FeatureBots implements TeleportFeature { component: Bots, }; - hasAccess() { + hasAccess(flags: FeatureFlags) { + // if feature hiding is enabled, only show + // if the user has access + if (cfg.hideInaccessibleFeatures) { + return flags.listBots; + } return true; } @@ -388,7 +393,12 @@ export class FeatureIntegrations implements TeleportFeature { section = ManagementSection.Access; hasAccess(flags: FeatureFlags) { - return flags.integrations; + // if feature hiding is enabled, only show + // if the user has access + if (cfg.hideInaccessibleFeatures) { + return flags.integrations; + } + return true; } route = {