From 913540dbac0570bcb497eee41826055a42848113 Mon Sep 17 00:00:00 2001 From: Michelle Bergquist Date: Mon, 18 Nov 2024 14:11:18 -0700 Subject: [PATCH] Add route and header for aws oidc dash --- web/packages/design/src/Label/Label.tsx | 7 +- .../design/src/Label/{index.js => index.ts} | 4 +- .../src/Integrations/IntegrationList.tsx | 41 ++------ .../src/Integrations/IntegrationStatus.tsx | 5 + .../teleport/src/Integrations/helpers.test.ts | 93 +++++++++++++++++++ .../teleport/src/Integrations/helpers.ts | 74 +++++++++++++++ .../status/AwsOidc/AwsOidcDashboard.story.tsx | 50 ++++++++++ .../status/AwsOidc/AwsOidcDashboard.test.tsx | 55 +++++++++++ .../status/AwsOidc/AwsOidcDashboard.tsx | 35 +++++++ .../status/AwsOidc/AwsOidcHeader.tsx | 55 +++++++++++ .../status/AwsOidc/AwsOidcRoutes.tsx | 41 ++++++++ .../testHelpers/mockAwsOidcStatusProvider.tsx | 48 ++++++++++ .../status/AwsOidc/useAwsOidcStatus.tsx | 76 +++++++++++++++ 13 files changed, 550 insertions(+), 34 deletions(-) rename web/packages/design/src/Label/{index.js => index.ts} (88%) create mode 100644 web/packages/teleport/src/Integrations/helpers.test.ts create mode 100644 web/packages/teleport/src/Integrations/helpers.ts create mode 100644 web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcDashboard.story.tsx create mode 100644 web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcDashboard.test.tsx create mode 100644 web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcDashboard.tsx create mode 100644 web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcHeader.tsx create mode 100644 web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcRoutes.tsx create mode 100644 web/packages/teleport/src/Integrations/status/AwsOidc/testHelpers/mockAwsOidcStatusProvider.tsx create mode 100644 web/packages/teleport/src/Integrations/status/AwsOidc/useAwsOidcStatus.tsx diff --git a/web/packages/design/src/Label/Label.tsx b/web/packages/design/src/Label/Label.tsx index 78f90ccead524..5dd8797d81b2a 100644 --- a/web/packages/design/src/Label/Label.tsx +++ b/web/packages/design/src/Label/Label.tsx @@ -59,7 +59,12 @@ const kind = ({ kind, theme }: { kind?: LabelKind; theme: Theme }) => { }; }; -type LabelKind = 'primary' | 'secondary' | 'warning' | 'danger' | 'success'; +export type LabelKind = + | 'primary' + | 'secondary' + | 'warning' + | 'danger' + | 'success'; interface LabelProps extends SpaceProps { kind?: LabelKind; diff --git a/web/packages/design/src/Label/index.js b/web/packages/design/src/Label/index.ts similarity index 88% rename from web/packages/design/src/Label/index.js rename to web/packages/design/src/Label/index.ts index e7c934c6f4029..500af263e629f 100644 --- a/web/packages/design/src/Label/index.js +++ b/web/packages/design/src/Label/index.ts @@ -16,6 +16,8 @@ * along with this program. If not, see . */ -import Label, { Primary, Secondary, Warning, Danger } from './Label'; +import Label, { Danger, Primary, Secondary, Warning } from './Label'; + export default Label; export { Primary, Secondary, Warning, Danger }; +export type { LabelKind } from './Label'; diff --git a/web/packages/teleport/src/Integrations/IntegrationList.tsx b/web/packages/teleport/src/Integrations/IntegrationList.tsx index c143158f91848..dfd8a89159efa 100644 --- a/web/packages/teleport/src/Integrations/IntegrationList.tsx +++ b/web/packages/teleport/src/Integrations/IntegrationList.tsx @@ -33,16 +33,18 @@ import useStickyClusterId from 'teleport/useStickyClusterId'; import api from 'teleport/services/api'; import { + ExternalAuditStorageIntegration, getStatusCodeDescription, getStatusCodeTitle, Integration, - IntegrationStatusCode, IntegrationKind, + IntegrationStatusCode, Plugin, - ExternalAuditStorageIntegration, } from 'teleport/services/integrations'; import cfg from 'teleport/config'; +import { getStatus } from 'teleport/Integrations/helpers'; + import { ExternalAuditStorageOpType } from './Operations/useIntegrationOperation'; type Props = { @@ -55,7 +57,10 @@ type Props = { onDeleteExternalAuditStorage?(opType: ExternalAuditStorageOpType): void; }; -type IntegrationLike = Integration | Plugin | ExternalAuditStorageIntegration; +export type IntegrationLike = + | Integration + | Plugin + | ExternalAuditStorageIntegration; export function IntegrationList(props: Props) { const history = useHistory(); @@ -254,40 +259,12 @@ const StatusCell = ({ item }: { item: IntegrationLike }) => { ); }; -enum Status { +export enum Status { Success, Warning, Error, } -function getStatus(item: IntegrationLike): Status | null { - if (item.resourceType === 'integration') { - return Status.Success; - } - - if (item.resourceType === 'external-audit-storage') { - switch (item.statusCode) { - case IntegrationStatusCode.Draft: - return Status.Warning; - default: - return Status.Success; - } - } - - switch (item.statusCode) { - case IntegrationStatusCode.Unknown: - return null; - case IntegrationStatusCode.Running: - return Status.Success; - case IntegrationStatusCode.SlackNotInChannel: - return Status.Warning; - case IntegrationStatusCode.Draft: - return Status.Warning; - default: - return Status.Error; - } -} - const StatusLight = styled(Box)<{ status: Status }>` border-radius: 50%; margin-right: 4px; diff --git a/web/packages/teleport/src/Integrations/IntegrationStatus.tsx b/web/packages/teleport/src/Integrations/IntegrationStatus.tsx index 836fe97cfcec7..500067a68d86c 100644 --- a/web/packages/teleport/src/Integrations/IntegrationStatus.tsx +++ b/web/packages/teleport/src/Integrations/IntegrationStatus.tsx @@ -20,11 +20,16 @@ import React from 'react'; import { useParams } from 'react-router'; import { IntegrationKind, PluginKind } from 'teleport/services/integrations'; +import { AwsOidcRoutes } from 'teleport/Integrations/status/AwsOidc/AwsOidcRoutes'; export function IntegrationStatus() { const { type: integrationType } = useParams<{ type: PluginKind | IntegrationKind; }>(); + if (integrationType === 'aws-oidc') { + return ; + } + return <>Status for integration type {integrationType} is not supported; } diff --git a/web/packages/teleport/src/Integrations/helpers.test.ts b/web/packages/teleport/src/Integrations/helpers.test.ts new file mode 100644 index 0000000000000..86668ee0d5fe9 --- /dev/null +++ b/web/packages/teleport/src/Integrations/helpers.test.ts @@ -0,0 +1,93 @@ +/** + * 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 { + Integration, + IntegrationStatusCode, +} from 'teleport/services/integrations'; +import { getStatus, getStatusAndLabel } from 'teleport/Integrations/helpers'; +import { IntegrationLike, Status } from 'teleport/Integrations/IntegrationList'; + +test.each` + type | code | expected + ${'integration'} | ${IntegrationStatusCode.Draft} | ${Status.Success} + ${'integration'} | ${IntegrationStatusCode.Running} | ${Status.Success} + ${'integration'} | ${IntegrationStatusCode.Unauthorized} | ${Status.Success} + ${'integration'} | ${IntegrationStatusCode.SlackNotInChannel} | ${Status.Success} + ${'integration'} | ${IntegrationStatusCode.Unknown} | ${Status.Success} + ${'integration'} | ${IntegrationStatusCode.OtherError} | ${Status.Success} + ${'external-audit-storage'} | ${IntegrationStatusCode.Draft} | ${Status.Warning} + ${'external-audit-storage'} | ${IntegrationStatusCode.Running} | ${Status.Success} + ${'external-audit-storage'} | ${IntegrationStatusCode.Unauthorized} | ${Status.Success} + ${'external-audit-storage'} | ${IntegrationStatusCode.SlackNotInChannel} | ${Status.Success} + ${'external-audit-storage'} | ${IntegrationStatusCode.Unknown} | ${Status.Success} + ${'external-audit-storage'} | ${IntegrationStatusCode.OtherError} | ${Status.Success} + ${'any'} | ${IntegrationStatusCode.Draft} | ${Status.Warning} + ${'any'} | ${IntegrationStatusCode.Running} | ${Status.Success} + ${'any'} | ${IntegrationStatusCode.Unauthorized} | ${Status.Error} + ${'any'} | ${IntegrationStatusCode.SlackNotInChannel} | ${Status.Warning} + ${'any'} | ${IntegrationStatusCode.Unknown} | ${null} + ${'any'} | ${IntegrationStatusCode.OtherError} | ${Status.Error} +`( + 'getStatus type $type with code $code returns $expected', + async ({ type, code, expected }) => { + const item: IntegrationLike = { + name: '', + kind: undefined, + resourceType: type, + statusCode: code, + }; + const status = getStatus(item); + expect(status).toBe(expected); + } +); + +test.each` + type | code | expectedLabelKind | expectedTitle + ${'integration'} | ${IntegrationStatusCode.Draft} | ${'success'} | ${'Draft'} + ${'integration'} | ${IntegrationStatusCode.Running} | ${'success'} | ${'Running'} + ${'integration'} | ${IntegrationStatusCode.Unauthorized} | ${'success'} | ${'Unauthorized'} + ${'integration'} | ${IntegrationStatusCode.SlackNotInChannel} | ${'success'} | ${'Bot not invited to channel'} + ${'integration'} | ${IntegrationStatusCode.Unknown} | ${'success'} | ${'Unknown'} + ${'integration'} | ${IntegrationStatusCode.OtherError} | ${'success'} | ${'Unknown error'} + ${'external-audit-storage'} | ${IntegrationStatusCode.Draft} | ${'warning'} | ${'Draft'} + ${'external-audit-storage'} | ${IntegrationStatusCode.Running} | ${'success'} | ${'Running'} + ${'external-audit-storage'} | ${IntegrationStatusCode.Unauthorized} | ${'success'} | ${'Unauthorized'} + ${'external-audit-storage'} | ${IntegrationStatusCode.SlackNotInChannel} | ${'success'} | ${'Bot not invited to channel'} + ${'external-audit-storage'} | ${IntegrationStatusCode.Unknown} | ${'success'} | ${'Unknown'} + ${'external-audit-storage'} | ${IntegrationStatusCode.OtherError} | ${'success'} | ${'Unknown error'} + ${'any'} | ${IntegrationStatusCode.Draft} | ${'warning'} | ${'Draft'} + ${'any'} | ${IntegrationStatusCode.Running} | ${'success'} | ${'Running'} + ${'any'} | ${IntegrationStatusCode.Unauthorized} | ${'danger'} | ${'Unauthorized'} + ${'any'} | ${IntegrationStatusCode.SlackNotInChannel} | ${'warning'} | ${'Bot not invited to channel'} + ${'any'} | ${IntegrationStatusCode.Unknown} | ${'secondary'} | ${'Unknown'} + ${'any'} | ${IntegrationStatusCode.OtherError} | ${'danger'} | ${'Unknown error'} +`( + 'getStatusAndLabel type $type with code $code returns expected', + async ({ type, code, expectedLabelKind, expectedTitle }) => { + const item: Integration = { + name: '', + kind: undefined, + resourceType: type, + statusCode: code, + }; + const status = getStatusAndLabel(item); + expect(status.status).toBe(expectedTitle); + expect(status.labelKind).toBe(expectedLabelKind); + } +); diff --git a/web/packages/teleport/src/Integrations/helpers.ts b/web/packages/teleport/src/Integrations/helpers.ts new file mode 100644 index 0000000000000..87690be4a421f --- /dev/null +++ b/web/packages/teleport/src/Integrations/helpers.ts @@ -0,0 +1,74 @@ +/** + * 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 { LabelKind } from 'design/Label'; + +import { + getStatusCodeTitle, + Integration, + IntegrationStatusCode, +} from 'teleport/services/integrations'; +import { IntegrationLike, Status } from 'teleport/Integrations/IntegrationList'; + +export function getStatus(item: IntegrationLike): Status { + if (item.resourceType === 'integration') { + return Status.Success; + } + + if (item.resourceType === 'external-audit-storage') { + switch (item.statusCode) { + case IntegrationStatusCode.Draft: + return Status.Warning; + default: + return Status.Success; + } + } + + switch (item.statusCode) { + case IntegrationStatusCode.Unknown: + return null; + case IntegrationStatusCode.Running: + return Status.Success; + case IntegrationStatusCode.SlackNotInChannel: + return Status.Warning; + case IntegrationStatusCode.Draft: + return Status.Warning; + default: + return Status.Error; + } +} + +export function getStatusAndLabel(integration: Integration): { + labelKind: LabelKind; + status: string; +} { + const modifiedStatus = getStatus(integration); + const statusCode = integration.statusCode; + const title = getStatusCodeTitle(statusCode); + + switch (modifiedStatus) { + case Status.Success: + return { labelKind: 'success', status: title }; + case Status.Error: + return { labelKind: 'danger', status: title }; + case Status.Warning: + return { labelKind: 'warning', status: title }; + default: + return { labelKind: 'secondary', status: title }; + } +} diff --git a/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcDashboard.story.tsx b/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcDashboard.story.tsx new file mode 100644 index 0000000000000..c18cc1e8c1fe5 --- /dev/null +++ b/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcDashboard.story.tsx @@ -0,0 +1,50 @@ +/** + * 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 React from 'react'; + +import { AwsOidcDashboard } from 'teleport/Integrations/status/AwsOidc/AwsOidcDashboard'; +import { MockAwsOidcStatusProvider } from 'teleport/Integrations/status/AwsOidc/testHelpers/mockAwsOidcStatusProvider'; + +export default { + title: 'Teleport/Integrations/AwsOidc', +}; + +export function Dashboard() { + return ( + + + + ); +} diff --git a/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcDashboard.test.tsx b/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcDashboard.test.tsx new file mode 100644 index 0000000000000..44acb1827c014 --- /dev/null +++ b/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcDashboard.test.tsx @@ -0,0 +1,55 @@ +/** + * 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 React from 'react'; +import { render, screen } from 'design/utils/testing'; + +import { AwsOidcDashboard } from 'teleport/Integrations/status/AwsOidc/AwsOidcDashboard'; +import { MockAwsOidcStatusProvider } from 'teleport/Integrations/status/AwsOidc/testHelpers/mockAwsOidcStatusProvider'; + +test('renders header', () => { + render( + + + + ); + + expect(screen.getByRole('link', { name: 'back' })).toHaveAttribute( + 'href', + '/web/integrations' + ); + expect(screen.getByText('integration-one')).toBeInTheDocument(); + expect(screen.getByLabelText('status')).toHaveAttribute('kind', 'success'); + expect(screen.getByLabelText('status')).toHaveTextContent('Running'); +}); diff --git a/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcDashboard.tsx b/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcDashboard.tsx new file mode 100644 index 0000000000000..45779ea05ed70 --- /dev/null +++ b/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcDashboard.tsx @@ -0,0 +1,35 @@ +/** + * 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 React from 'react'; + +import { AwsOidcHeader } from 'teleport/Integrations/status/AwsOidc/AwsOidcHeader'; +import { useAwsOidcStatus } from 'teleport/Integrations/status/AwsOidc/useAwsOidcStatus'; +import { FeatureBox } from 'teleport/components/Layout'; + +// todo (michellescripts) after routing, ensure this view can be sticky +export function AwsOidcDashboard() { + const { attempt } = useAwsOidcStatus(); + + return ( + + + Status for integration type aws-oidc is not supported + + ); +} diff --git a/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcHeader.tsx b/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcHeader.tsx new file mode 100644 index 0000000000000..136e3ee354e09 --- /dev/null +++ b/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcHeader.tsx @@ -0,0 +1,55 @@ +/** + * 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 React from 'react'; +import { Link as InternalLink } from 'react-router-dom'; + +import { ButtonIcon, Flex, Label, Text } from 'design'; +import { ArrowLeft } from 'design/Icon'; +import { HoverTooltip } from 'shared/components/ToolTip'; + +import cfg from 'teleport/config'; +import { getStatusAndLabel } from 'teleport/Integrations/helpers'; +import { Integration } from 'teleport/services/integrations'; + +export function AwsOidcHeader({ + integration, +}: { + integration: Integration | null; +}) { + const { status, labelKind } = getStatusAndLabel(integration); + return ( + + + + + + + + {integration?.name} + + + + ); +} diff --git a/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcRoutes.tsx b/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcRoutes.tsx new file mode 100644 index 0000000000000..b218fc905706d --- /dev/null +++ b/web/packages/teleport/src/Integrations/status/AwsOidc/AwsOidcRoutes.tsx @@ -0,0 +1,41 @@ +/** + * 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 React from 'react'; + +import { Route, Switch } from 'teleport/components/Router'; +import cfg from 'teleport/config'; + +import { AwsOidcStatusProvider } from 'teleport/Integrations/status/AwsOidc/useAwsOidcStatus'; + +import { AwsOidcDashboard } from './AwsOidcDashboard'; + +export function AwsOidcRoutes() { + return ( + + + + + + ); +} diff --git a/web/packages/teleport/src/Integrations/status/AwsOidc/testHelpers/mockAwsOidcStatusProvider.tsx b/web/packages/teleport/src/Integrations/status/AwsOidc/testHelpers/mockAwsOidcStatusProvider.tsx new file mode 100644 index 0000000000000..4d29af57d0422 --- /dev/null +++ b/web/packages/teleport/src/Integrations/status/AwsOidc/testHelpers/mockAwsOidcStatusProvider.tsx @@ -0,0 +1,48 @@ +/** + * 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 React from 'react'; + +import { MemoryRouter } from 'react-router'; + +import { + awsOidcStatusContext, + AwsOidcStatusContextState, +} from 'teleport/Integrations/status/AwsOidc/useAwsOidcStatus'; +import { ContextProvider } from 'teleport'; +import { createTeleportContext } from 'teleport/mocks/contexts'; + +export const MockAwsOidcStatusProvider = ({ + children, + value, +}: { + children?: React.ReactNode; + value: AwsOidcStatusContextState; +}) => { + const ctx = createTeleportContext(); + + return ( + + + + {children} + + + + ); +}; diff --git a/web/packages/teleport/src/Integrations/status/AwsOidc/useAwsOidcStatus.tsx b/web/packages/teleport/src/Integrations/status/AwsOidc/useAwsOidcStatus.tsx new file mode 100644 index 0000000000000..3b11e3f72f0c2 --- /dev/null +++ b/web/packages/teleport/src/Integrations/status/AwsOidc/useAwsOidcStatus.tsx @@ -0,0 +1,76 @@ +/** + * Teleport + * Copyright (C) 2023 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 React, { createContext, useContext, useEffect } from 'react'; +import { useParams } from 'react-router'; +import { Attempt, useAsync } from 'shared/hooks/useAsync'; + +import { + Integration, + IntegrationKind, + integrationService, +} from 'teleport/services/integrations'; + +import useTeleport from 'teleport/useTeleport'; + +interface AwsOidcStatusContextState { + attempt: Attempt; +} + +export const awsOidcStatusContext = + createContext(null); + +export function AwsOidcStatusProvider({ children }: React.PropsWithChildren) { + const { name } = useParams<{ + type: IntegrationKind; + name: string; + }>(); + const ctx = useTeleport(); + const integrationAccess = ctx.storeUser.getIntegrationsAccess(); + const hasIntegrationReadAccess = integrationAccess.read; + + const [attempt, fetchIntegration] = useAsync(async () => { + return await integrationService.fetchIntegration(name); + }); + + useEffect(() => { + if (hasIntegrationReadAccess) { + fetchIntegration(); + } + }, []); + + const value: AwsOidcStatusContextState = { + attempt, + }; + + return ( + + {children} + + ); +} + +export function useAwsOidcStatus(): AwsOidcStatusContextState { + const context = useContext(awsOidcStatusContext); + if (!context) { + throw new Error( + 'useAwsOidcStatus must be used within a AwsOidcStatusProvider' + ); + } + return context; +}