Fix UI(#8467) : Only allow admins to create and update bot and user entities (#8491)

* FIx UI : Only allow admins to create and update bot and user entities. #8467

* Add helper text for ADMIN_ONLY_ACTION
This commit is contained in:
Sachin Chaurasiya 2022-11-02 22:43:46 +05:30 committed by GitHub
parent 370288f1ff
commit f3b9e2c59c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 66 deletions

View File

@ -16,6 +16,7 @@ import { ColumnsType } from 'antd/lib/table';
import { AxiosError } from 'axios';
import { isEmpty, lowerCase } from 'lodash';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
import { getBots } from '../../axiosAPIs/botsAPI';
import {
@ -25,16 +26,15 @@ import {
} from '../../constants/constants';
import { BOTS_DOCS } from '../../constants/docs.constants';
import {
ADMIN_ONLY_ACTION,
INGESTION_BOT_CANT_BE_DELETED,
NO_PERMISSION_FOR_ACTION,
} from '../../constants/HelperTextUtil';
import { EntityType } from '../../enums/entity.enum';
import { Bot, ProviderType } from '../../generated/entity/bot';
import { Operation } from '../../generated/entity/policies/accessControl/rule';
import { Include } from '../../generated/type/include';
import { Paging } from '../../generated/type/paging';
import { useAuth } from '../../hooks/authHooks';
import { getEntityName } from '../../utils/CommonUtils';
import { checkPermission } from '../../utils/PermissionsUtils';
import SVGIcons, { Icons } from '../../utils/SvgUtils';
import { showErrorToast } from '../../utils/ToastUtils';
import DeleteWidgetModal from '../common/DeleteWidget/DeleteWidgetModal';
@ -43,8 +43,6 @@ import NextPrevious from '../common/next-previous/NextPrevious';
import RichTextEditorPreviewer from '../common/rich-text-editor/RichTextEditorPreviewer';
import Searchbar from '../common/searchbar/Searchbar';
import Loader from '../Loader/Loader';
import { usePermissionProvider } from '../PermissionProvider/PermissionProvider';
import { ResourceEntity } from '../PermissionProvider/PermissionProvider.interface';
import { BotListV1Props } from './BotListV1.interfaces';
const BotListV1 = ({
@ -52,7 +50,8 @@ const BotListV1 = ({
handleAddBotClick,
handleShowDeleted,
}: BotListV1Props) => {
const { permissions } = usePermissionProvider();
const { isAdminUser } = useAuth();
const { t } = useTranslation();
const [botUsers, setBotUsers] = useState<Bot[]>([]);
const [paging, setPaging] = useState<Paging>({} as Paging);
const [selectedUser, setSelectedUser] = useState<Bot>();
@ -62,22 +61,6 @@ const BotListV1 = ({
const [handleErrorPlaceholder, setHandleErrorPlaceholder] = useState(false);
const [searchedData, setSearchedData] = useState<Bot[]>([]);
/**
* Bot creation is two step process so here we should check for
* Create User and Create Bot both permissions
*/
const createPermission = useMemo(
() =>
checkPermission(Operation.Create, ResourceEntity.BOT, permissions) &&
checkPermission(Operation.Create, ResourceEntity.USER, permissions),
[permissions]
);
const deletePermission = useMemo(
() => checkPermission(Operation.Delete, ResourceEntity.BOT, permissions),
[permissions]
);
/**
*
* @param after - Pagination value if passed data will be fetched post cursor value
@ -111,7 +94,7 @@ const BotListV1 = ({
const columns: ColumnsType<Bot> = useMemo(
() => [
{
title: 'Name',
title: t('label.name'),
dataIndex: 'displayName',
key: 'displayName',
render: (_, record) => (
@ -124,18 +107,20 @@ const BotListV1 = ({
),
},
{
title: 'Description',
title: t('label.description'),
dataIndex: 'description',
key: 'description',
render: (_, record) =>
record?.description ? (
<RichTextEditorPreviewer markdown={record?.description || ''} />
) : (
<span data-testid="no-description">No Description</span>
<span data-testid="no-description">
{t('label.no-description')}
</span>
),
},
{
title: 'Actions',
title: t('label.actions'),
dataIndex: 'id',
key: 'id',
width: 90,
@ -143,10 +128,10 @@ const BotListV1 = ({
const isSystemBot = record.provider === ProviderType.System;
const title = isSystemBot
? INGESTION_BOT_CANT_BE_DELETED
: deletePermission
? 'Delete'
: NO_PERMISSION_FOR_ACTION;
const isDisabled = !deletePermission || isSystemBot;
: isAdminUser
? t('label.delete')
: ADMIN_ONLY_ACTION;
const isDisabled = !isAdminUser || isSystemBot;
return (
<Space align="center" size={8}>
@ -220,7 +205,7 @@ const BotListV1 = ({
size="small"
onClick={handleShowDeleted}
/>
<label htmlFor="switch-deleted">Show deleted</label>
<label htmlFor="switch-deleted">{t('label.show-deleted')}</label>
</Space>
</Col>
<Col className="w-full">
@ -229,14 +214,14 @@ const BotListV1 = ({
<div className="tw-text-lg tw-text-center">
<Tooltip
placement="left"
title={createPermission ? 'Add Bot' : NO_PERMISSION_FOR_ACTION}>
title={isAdminUser ? t('label.add-bot') : ADMIN_ONLY_ACTION}>
<Button
ghost
data-testid="add-bot"
disabled={!createPermission}
disabled={!isAdminUser}
type="primary"
onClick={handleAddBotClick}>
Add Bot
{t('label.add-bot')}
</Button>
</Tooltip>
</div>
@ -252,7 +237,7 @@ const BotListV1 = ({
<Col span={8}>
<Searchbar
removeMargin
placeholder="Search for bots..."
placeholder={t('label.search-for-bots')}
typingInterval={500}
onSearch={handleSearch}
/>
@ -265,17 +250,16 @@ const BotListV1 = ({
id="switch-deleted"
onClick={handleShowDeleted}
/>
<label htmlFor="switch-deleted">Show deleted</label>
<label htmlFor="switch-deleted">{t('label.show-deleted')}</label>
</Space>
<Tooltip
title={createPermission ? 'Add Bot' : NO_PERMISSION_FOR_ACTION}>
<Tooltip title={isAdminUser ? t('label.add-bot') : ADMIN_ONLY_ACTION}>
<Button
data-testid="add-bot"
disabled={!createPermission}
disabled={!isAdminUser}
type="primary"
onClick={handleAddBotClick}>
Add Bot
{t('label.add-bot')}
</Button>
</Tooltip>
</Space>

View File

@ -20,17 +20,16 @@ import { useTranslation } from 'react-i18next';
import { useHistory } from 'react-router-dom';
import { updateUser } from '../../axiosAPIs/userAPI';
import { PAGE_SIZE_MEDIUM, ROUTES } from '../../constants/constants';
import { NO_PERMISSION_FOR_ACTION } from '../../constants/HelperTextUtil';
import { ADMIN_ONLY_ACTION } from '../../constants/HelperTextUtil';
import { CreateUser } from '../../generated/api/teams/createUser';
import { Operation } from '../../generated/entity/policies/policy';
import { User } from '../../generated/entity/teams/user';
import { Paging } from '../../generated/type/paging';
import { useAuth } from '../../hooks/authHooks';
import jsonData from '../../jsons/en';
import {
commonUserDetailColumns,
getEntityName,
} from '../../utils/CommonUtils';
import { checkPermission } from '../../utils/PermissionsUtils';
import SVGIcons, { Icons } from '../../utils/SvgUtils';
import { showErrorToast, showSuccessToast } from '../../utils/ToastUtils';
import DeleteWidgetModal from '../common/DeleteWidget/DeleteWidgetModal';
@ -38,8 +37,6 @@ import ErrorPlaceHolder from '../common/error-with-placeholder/ErrorPlaceHolder'
import NextPrevious from '../common/next-previous/NextPrevious';
import Searchbar from '../common/searchbar/Searchbar';
import Loader from '../Loader/Loader';
import { usePermissionProvider } from '../PermissionProvider/PermissionProvider';
import { ResourceEntity } from '../PermissionProvider/PermissionProvider.interface';
import './usersList.less';
interface UserListV1Props {
@ -67,8 +64,8 @@ const UserListV1: FC<UserListV1Props> = ({
onPagingChange,
afterDeleteAction,
}) => {
const { isAdminUser } = useAuth();
const { t } = useTranslation();
const { permissions } = usePermissionProvider();
const history = useHistory();
const [selectedUser, setSelectedUser] = useState<User>();
const [showDeleteModal, setShowDeleteModal] = useState(false);
@ -76,16 +73,6 @@ const UserListV1: FC<UserListV1Props> = ({
const showRestore = showDeletedUser && !isDataLoading;
const [isLoading, setIsLoading] = useState(false);
const createPermission = useMemo(
() => checkPermission(Operation.Create, ResourceEntity.USER, permissions),
[permissions]
);
const deletePermission = useMemo(
() => checkPermission(Operation.Delete, ResourceEntity.USER, permissions),
[permissions]
);
const handleAddNewUser = () => {
history.push(ROUTES.CREATE_USER);
};
@ -164,11 +151,9 @@ const UserListV1: FC<UserListV1Props> = ({
)}
<Tooltip
placement="bottom"
title={
deletePermission ? t('label.delete') : NO_PERMISSION_FOR_ACTION
}>
title={isAdminUser ? t('label.delete') : ADMIN_ONLY_ACTION}>
<Button
disabled={!deletePermission}
disabled={!isAdminUser}
icon={
<SVGIcons
alt="Delete"
@ -212,7 +197,7 @@ const UserListV1: FC<UserListV1Props> = ({
<Button
ghost
data-testid="add-user"
disabled={!createPermission}
disabled={!isAdminUser}
type="primary"
onClick={handleAddNewUser}>
{t('label.add-user')}
@ -253,12 +238,10 @@ const UserListV1: FC<UserListV1Props> = ({
<span className="tw-ml-2">{t('label.deleted-users')}</span>
</span>
<Tooltip
title={
createPermission ? t('label.add-user') : NO_PERMISSION_FOR_ACTION
}>
title={isAdminUser ? t('label.add-user') : ADMIN_ONLY_ACTION}>
<Button
data-testid="add-user"
disabled={!createPermission}
disabled={!isAdminUser}
type="primary"
onClick={handleAddNewUser}>
{t('label.add-user')}

View File

@ -57,3 +57,5 @@ export const INGESTION_BOT_CANT_BE_DELETED =
export const BOT_ACCOUNT_EMAIL_CHANGE_CONFIRMATION =
'Changing account email will update or create a new bot user';
export const ADMIN_ONLY_ACTION = 'Only admin can perform this action.';

View File

@ -195,7 +195,10 @@
"unpause": "UnPause",
"execution-date": "Execution Date",
"start-date": "Start Date",
"end-date": "End Date"
"end-date": "End Date",
"show-deleted": "Show deleted",
"add-bot": "Add Bot",
"search-for-bots": "Search for bots..."
},
"message": {
"service-email-required": "Service account Email is required",