1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-03-18 00:19:49 +01:00

feat: implement ui for deleting scim users

This commit is contained in:
Simon Hornby 2025-02-03 11:08:20 +02:00
parent 20ef0fae39
commit d9ac57052e
No known key found for this signature in database
GPG Key ID: 57BE3E58BA999B19
4 changed files with 156 additions and 20 deletions

View File

@ -0,0 +1,36 @@
import { Alert, styled, Typography } from '@mui/material';
import { Dialogue } from 'component/common/Dialogue/Dialogue';
const StyledAlert = styled(Alert)(({ theme }) => ({
marginBottom: theme.spacing(3),
}));
export type EntityType = 'Users' | 'Groups';
interface IScimDeleteUsersProps {
open: boolean;
entityType: EntityType;
closeDialog: () => void;
deleteEntities: () => void;
}
export const ScimDeleteEntityDialog = ({
open,
closeDialog,
deleteEntities: removeUser,
entityType,
}: IScimDeleteUsersProps) => (
<Dialogue
open={open}
primaryButtonText={`Delete SCIM ${entityType}`}
secondaryButtonText='Cancel'
title={`Really Delete All SCIM ${entityType}?`}
onClose={closeDialog}
onClick={removeUser}
>
<Typography variant='body1'>
This will delete all {entityType.toLocaleLowerCase()} created or
managed by SCIM.
</Typography>
</Dialogue>
);

View File

@ -9,6 +9,8 @@ import { formatUnknownError } from 'utils/formatUnknownError';
import useToast from 'hooks/useToast';
import { useScimSettingsApi } from 'hooks/api/actions/useScimSettingsApi/useScimSettingsApi';
import { useScimSettings } from 'hooks/api/getters/useScimSettings/useScimSettings';
import { ScimDeleteEntityDialog } from './ScimDeleteUsersDialog';
import useAdminUsersApi from 'hooks/api/actions/useAdminUsersApi/useAdminUsersApi';
const StyledContainer = styled('div')(({ theme }) => ({
padding: theme.spacing(3),
@ -25,8 +27,11 @@ export const ScimSettings = () => {
const { setToastData, setToastApiError } = useToast();
const [newToken, setNewToken] = useState('');
const [tokenGenerationDialog, setTokenGenerationDialog] = useState(false);
const [deleteGroupsDialog, setDeleteGroupsDialog] = useState(false);
const [deleteUsersDialog, setDeleteUsersDialog] = useState(false);
const [tokenDialog, setTokenDialog] = useState(false);
const { settings, refetch } = useScimSettings();
const { deleteScimUsers } = useAdminUsersApi();
const [enabled, setEnabled] = useState(settings.enabled ?? true);
useEffect(() => {
@ -40,6 +45,24 @@ export const ScimSettings = () => {
setTokenGenerationDialog(true);
};
const onDeleteScimGroups = async () => {
setDeleteGroupsDialog(true);
};
const onDeleteScimUsers = async () => {
try {
await deleteScimUsers();
setToastData({
text: 'Scim Users have been deleted',
type: 'success',
});
setDeleteUsersDialog(false);
refetch();
} catch (error: unknown) {
setToastApiError(formatUnknownError(error));
}
};
const onGenerateNewTokenConfirm = async () => {
setTokenGenerationDialog(false);
const token = await generateNewToken();
@ -138,6 +161,55 @@ export const ScimSettings = () => {
/>
</Grid>
</Grid>
<Grid container spacing={3}>
<Grid item md={10.5} mb={2}>
<StyledTitleDiv>
<strong>Delete SCIM Users</strong>
</StyledTitleDiv>
<p>
This will remove all SCIM users from the Unleash
database. This action cannot be undone through
Unleash but the upstream SCIM provider may re sync
these users.
</p>
</Grid>
<Grid item md={1.5}>
<Button
variant='outlined'
color='error'
disabled={loading}
onClick={() => {
setDeleteUsersDialog(true);
}}
>
Delete Users
</Button>
</Grid>
<Grid item md={10.5} mb={2}>
<StyledTitleDiv>
<strong>Clear SCIM Groups</strong>
</StyledTitleDiv>
<p>
This will remove all SCIM groups from the Unleash
database. This action cannot be undone through
Unleash but the upstream SCIM provider may re sync
these groups. Note that this may affect the
permissions of users present in those groups.
</p>
</Grid>
<Grid item md={1.5}>
<Button
variant='outlined'
color='error'
disabled={loading}
onClick={onDeleteScimGroups}
>
Delete Groups
</Button>
</Grid>
</Grid>
<ScimTokenGenerationDialog
open={tokenGenerationDialog}
setOpen={setTokenGenerationDialog}
@ -148,6 +220,20 @@ export const ScimSettings = () => {
setOpen={setTokenDialog}
token={newToken}
/>
<ScimDeleteEntityDialog
open={deleteUsersDialog}
closeDialog={() => setDeleteUsersDialog(false)}
deleteEntities={onDeleteScimUsers}
entityType='Users'
></ScimDeleteEntityDialog>
<ScimDeleteEntityDialog
open={deleteGroupsDialog}
closeDialog={() => setDeleteGroupsDialog(false)}
deleteEntities={onDeleteScimGroups}
entityType='Groups'
></ScimDeleteEntityDialog>
</StyledContainer>
</>
);

View File

@ -94,6 +94,19 @@ const useAdminUsersApi = () => {
return makeRequest(req.caller, req.id);
};
const deleteScimUsers = async () => {
const requestId = 'deleteScimUsers';
const req = createRequest(
'api/admin/user-admin/scim-users',
{
method: 'DELETE',
},
requestId,
);
return makeRequest(req.caller, req.id);
};
return {
addUser,
updateUser,
@ -101,6 +114,7 @@ const useAdminUsersApi = () => {
changePassword,
validatePassword,
resetPassword,
deleteScimUsers,
userApiErrors: errors,
userLoading: loading,
};

View File

@ -411,6 +411,26 @@ export default class UserAdminController extends Controller {
],
});
this.route({
method: 'delete',
path: '/scim-users',
acceptAnyContentType: true,
handler: this.deleteScimUsers,
permission: ADMIN,
middleware: [
openApiService.validPath({
tags: ['Users'],
operationId: 'deleteScimUsers',
summary: 'Delete all SCIM users',
description: 'Deletes all users managed by SCIM',
responses: {
200: emptyResponse,
...getStandardResponses(401, 403),
},
}),
],
});
this.route({
method: 'delete',
path: '/:id',
@ -441,26 +461,6 @@ export default class UserAdminController extends Controller {
}),
],
});
//add a method to delete all scim users
this.route({
method: 'delete',
path: '/scim-users',
handler: this.deleteScimUsers,
permission: ADMIN,
middleware: [
openApiService.validPath({
tags: ['Users'],
operationId: 'deleteScimUsers',
summary: 'Delete all SCIM users',
description: 'Deletes all users managed by SCIM',
responses: {
200: emptyResponse,
...getStandardResponses(401, 403),
},
}),
],
});
}
async resetUserPassword(