feat: initial implementation of scaffolder granular permissions

Signed-off-by: Kashish Mittal <kmittal@redhat.com>
Co-authored-by: Frank Kong <frkong@redhat.com>
This commit is contained in:
Kashish Mittal
2025-03-12 18:35:41 -04:00
parent 9ad11f6555
commit 152ae1e3c5
11 changed files with 384 additions and 59 deletions
@@ -91,14 +91,22 @@ const ListTaskPageContent = (props: MyTaskPageProps) => {
if (error) {
return (
<>
<ErrorPanel error={error} />
<EmptyState
missing="info"
title={t('listTaskPage.content.emptyState.title')}
description={t('listTaskPage.content.emptyState.description')}
/>
</>
<CatalogFilterLayout>
<CatalogFilterLayout.Filters>
<OwnerListPicker
filter={ownerFilter}
onSelectOwner={id => setOwnerFilter(id)}
/>
</CatalogFilterLayout.Filters>
<CatalogFilterLayout.Content>
<ErrorPanel error={error} />
<EmptyState
missing="info"
title={t('listTaskPage.content.emptyState.title')}
description={t('listTaskPage.content.emptyState.description')}
/>
</CatalogFilterLayout.Content>
</CatalogFilterLayout>
);
}
@@ -46,6 +46,7 @@ type ContextMenuProps = {
onStartOver?: () => void;
onToggleLogs?: (state: boolean) => void;
onToggleButtonBar?: (state: boolean) => void;
taskId?: string;
isCancelButtonDisabled: boolean;
onCancel: () => void;
};
@@ -67,6 +68,7 @@ export const ContextMenu = (props: ContextMenuProps) => {
onStartOver,
onToggleLogs,
onToggleButtonBar,
taskId
} = props;
const { getPageTheme } = useTheme();
const pageTheme = getPageTheme({ themeId: 'website' });
@@ -76,6 +78,7 @@ export const ContextMenu = (props: ContextMenuProps) => {
const { allowed: canReadTask } = usePermission({
permission: taskReadPermission,
resourceRef: taskId
});
const { allowed: canCreateTask } = usePermission({
@@ -46,7 +46,7 @@ import {
TaskSteps,
} from '@backstage/plugin-scaffolder-react/alpha';
import { useAsync } from '@react-hookz/web';
import { usePermission } from '@backstage/plugin-permission-react';
import { usePermission} from '@backstage/plugin-permission-react';
import {
taskCancelPermission,
taskCreatePermission,
@@ -142,10 +142,12 @@ function OngoingTaskContent(props: {
// Used dummy string value for `resourceRef` since `allowed` field will always return `false` if `resourceRef` is `undefined`
const { allowed: canCancelTask } = usePermission({
permission: taskCancelPermission,
resourceRef: taskId,
});
const { allowed: canReadTask } = usePermission({
permission: taskReadPermission,
resourceRef: taskId,
});
const { allowed: canCreateTask } = usePermission({
@@ -269,6 +271,7 @@ function OngoingTaskContent(props: {
onRetry={triggerRetry}
onToggleLogs={setLogVisibleState}
onToggleButtonBar={setButtonBarVisibleState}
taskId={taskId}
onCancel={triggerCancel}
isCancelButtonDisabled={isCancelButtonDisabled}
/>
@@ -60,10 +60,7 @@ import {
CustomFieldsPage,
} from '../../alpha/components/TemplateEditorPage';
import { RequirePermission } from '@backstage/plugin-permission-react';
import {
taskReadPermission,
templateManagementPermission,
} from '@backstage/plugin-scaffolder-common/alpha';
import { templateManagementPermission } from '@backstage/plugin-scaffolder-common/alpha';
import { useApp } from '@backstage/core-plugin-api';
import { FormField, OpaqueFormField } from '@internal/scaffolder';
import { useAsync, useMountEffect } from '@react-hookz/web';
@@ -182,11 +179,9 @@ export const InternalRouter = (
<Route
path={scaffolderTaskRouteRef.path}
element={
<RequirePermission permission={taskReadPermission}>
<TaskPageComponent
TemplateOutputsComponent={TemplateOutputsComponent}
/>
</RequirePermission>
<TaskPageComponent
TemplateOutputsComponent={TemplateOutputsComponent}
/>
}
/>
<Route
@@ -230,11 +225,7 @@ export const InternalRouter = (
/>
<Route
path={scaffolderListTaskRouteRef.path}
element={
<RequirePermission permission={taskReadPermission}>
<ListTasksPage contextMenu={props.contextMenu} />
</RequirePermission>
}
element={<ListTasksPage contextMenu={props.contextMenu} />}
/>
<Route
path={editorRouteRef.path}