add scaffolder permission for template management
Signed-off-by: Stephen Glass <stephen@stephen.glass>
This commit is contained in:
@@ -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
|
||||
@@ -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'>;
|
||||
|
||||
|
||||
@@ -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,
|
||||
];
|
||||
|
||||
+7
-1
@@ -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<HTMLButtonElement>();
|
||||
|
||||
const { allowed: canManageTemplates } = usePermission({
|
||||
permission: templateManagementPermission,
|
||||
});
|
||||
|
||||
if (!onEditorClicked && !onActionsClicked) {
|
||||
return null;
|
||||
}
|
||||
@@ -100,7 +106,7 @@ export function ScaffolderPageContextMenu(
|
||||
<ListItemText primary="Create" />
|
||||
</MenuItem>
|
||||
)}
|
||||
{onEditorClicked && (
|
||||
{onEditorClicked && canManageTemplates && (
|
||||
<MenuItem onClick={onEditorClicked}>
|
||||
<ListItemIcon>
|
||||
<Edit fontSize="small" />
|
||||
|
||||
@@ -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<ScaffolderApi> = {
|
||||
scaffold: jest.fn(),
|
||||
@@ -36,7 +37,11 @@ const scaffolderApiMock: jest.Mocked<ScaffolderApi> = {
|
||||
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());
|
||||
|
||||
@@ -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('<ListTasksPage />', () => {
|
||||
const catalogApi: jest.Mocked<CatalogApi> = {
|
||||
@@ -49,6 +50,8 @@ describe('<ListTasksPage />', () => {
|
||||
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('<ListTasksPage />', () => {
|
||||
[catalogApiRef, catalogApi],
|
||||
[identityApiRef, identityApi],
|
||||
[scaffolderApiRef, scaffolderApiMock],
|
||||
[permissionApiRef, mockPermissionApi],
|
||||
]}
|
||||
>
|
||||
<ListTasksPage />
|
||||
@@ -132,6 +136,7 @@ describe('<ListTasksPage />', () => {
|
||||
[catalogApiRef, catalogApi],
|
||||
[identityApiRef, identityApi],
|
||||
[scaffolderApiRef, scaffolderApiMock],
|
||||
[permissionApiRef, mockPermissionApi],
|
||||
]}
|
||||
>
|
||||
<ListTasksPage />
|
||||
@@ -230,6 +235,7 @@ describe('<ListTasksPage />', () => {
|
||||
[catalogApiRef, catalogApi],
|
||||
[identityApiRef, identityApi],
|
||||
[scaffolderApiRef, scaffolderApiMock],
|
||||
[permissionApiRef, mockPermissionApi],
|
||||
]}
|
||||
>
|
||||
<ListTasksPage />
|
||||
|
||||
@@ -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<RouterProps>) => {
|
||||
<Route
|
||||
path={editRouteRef.path}
|
||||
element={
|
||||
<SecretsContextProvider>
|
||||
<TemplateIntroPage />
|
||||
</SecretsContextProvider>
|
||||
<RequirePermission permission={templateManagementPermission}>
|
||||
<SecretsContextProvider>
|
||||
<TemplateIntroPage />
|
||||
</SecretsContextProvider>
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path={customFieldsRouteRef.path}
|
||||
element={
|
||||
<SecretsContextProvider>
|
||||
<CustomFieldsPage fieldExtensions={fieldExtensions} />
|
||||
</SecretsContextProvider>
|
||||
<RequirePermission permission={templateManagementPermission}>
|
||||
<SecretsContextProvider>
|
||||
<CustomFieldsPage fieldExtensions={fieldExtensions} />
|
||||
</SecretsContextProvider>
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path={templateFormRouteRef.path}
|
||||
element={
|
||||
<SecretsContextProvider>
|
||||
<TemplateFormPage
|
||||
layouts={customLayouts}
|
||||
formProps={props.formProps}
|
||||
fieldExtensions={fieldExtensions}
|
||||
/>
|
||||
</SecretsContextProvider>
|
||||
<RequirePermission permission={templateManagementPermission}>
|
||||
<SecretsContextProvider>
|
||||
<TemplateFormPage
|
||||
layouts={customLayouts}
|
||||
formProps={props.formProps}
|
||||
fieldExtensions={fieldExtensions}
|
||||
/>
|
||||
</SecretsContextProvider>
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -204,13 +212,15 @@ export const Router = (props: PropsWithChildren<RouterProps>) => {
|
||||
<Route
|
||||
path={editorRouteRef.path}
|
||||
element={
|
||||
<SecretsContextProvider>
|
||||
<TemplateEditorPage
|
||||
layouts={customLayouts}
|
||||
formProps={props.formProps}
|
||||
fieldExtensions={fieldExtensions}
|
||||
/>
|
||||
</SecretsContextProvider>
|
||||
<RequirePermission permission={templateManagementPermission}>
|
||||
<SecretsContextProvider>
|
||||
<TemplateEditorPage
|
||||
layouts={customLayouts}
|
||||
formProps={props.formProps}
|
||||
fieldExtensions={fieldExtensions}
|
||||
/>
|
||||
</SecretsContextProvider>
|
||||
</RequirePermission>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
|
||||
Reference in New Issue
Block a user