diff --git a/.changeset/ten-dryers-compete.md b/.changeset/ten-dryers-compete.md index 14fdcd1e6c..02715d0736 100644 --- a/.changeset/ten-dryers-compete.md +++ b/.changeset/ten-dryers-compete.md @@ -4,10 +4,4 @@ '@backstage/plugin-azure-devops-common': patch --- -Azure DevOps plugin is now integrated with permission framework for the below features - -1. PullRequest -2. Dashboard Pull Request -3. Pipeline -4. GitTag -5. Readme +Azure DevOps plugin is now integrated with permission framework for its core features, see the https://github.com/backstage/backstage/blob/master/plugins/azure-devops/README.md for more details. diff --git a/plugins/azure-devops-common/api-report.md b/plugins/azure-devops-common/api-report.md index 7e559ac4fc..c926823367 100644 --- a/plugins/azure-devops-common/api-report.md +++ b/plugins/azure-devops-common/api-report.md @@ -25,36 +25,24 @@ export const AZURE_DEVOPS_README_ANNOTATION = 'dev.azure.com/readme-path'; // @public (undocumented) export const AZURE_DEVOPS_REPO_ANNOTATION = 'dev.azure.com/project-repo'; -// Warning: (ae-missing-release-tag) "azureDevOpsGitTagReadPermission" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const azureDevOpsGitTagReadPermission: ResourcePermission<'catalog-entity'>; -// Warning: (ae-missing-release-tag) "azureDevOpsPermissions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const azureDevOpsPermissions: ( | BasicPermission | ResourcePermission<'catalog-entity'> )[]; -// Warning: (ae-missing-release-tag) "azureDevOpsPipelineReadPermission" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const azureDevOpsPipelineReadPermission: ResourcePermission<'catalog-entity'>; -// Warning: (ae-missing-release-tag) "azureDevOpsPullRequestDashboardReadPermission" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const azureDevOpsPullRequestDashboardReadPermission: BasicPermission; -// Warning: (ae-missing-release-tag) "azureDevOpsPullRequestReadPermission" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const azureDevOpsPullRequestReadPermission: ResourcePermission<'catalog-entity'>; -// Warning: (ae-missing-release-tag) "azureDevOpsReadmeReadPermission" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const azureDevOpsReadmeReadPermission: ResourcePermission<'catalog-entity'>; diff --git a/plugins/azure-devops-common/src/permissions.ts b/plugins/azure-devops-common/src/permissions.ts index 86e1d26138..da1515580a 100644 --- a/plugins/azure-devops-common/src/permissions.ts +++ b/plugins/azure-devops-common/src/permissions.ts @@ -14,36 +14,55 @@ * limitations under the License. */ import { createPermission } from '@backstage/plugin-permission-common'; - import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common/alpha'; +/** + * @public + */ export const azureDevOpsPullRequestReadPermission = createPermission({ name: 'azure.devops.pullrequest.read', attributes: { action: 'read' }, resourceType: RESOURCE_TYPE_CATALOG_ENTITY, }); +/** + * @public + */ export const azureDevOpsPullRequestDashboardReadPermission = createPermission({ name: 'azure.devops.pullrequest.dashboard.read', attributes: { action: 'read' }, }); +/** + * @public + */ export const azureDevOpsPipelineReadPermission = createPermission({ name: 'azure.devops.pipeline.read', attributes: { action: 'read' }, resourceType: RESOURCE_TYPE_CATALOG_ENTITY, }); + +/** + * @public + */ export const azureDevOpsGitTagReadPermission = createPermission({ name: 'azure.devops.gittag.read', attributes: { action: 'read' }, resourceType: RESOURCE_TYPE_CATALOG_ENTITY, }); + +/** + * @public + */ export const azureDevOpsReadmeReadPermission = createPermission({ name: 'azure.devops.readme.read', attributes: { action: 'read' }, resourceType: RESOURCE_TYPE_CATALOG_ENTITY, }); +/** + * @public + */ export const azureDevOpsPermissions = [ azureDevOpsPullRequestReadPermission, azureDevOpsPipelineReadPermission, diff --git a/plugins/azure-devops/package.json b/plugins/azure-devops/package.json index 12860d82cc..6e72c4e45d 100644 --- a/plugins/azure-devops/package.json +++ b/plugins/azure-devops/package.json @@ -50,6 +50,7 @@ "@backstage/frontend-plugin-api": "workspace:^", "@backstage/plugin-azure-devops-common": "workspace:^", "@backstage/plugin-catalog-react": "workspace:^", + "@backstage/plugin-permission-react": "workspace:^", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", diff --git a/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx b/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx index bc69b68d56..09eba5f5a2 100644 --- a/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx +++ b/plugins/azure-devops/src/components/BuildTable/BuildTable.tsx @@ -32,14 +32,12 @@ import { StatusWarning, Table, TableColumn, - EmptyState, } from '@backstage/core-components'; import { AzurePipelinesIcon } from '../AzurePipelinesIcon'; import { DateTime } from 'luxon'; import React from 'react'; import { getDurationFromDates } from '../../utils/getDurationFromDates'; -import { isAuthorizationError } from '../../utils'; export const getBuildResultComponent = (result: number | undefined) => { switch (result) { @@ -181,15 +179,6 @@ type BuildTableProps = { export const BuildTable = ({ items, loading, error }: BuildTableProps) => { if (error) { - if (isAuthorizationError(error)) { - return ( - - ); - } return (
diff --git a/plugins/azure-devops/src/components/EntityPageAzureGitTags/EntityPageAzureGitTags.tsx b/plugins/azure-devops/src/components/EntityPageAzureGitTags/EntityPageAzureGitTags.tsx index 2d94d735df..1632649d59 100644 --- a/plugins/azure-devops/src/components/EntityPageAzureGitTags/EntityPageAzureGitTags.tsx +++ b/plugins/azure-devops/src/components/EntityPageAzureGitTags/EntityPageAzureGitTags.tsx @@ -14,7 +14,29 @@ * limitations under the License. */ +import { azureDevOpsGitTagReadPermission } from '@backstage/plugin-azure-devops-common'; import { GitTagTable } from '../GitTagTable/GitTagTable'; import React from 'react'; +import { stringifyEntityRef } from '@backstage/catalog-model'; +import { useEntity } from '@backstage/plugin-catalog-react'; +import { RequirePermission } from '@backstage/plugin-permission-react'; +import { EmptyState } from '@backstage/core-components'; -export const EntityPageAzureGitTags = () => ; +export const EntityPageAzureGitTags = () => { + const { entity } = useEntity(); + return ( + + } + > + + + ); +}; diff --git a/plugins/azure-devops/src/components/EntityPageAzurePipelines/EntityPageAzurePipelines.tsx b/plugins/azure-devops/src/components/EntityPageAzurePipelines/EntityPageAzurePipelines.tsx index c33d849c24..39e3da1a7e 100644 --- a/plugins/azure-devops/src/components/EntityPageAzurePipelines/EntityPageAzurePipelines.tsx +++ b/plugins/azure-devops/src/components/EntityPageAzurePipelines/EntityPageAzurePipelines.tsx @@ -18,11 +18,29 @@ import { BuildTable } from '../BuildTable/BuildTable'; import React from 'react'; import { useBuildRuns } from '../../hooks'; import { useEntity } from '@backstage/plugin-catalog-react'; +import { azureDevOpsPipelineReadPermission } from '@backstage/plugin-azure-devops-common'; +import { stringifyEntityRef } from '@backstage/catalog-model'; +import { RequirePermission } from '@backstage/plugin-permission-react'; +import { EmptyState } from '@backstage/core-components'; export const EntityPageAzurePipelines = (props: { defaultLimit?: number }) => { const { entity } = useEntity(); const { items, loading, error } = useBuildRuns(entity, props.defaultLimit); - return ; + return ( + + } + > + + + ); }; diff --git a/plugins/azure-devops/src/components/EntityPageAzurePullRequests/EntityPageAzurePullRequests.tsx b/plugins/azure-devops/src/components/EntityPageAzurePullRequests/EntityPageAzurePullRequests.tsx index b5a21ff750..7b828c512c 100644 --- a/plugins/azure-devops/src/components/EntityPageAzurePullRequests/EntityPageAzurePullRequests.tsx +++ b/plugins/azure-devops/src/components/EntityPageAzurePullRequests/EntityPageAzurePullRequests.tsx @@ -14,11 +14,31 @@ * limitations under the License. */ +import { azureDevOpsPullRequestReadPermission } from '@backstage/plugin-azure-devops-common'; import { PullRequestTable } from '../PullRequestTable/PullRequestTable'; import React from 'react'; +import { RequirePermission } from '@backstage/plugin-permission-react'; +import { useEntity } from '@backstage/plugin-catalog-react'; +import { stringifyEntityRef } from '@backstage/catalog-model'; +import { EmptyState } from '@backstage/core-components'; export const EntityPageAzurePullRequests = (props: { defaultLimit?: number; }) => { - return ; + const { entity } = useEntity(); + return ( + + } + > + + + ); }; diff --git a/plugins/azure-devops/src/components/GitTagTable/GitTagTable.tsx b/plugins/azure-devops/src/components/GitTagTable/GitTagTable.tsx index 31475a66d7..f34a1929fe 100644 --- a/plugins/azure-devops/src/components/GitTagTable/GitTagTable.tsx +++ b/plugins/azure-devops/src/components/GitTagTable/GitTagTable.tsx @@ -20,7 +20,6 @@ import { ResponseErrorPanel, Table, TableColumn, - EmptyState, } from '@backstage/core-components'; import { GitTag } from '@backstage/plugin-azure-devops-common'; import React from 'react'; @@ -28,7 +27,6 @@ import React from 'react'; import { AzureGitTagsIcon } from '../AzureGitTagsIcon'; import { useEntity } from '@backstage/plugin-catalog-react'; import { useGitTags } from '../../hooks/useGitTags'; -import { isAuthorizationError } from '../../utils'; const columns: TableColumn[] = [ { @@ -66,15 +64,6 @@ export const GitTagTable = () => { const { items, loading, error } = useGitTags(entity); if (error) { - if (isAuthorizationError(error)) { - return ( - - ); - } return ; } diff --git a/plugins/azure-devops/src/components/PullRequestTable/PullRequestTable.tsx b/plugins/azure-devops/src/components/PullRequestTable/PullRequestTable.tsx index 3e41a8c46f..d672102945 100644 --- a/plugins/azure-devops/src/components/PullRequestTable/PullRequestTable.tsx +++ b/plugins/azure-devops/src/components/PullRequestTable/PullRequestTable.tsx @@ -21,7 +21,6 @@ import { ResponseErrorPanel, Table, TableColumn, - EmptyState, } from '@backstage/core-components'; import { PullRequest, @@ -34,7 +33,6 @@ import { DateTime } from 'luxon'; import { PullRequestStatusButtonGroup } from '../PullRequestStatusButtonGroup'; import { useEntity } from '@backstage/plugin-catalog-react'; import { usePullRequests } from '../../hooks/usePullRequests'; -import { isAuthorizationError } from '../../utils'; const columns: TableColumn[] = [ { @@ -106,15 +104,6 @@ export const PullRequestTable = ({ defaultLimit }: PullRequestTableProps) => { ); if (error) { - if (isAuthorizationError(error)) { - return ( - - ); - } return ; } diff --git a/plugins/azure-devops/src/components/PullRequestsPage/PullRequestsPage.tsx b/plugins/azure-devops/src/components/PullRequestsPage/PullRequestsPage.tsx index 9561c76a2c..c5da207bd6 100644 --- a/plugins/azure-devops/src/components/PullRequestsPage/PullRequestsPage.tsx +++ b/plugins/azure-devops/src/components/PullRequestsPage/PullRequestsPage.tsx @@ -16,7 +16,6 @@ import { Content, - EmptyState, Header, Page, Progress, @@ -29,7 +28,6 @@ import { FilterType } from './lib/filters'; import { PullRequestGrid } from './lib/PullRequestGrid'; import { useDashboardPullRequests } from '../../hooks'; import { useFilterProcessor } from './lib/hooks'; -import { isAuthorizationError } from '../../utils'; type PullRequestsPageContentProps = { pullRequestGroups: PullRequestGroup[] | undefined; @@ -47,15 +45,6 @@ const PullRequestsPageContent = ({ } if (error) { - if (isAuthorizationError(error)) { - return ( - - ); - } return ; } diff --git a/plugins/azure-devops/src/components/ReadmeCard/ReadmeCard.tsx b/plugins/azure-devops/src/components/ReadmeCard/ReadmeCard.tsx index a45c6fe831..6c9c427f9c 100644 --- a/plugins/azure-devops/src/components/ReadmeCard/ReadmeCard.tsx +++ b/plugins/azure-devops/src/components/ReadmeCard/ReadmeCard.tsx @@ -28,7 +28,9 @@ import { useEntity } from '@backstage/plugin-catalog-react'; import React from 'react'; import { useReadme } from '../../hooks'; -import { isAuthorizationError } from '../../utils'; +import { RequirePermission } from '@backstage/plugin-permission-react'; +import { azureDevOpsReadmeReadPermission } from '@backstage/plugin-azure-devops-common'; +import { stringifyEntityRef } from '@backstage/catalog-model'; const useStyles = makeStyles(theme => ({ readMe: { @@ -64,15 +66,7 @@ function isNotFoundError(error: any): boolean { } const ReadmeCardError = ({ error }: ErrorProps) => { - if (isAuthorizationError(error)) { - return ( - - ); - } else if (isNotFoundError(error)) { + if (isNotFoundError(error)) { return ( { } return ( - + } > - - - - + + + + + + ); }; diff --git a/plugins/azure-devops/src/utils/index.ts b/plugins/azure-devops/src/utils/index.ts index a05ea4f650..998bb0e23d 100644 --- a/plugins/azure-devops/src/utils/index.ts +++ b/plugins/azure-devops/src/utils/index.ts @@ -18,4 +18,3 @@ export * from './arrayHas'; export * from './equalsIgnoreCase'; export * from './getDurationFromDates'; export * from './getAnnotationValuesFromEntity'; -export * from './validateError'; diff --git a/plugins/azure-devops/src/utils/validateError.ts b/plugins/azure-devops/src/utils/validateError.ts deleted file mode 100644 index fca1687013..0000000000 --- a/plugins/azure-devops/src/utils/validateError.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export function isAuthorizationError(error: any): boolean { - return error?.response?.status === 403; -} diff --git a/yarn.lock b/yarn.lock index d0b27cb311..e7338a85fa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5164,6 +5164,7 @@ __metadata: "@backstage/frontend-plugin-api": "workspace:^" "@backstage/plugin-azure-devops-common": "workspace:^" "@backstage/plugin-catalog-react": "workspace:^" + "@backstage/plugin-permission-react": "workspace:^" "@backstage/test-utils": "workspace:^" "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1