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