Skip to content

Commit

Permalink
feat(rbac): show warning alert when user is not authorised to create …
Browse files Browse the repository at this point in the history
…roles (janus-idp#1064)
  • Loading branch information
divyanshiGupta authored Jan 15, 2024
1 parent ecec1db commit b5c46c8
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 14 deletions.
1 change: 1 addition & 0 deletions plugins/rbac/src/components/RbacPage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ describe('RbacPage', () => {
data: [],
retry: jest.fn(),
createRoleAllowed: false,
createRoleLoading: false,
});
await renderInTestApp(<RbacPage />);
expect(screen.getByText('Administration')).toBeInTheDocument();
Expand Down
22 changes: 22 additions & 0 deletions plugins/rbac/src/components/RolesList/RolesList.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ describe('RolesList', () => {
data: useRolesMockData,
retry: jest.fn(),
createRoleAllowed: false,
createRoleLoading: false,
});
const { queryByText } = await renderInTestApp(<RolesList />);
expect(queryByText('All roles (2)')).not.toBeNull();
Expand All @@ -81,6 +82,7 @@ describe('RolesList', () => {
data: [],
retry: jest.fn(),
createRoleAllowed: false,
createRoleLoading: false,
});
const { getByTestId } = await renderInTestApp(<RolesList />);
expect(getByTestId('roles-table-empty')).not.toBeNull();
Expand All @@ -96,6 +98,7 @@ describe('RolesList', () => {
data: useRolesMockData,
retry: jest.fn(),
createRoleAllowed: false,
createRoleLoading: false,
});
const { getAllByTestId, getByText } = await renderInTestApp(<RolesList />);
expect(getAllByTestId('delete-role')).not.toBeNull();
Expand Down Expand Up @@ -127,6 +130,7 @@ describe('RolesList', () => {
],
retry: jest.fn(),
createRoleAllowed: false,
createRoleLoading: false,
});
const { getAllByTestId } = await renderInTestApp(<RolesList />);
expect(getAllByTestId('disable-delete-role')).not.toBeNull();
Expand Down Expand Up @@ -158,6 +162,7 @@ describe('RolesList', () => {
],
retry: jest.fn(),
createRoleAllowed: true,
createRoleLoading: false,
});
const { getAllByTestId } = await renderInTestApp(<RolesList />);
expect(getAllByTestId('disable-update-role')).not.toBeNull();
Expand All @@ -172,6 +177,7 @@ describe('RolesList', () => {
data: useRolesMockData,
retry: jest.fn(),
createRoleAllowed: false,
createRoleLoading: false,
});
const { getByTestId } = await renderInTestApp(<RolesList />);

Expand All @@ -188,11 +194,27 @@ describe('RolesList', () => {
data: useRolesMockData,
retry: jest.fn(),
createRoleAllowed: true,
createRoleLoading: false,
});
const { getByTestId } = await renderInTestApp(<RolesList />);

expect(getByTestId('create-role').getAttribute('aria-disabled')).toEqual(
'false',
);
});

it('should show warning alert if user is not authorized to create roles', async () => {
RequirePermissionMock.mockImplementation(props => <>{props.children}</>);
mockUsePermission.mockReturnValue({ loading: false, allowed: true });
mockUseRoles.mockReturnValue({
loading: false,
data: useRolesMockData,
retry: jest.fn(),
createRoleAllowed: false,
createRoleLoading: false,
});
const { getByTestId } = await renderInTestApp(<RolesList />);

expect(getByTestId('create-role-warning')).not.toBeNull();
});
});
8 changes: 6 additions & 2 deletions plugins/rbac/src/components/RolesList/RolesList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ export const RolesList = () => {

const [roles, setRoles] = React.useState<number | undefined>();
const classes = useStyles();
const { loading, data, retry, createRoleAllowed } = useRoles();
const { loading, data, retry, createRoleAllowed, createRoleLoading } =
useRoles();

const closeDialog = () => {
setOpenDialog(false);
Expand All @@ -44,7 +45,10 @@ export const RolesList = () => {
return (
<>
<SnackbarAlert toastMessage={toastMessage} onAlertClose={onAlertClose} />
<RolesListToolbar createRoleAllowed={createRoleAllowed} />
<RolesListToolbar
createRoleAllowed={createRoleAllowed}
createRoleLoading={createRoleLoading}
/>
<Table
title={
!loading && data?.length
Expand Down
49 changes: 37 additions & 12 deletions plugins/rbac/src/components/RolesList/RolesListToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,57 @@ import React from 'react';
import { LinkButton } from '@backstage/core-components';

import { makeStyles } from '@material-ui/core';
import Alert from '@mui/material/Alert';
import AlertTitle from '@mui/material/AlertTitle';

const useStyles = makeStyles(_theme => ({
const useStyles = makeStyles(theme => ({
toolbar: {
display: 'flex',
justifyContent: 'end',
marginBottom: '24px',
},
rbacPreReqLink: {
color: theme.palette.link,
},
}));

export const RolesListToolbar = ({
createRoleAllowed,
createRoleLoading,
}: {
createRoleAllowed: boolean;
createRoleLoading: boolean;
}) => {
const classes = useStyles();
return (
<span className={classes.toolbar}>
<LinkButton
to="role/new"
color="primary"
variant="contained"
disabled={!createRoleAllowed}
data-testid="create-role"
>
Create
</LinkButton>
</span>
<div>
{!createRoleLoading && !createRoleAllowed && (
<Alert severity="warning" data-testid="create-role-warning">
<AlertTitle>Unable to create role.</AlertTitle>
To enable create role button, the role associacted with your user
should have the permission policies mentioned{' '}
<a
href="https://github.com/janus-idp/backstage-plugins/tree/main/plugins/rbac#prerequisites"
target="blank"
className={classes.rbacPreReqLink}
>
here
</a>{' '}
associated with it.
</Alert>
)}
<br />
<span className={classes.toolbar}>
<LinkButton
to="role/new"
color="primary"
variant="contained"
disabled={!createRoleAllowed}
data-testid="create-role"
>
Create
</LinkButton>
</span>
</div>
);
};
6 changes: 6 additions & 0 deletions plugins/rbac/src/hooks/useRoles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const useRoles = (
): {
loading: boolean;
data: RolesData[];
createRoleLoading: boolean;
createRoleAllowed: boolean;
retry: () => void;
} => {
Expand Down Expand Up @@ -52,6 +53,10 @@ export const useRoles = (
resourceRef: catalogEntityReadPermission.resourceType,
});

const createRoleLoading =
policyEntityCreatePermissionResult.loading ||
catalogEntityReadPermissionResult.loading;

const createRoleAllowed =
policyEntityCreatePermissionResult.allowed &&
catalogEntityReadPermissionResult.allowed;
Expand Down Expand Up @@ -113,6 +118,7 @@ export const useRoles = (
return {
loading,
data,
createRoleLoading,
createRoleAllowed,
retry: roleRetry,
};
Expand Down

0 comments on commit b5c46c8

Please sign in to comment.