From f61d4ccc2fe2af4cc8e1bc75cae3c59a6b15ca2f Mon Sep 17 00:00:00 2001 From: Stephen Glass Date: Wed, 2 Oct 2024 23:13:55 -0400 Subject: [PATCH 1/6] add scaffolder permission for template management Signed-off-by: Stephen Glass --- .changeset/lemon-gifts-crash.md | 7 +++ plugins/scaffolder-common/report-alpha.api.md | 6 +++ plugins/scaffolder-common/src/permissions.ts | 17 +++++++ .../ScaffolderPageContextMenu.tsx | 8 ++- .../ActionsPage/ActionsPage.test.tsx | 7 ++- .../ListTasksPage/ListTaskPage.test.tsx | 6 +++ .../src/components/Router/Router.tsx | 50 +++++++++++-------- 7 files changed, 79 insertions(+), 22 deletions(-) create mode 100644 .changeset/lemon-gifts-crash.md diff --git a/.changeset/lemon-gifts-crash.md b/.changeset/lemon-gifts-crash.md new file mode 100644 index 0000000000..162b0b3817 --- /dev/null +++ b/.changeset/lemon-gifts-crash.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-scaffolder-common': patch +'@backstage/plugin-scaffolder-react': patch +'@backstage/plugin-scaffolder': patch +--- + +Add scaffolder permission for accessing the template management features diff --git a/plugins/scaffolder-common/report-alpha.api.md b/plugins/scaffolder-common/report-alpha.api.md index 36b6a7cdb0..47ca033731 100644 --- a/plugins/scaffolder-common/report-alpha.api.md +++ b/plugins/scaffolder-common/report-alpha.api.md @@ -18,6 +18,9 @@ export const RESOURCE_TYPE_SCAFFOLDER_TEMPLATE = 'scaffolder-template'; // @alpha export const scaffolderActionPermissions: ResourcePermission<'scaffolder-action'>[]; +// @alpha +export const scaffolderManagementPermissions: BasicPermission[]; + // @alpha export const scaffolderPermissions: ( | BasicPermission @@ -40,6 +43,9 @@ export const taskCreatePermission: BasicPermission; // @alpha export const taskReadPermission: BasicPermission; +// @alpha +export const templateManagementPermission: BasicPermission; + // @alpha export const templateParameterReadPermission: ResourcePermission<'scaffolder-template'>; diff --git a/plugins/scaffolder-common/src/permissions.ts b/plugins/scaffolder-common/src/permissions.ts index c441b48d5d..a81952a568 100644 --- a/plugins/scaffolder-common/src/permissions.ts +++ b/plugins/scaffolder-common/src/permissions.ts @@ -113,6 +113,16 @@ export const taskCancelPermission = createPermission({ attributes: {}, }); +/** + * This permission is used to authorize template management features. + * + * @alpha + */ +export const templateManagementPermission = createPermission({ + name: 'scaffolder.template.management', + attributes: {}, +}); + /** * List of the scaffolder permissions that are associated with template steps and parameters. * @alpha @@ -138,6 +148,12 @@ export const scaffolderTaskPermissions = [ taskReadPermission, ]; +/** + * List of the scaffolder permissions that are associated with scaffolder management. + * @alpha + */ +export const scaffolderManagementPermissions = [templateManagementPermission]; + /** * List of all the scaffolder permissions * @alpha @@ -146,4 +162,5 @@ export const scaffolderPermissions = [ ...scaffolderTemplatePermissions, ...scaffolderActionPermissions, ...scaffolderTaskPermissions, + ...scaffolderManagementPermissions, ]; diff --git a/plugins/scaffolder-react/src/next/components/ScaffolderPageContextMenu/ScaffolderPageContextMenu.tsx b/plugins/scaffolder-react/src/next/components/ScaffolderPageContextMenu/ScaffolderPageContextMenu.tsx index 12ca4135f0..bbd3ae018e 100644 --- a/plugins/scaffolder-react/src/next/components/ScaffolderPageContextMenu/ScaffolderPageContextMenu.tsx +++ b/plugins/scaffolder-react/src/next/components/ScaffolderPageContextMenu/ScaffolderPageContextMenu.tsx @@ -27,6 +27,8 @@ import Edit from '@material-ui/icons/Edit'; import List from '@material-ui/icons/List'; import MoreVert from '@material-ui/icons/MoreVert'; import React, { useState } from 'react'; +import { usePermission } from '@backstage/plugin-permission-react'; +import { templateManagementPermission } from '@backstage/plugin-scaffolder-common/alpha'; const useStyles = makeStyles(theme => ({ button: { @@ -55,6 +57,10 @@ export function ScaffolderPageContextMenu( const classes = useStyles(); const [anchorEl, setAnchorEl] = useState(); + const { allowed: canManageTemplates } = usePermission({ + permission: templateManagementPermission, + }); + if (!onEditorClicked && !onActionsClicked) { return null; } @@ -100,7 +106,7 @@ export function ScaffolderPageContextMenu( )} - {onEditorClicked && ( + {onEditorClicked && canManageTemplates && ( diff --git a/plugins/scaffolder/src/components/ActionsPage/ActionsPage.test.tsx b/plugins/scaffolder/src/components/ActionsPage/ActionsPage.test.tsx index bf056dd3b3..acfdabac5b 100644 --- a/plugins/scaffolder/src/components/ActionsPage/ActionsPage.test.tsx +++ b/plugins/scaffolder/src/components/ActionsPage/ActionsPage.test.tsx @@ -23,6 +23,7 @@ import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils'; import { ApiProvider } from '@backstage/core-app-api'; import { rootRouteRef } from '../../routes'; import { userEvent } from '@testing-library/user-event'; +import { permissionApiRef } from '@backstage/plugin-permission-react'; const scaffolderApiMock: jest.Mocked = { scaffold: jest.fn(), @@ -36,7 +37,11 @@ const scaffolderApiMock: jest.Mocked = { autocomplete: jest.fn(), }; -const apis = TestApiRegistry.from([scaffolderApiRef, scaffolderApiMock]); +const mockPermissionApi = { authorize: jest.fn() }; +const apis = TestApiRegistry.from( + [scaffolderApiRef, scaffolderApiMock], + [permissionApiRef, mockPermissionApi], +); describe('TemplatePage', () => { beforeEach(() => jest.resetAllMocks()); diff --git a/plugins/scaffolder/src/components/ListTasksPage/ListTaskPage.test.tsx b/plugins/scaffolder/src/components/ListTasksPage/ListTaskPage.test.tsx index f7f75bc3e8..ad3ca7fbde 100644 --- a/plugins/scaffolder/src/components/ListTasksPage/ListTaskPage.test.tsx +++ b/plugins/scaffolder/src/components/ListTasksPage/ListTaskPage.test.tsx @@ -30,6 +30,7 @@ import { } from '@backstage/plugin-scaffolder-react'; import { act, fireEvent } from '@testing-library/react'; import { rootRouteRef } from '../../routes'; +import { permissionApiRef } from '@backstage/plugin-permission-react'; describe('', () => { const catalogApi: jest.Mocked = { @@ -49,6 +50,8 @@ describe('', () => { listTasks: jest.fn(), } as any; + const mockPermissionApi = { authorize: jest.fn() }; + it('should render the page', async () => { const entity: Entity = { apiVersion: 'v1', @@ -72,6 +75,7 @@ describe('', () => { [catalogApiRef, catalogApi], [identityApiRef, identityApi], [scaffolderApiRef, scaffolderApiMock], + [permissionApiRef, mockPermissionApi], ]} > @@ -132,6 +136,7 @@ describe('', () => { [catalogApiRef, catalogApi], [identityApiRef, identityApi], [scaffolderApiRef, scaffolderApiMock], + [permissionApiRef, mockPermissionApi], ]} > @@ -230,6 +235,7 @@ describe('', () => { [catalogApiRef, catalogApi], [identityApiRef, identityApi], [scaffolderApiRef, scaffolderApiMock], + [permissionApiRef, mockPermissionApi], ]} > diff --git a/plugins/scaffolder/src/components/Router/Router.tsx b/plugins/scaffolder/src/components/Router/Router.tsx index 5766e3d043..4f578d9ff2 100644 --- a/plugins/scaffolder/src/components/Router/Router.tsx +++ b/plugins/scaffolder/src/components/Router/Router.tsx @@ -59,6 +59,8 @@ import { TemplateEditorPage, CustomFieldsPage, } from '../../alpha/components/TemplateEditorPage'; +import { RequirePermission } from '@backstage/plugin-permission-react'; +import { templateManagementPermission } from '@backstage/plugin-scaffolder-common/alpha'; /** * The Props for the Scaffolder Router @@ -170,29 +172,35 @@ export const Router = (props: PropsWithChildren) => { - - + + + + + } /> - - + + + + + } /> - - + + + + + } /> @@ -204,13 +212,15 @@ export const Router = (props: PropsWithChildren) => { - - + + + + + } /> Date: Mon, 14 Oct 2024 14:30:35 -0400 Subject: [PATCH 2/6] add template management permission check to dry run endpoint Signed-off-by: Stephen Glass --- .changeset/lemon-gifts-crash.md | 3 ++- plugins/scaffolder-backend/src/service/router.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.changeset/lemon-gifts-crash.md b/.changeset/lemon-gifts-crash.md index 162b0b3817..6c791ee86f 100644 --- a/.changeset/lemon-gifts-crash.md +++ b/.changeset/lemon-gifts-crash.md @@ -1,7 +1,8 @@ --- '@backstage/plugin-scaffolder-common': patch '@backstage/plugin-scaffolder-react': patch +'@backstage/plugin-scaffolder-backend' '@backstage/plugin-scaffolder': patch --- -Add scaffolder permission for accessing the template management features +Add scaffolder permission `scaffolder.template.management` for accessing the template management features diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index 80406496d2..c404549a3f 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -46,6 +46,7 @@ import { taskCancelPermission, taskCreatePermission, taskReadPermission, + templateManagementPermission, templateParameterReadPermission, templateStepReadPermission, } from '@backstage/plugin-scaffolder-common/alpha'; @@ -761,7 +762,7 @@ export async function createRouter( const credentials = await httpAuth.credentials(req); await checkPermission({ credentials, - permissions: [taskCreatePermission], + permissions: [taskCreatePermission, templateManagementPermission], permissionService: permissions, }); From a3b10fa12e99b9b3e808f7f66ce779f400571107 Mon Sep 17 00:00:00 2001 From: Stephen Glass Date: Mon, 14 Oct 2024 14:35:42 -0400 Subject: [PATCH 3/6] fix changeset Signed-off-by: Stephen Glass --- .changeset/lemon-gifts-crash.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/lemon-gifts-crash.md b/.changeset/lemon-gifts-crash.md index 6c791ee86f..cd473f6c58 100644 --- a/.changeset/lemon-gifts-crash.md +++ b/.changeset/lemon-gifts-crash.md @@ -1,7 +1,7 @@ --- '@backstage/plugin-scaffolder-common': patch '@backstage/plugin-scaffolder-react': patch -'@backstage/plugin-scaffolder-backend' +'@backstage/plugin-scaffolder-backend': patch '@backstage/plugin-scaffolder': patch --- From db507dd9e6a86b5ff0b6f5da3e7ee4c393c35168 Mon Sep 17 00:00:00 2001 From: Stephen Glass Date: Mon, 28 Oct 2024 16:23:13 -0400 Subject: [PATCH 4/6] address comments Signed-off-by: Stephen Glass --- .changeset/lemon-gifts-crash.md | 3 +-- plugins/scaffolder-backend/src/service/router.ts | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.changeset/lemon-gifts-crash.md b/.changeset/lemon-gifts-crash.md index cd473f6c58..c4ab159dc8 100644 --- a/.changeset/lemon-gifts-crash.md +++ b/.changeset/lemon-gifts-crash.md @@ -1,8 +1,7 @@ --- '@backstage/plugin-scaffolder-common': patch '@backstage/plugin-scaffolder-react': patch -'@backstage/plugin-scaffolder-backend': patch -'@backstage/plugin-scaffolder': patch +'@backstage/plugin-scaffolder': minor --- Add scaffolder permission `scaffolder.template.management` for accessing the template management features diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index 59f52af0c4..35dacf6559 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -46,7 +46,6 @@ import { taskCancelPermission, taskCreatePermission, taskReadPermission, - templateManagementPermission, templateParameterReadPermission, templateStepReadPermission, } from '@backstage/plugin-scaffolder-common/alpha'; @@ -767,7 +766,7 @@ export async function createRouter( const credentials = await httpAuth.credentials(req); await checkPermission({ credentials, - permissions: [taskCreatePermission, templateManagementPermission], + permissions: [taskCreatePermission], permissionService: permissions, }); From 28e222bbd8b8c174c98f4e36bc2b719662023cec Mon Sep 17 00:00:00 2001 From: Stephen Glass Date: Wed, 6 Nov 2024 15:45:39 -0500 Subject: [PATCH 5/6] Apply suggestions from code review Co-authored-by: Vincenzo Scamporlino Signed-off-by: Stephen Glass --- plugins/scaffolder-common/src/permissions.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/plugins/scaffolder-common/src/permissions.ts b/plugins/scaffolder-common/src/permissions.ts index a81952a568..e758291e75 100644 --- a/plugins/scaffolder-common/src/permissions.ts +++ b/plugins/scaffolder-common/src/permissions.ts @@ -148,12 +148,6 @@ export const scaffolderTaskPermissions = [ taskReadPermission, ]; -/** - * List of the scaffolder permissions that are associated with scaffolder management. - * @alpha - */ -export const scaffolderManagementPermissions = [templateManagementPermission]; - /** * List of all the scaffolder permissions * @alpha @@ -162,5 +156,5 @@ export const scaffolderPermissions = [ ...scaffolderTemplatePermissions, ...scaffolderActionPermissions, ...scaffolderTaskPermissions, - ...scaffolderManagementPermissions, + templateManagementPermission, ]; From 71bb422d4fc6aeda3062be50ec6c315151c851ab Mon Sep 17 00:00:00 2001 From: Stephen Glass Date: Wed, 6 Nov 2024 15:57:10 -0500 Subject: [PATCH 6/6] Update report-alpha.api.md Signed-off-by: Stephen Glass --- plugins/scaffolder-common/report-alpha.api.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/scaffolder-common/report-alpha.api.md b/plugins/scaffolder-common/report-alpha.api.md index 47ca033731..97a3de63c5 100644 --- a/plugins/scaffolder-common/report-alpha.api.md +++ b/plugins/scaffolder-common/report-alpha.api.md @@ -18,9 +18,6 @@ export const RESOURCE_TYPE_SCAFFOLDER_TEMPLATE = 'scaffolder-template'; // @alpha export const scaffolderActionPermissions: ResourcePermission<'scaffolder-action'>[]; -// @alpha -export const scaffolderManagementPermissions: BasicPermission[]; - // @alpha export const scaffolderPermissions: ( | BasicPermission