diff --git a/openmetadata-ui/src/main/resources/ui/src/App.tsx b/openmetadata-ui/src/main/resources/ui/src/App.tsx index ec5a06d7257..351041c975c 100644 --- a/openmetadata-ui/src/main/resources/ui/src/App.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/App.tsx @@ -31,6 +31,7 @@ import 'react-toastify/dist/ReactToastify.min.css'; import { AuthProvider } from './authentication/auth-provider/AuthProvider'; import Appbar from './components/app-bar/Appbar'; import GlobalSearchProvider from './components/GlobalSearchProvider/GlobalSearchProvider'; +import PermissionProvider from './components/PermissionProvider/PermissionProvider'; import WebSocketProvider from './components/web-scoket/web-scoket.provider'; import { toastOptions } from './constants/toast.constants'; import ErrorBoundry from './ErrorBoundry/ErrorBoundry'; @@ -56,12 +57,14 @@ const App: FunctionComponent = () => { - - - - - - + + + + + + + + diff --git a/openmetadata-ui/src/main/resources/ui/src/components/BotDetails/BotDetails.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/BotDetails/BotDetails.component.tsx index 69bc2fab2b5..4fb8b9b3a30 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/BotDetails/BotDetails.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/BotDetails/BotDetails.component.tsx @@ -30,9 +30,11 @@ import { GlobalSettingOptions, GlobalSettingsMenuCategory, } from '../../constants/globalSettings.constants'; +import { Operation } from '../../generated/entity/policies/accessControl/rule'; import { JWTTokenExpiry, User } from '../../generated/entity/teams/user'; import { EntityReference } from '../../generated/type/entityReference'; import { getEntityName, requiredField } from '../../utils/CommonUtils'; +import { checkPemission } from '../../utils/PermissionsUtils'; import { getSettingPath } from '../../utils/RouterUtils'; import SVGIcons, { Icons } from '../../utils/SvgUtils'; import { showErrorToast } from '../../utils/ToastUtils'; @@ -43,6 +45,8 @@ import { reactSingleSelectCustomStyle } from '../common/react-select-component/r import TitleBreadcrumb from '../common/title-breadcrumb/title-breadcrumb.component'; import PageLayout, { leftPanelAntCardStyle } from '../containers/PageLayout'; import ConfirmationModal from '../Modals/ConfirmationModal/ConfirmationModal'; +import { usePermissionProvider } from '../PermissionProvider/PermissionProvider'; +import { ResourceEntity } from '../PermissionProvider/PermissionProvider.interface'; import { UserDetails } from '../Users/Users.interface'; interface BotsDetailProp extends HTMLAttributes { @@ -61,6 +65,7 @@ const BotDetails: FC = ({ updateBotsDetails, revokeTokenHandler, }) => { + const { permissions } = usePermissionProvider(); const [displayName, setDisplayName] = useState(botsData.displayName); const [isDisplayNameEdit, setIsDisplayNameEdit] = useState(false); const [isDescriptionEdit, setIsDescriptionEdit] = useState(false); @@ -72,6 +77,23 @@ const BotDetails: FC = ({ const [generateToken, setGenerateToken] = useState(false); const [selectedExpiry, setSelectedExpiry] = useState('7'); + const editAllPermission = checkPemission( + Operation.EditAll, + ResourceEntity.BOT, + permissions + ); + const displayNamePermission = checkPemission( + Operation.EditDisplayName, + ResourceEntity.BOT, + permissions + ); + + const descriptionPermission = checkPemission( + Operation.EditDescription, + ResourceEntity.BOT, + permissions + ); + const getJWTTokenExpiryOptions = () => { return Object.keys(JWTTokenExpiry).map((expiry) => { const expiryValue = JWTTokenExpiry[expiry as keyof typeof JWTTokenExpiry]; @@ -209,13 +231,19 @@ const BotDetails: FC = ({ Add display name )} - - + {(displayNamePermission || editAllPermission) && ( + + )} )} @@ -226,9 +254,9 @@ const BotDetails: FC = ({ return (
setIsDescriptionEdit(false)} onDescriptionEdit={() => setIsDescriptionEdit(true)} @@ -407,7 +435,7 @@ const BotDetails: FC = ({
{generateToken ? 'Generate JWT token' : 'JWT Token'}
- {!generateToken ? ( + {!generateToken && editAllPermission ? (
- - - - - + {viewAllPermission ? ( + <> + + + + + + + + + {createPermission && ( + + )} + + + + + + + ) : ( + + )} ); }; diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/PoliciesPage/AddPolicyPage/AddPolicyPage.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/PoliciesPage/AddPolicyPage/AddPolicyPage.tsx index 897eb1cea21..2f5bc9c7dcb 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/PoliciesPage/AddPolicyPage/AddPolicyPage.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/PoliciesPage/AddPolicyPage/AddPolicyPage.tsx @@ -80,11 +80,12 @@ const AddPolicyPage = () => { }; const handleSumbit = async () => { + const { condition, ...rest } = ruleData; const data: CreatePolicy = { name, description, policyType: PolicyType.AccessControl, - rules: [ruleData], + rules: [condition ? { ...rest, condition } : rest], }; try { diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/PoliciesPage/PoliciesDetailPage/AddRulePage.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/PoliciesPage/PoliciesDetailPage/AddRulePage.tsx index 7fd1a74edc6..3f339b0f111 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/PoliciesPage/PoliciesDetailPage/AddRulePage.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/PoliciesPage/PoliciesDetailPage/AddRulePage.tsx @@ -87,9 +87,10 @@ const AddRulePage = () => { }; const handleSubmit = async () => { + const { condition, ...rest } = ruleData; const patch = compare(policy, { ...policy, - rules: [...policy.rules, ruleData], + rules: [...policy.rules, condition ? { ...rest, condition } : rest], }); try { const data = await patchPolicy(patch, policy.id); diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/PoliciesPage/PoliciesDetailPage/EditRulePage.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/PoliciesPage/PoliciesDetailPage/EditRulePage.tsx index c13c5d3d56d..837452cc1d5 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/PoliciesPage/PoliciesDetailPage/EditRulePage.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/PoliciesPage/PoliciesDetailPage/EditRulePage.tsx @@ -98,11 +98,14 @@ const EditRulePage = () => { const existingRules = policy.rules; const updatedRules = existingRules.map((rule) => { if (rule.name === ruleName) { - return ruleData; + const { condition, ...rest } = ruleData; + + return condition ? { ...rest, condition } : rest; } else { return rule; } }); + const patch = compare(policy, { ...policy, rules: updatedRules, diff --git a/openmetadata-ui/src/main/resources/ui/src/router/AdminProtectedRoute.tsx b/openmetadata-ui/src/main/resources/ui/src/router/AdminProtectedRoute.tsx index 520d1dd47fb..9c915f89e8e 100644 --- a/openmetadata-ui/src/main/resources/ui/src/router/AdminProtectedRoute.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/router/AdminProtectedRoute.tsx @@ -17,11 +17,15 @@ import { useAuthContext } from '../authentication/auth-provider/AuthProvider'; import { ROUTES } from '../constants/constants'; import { useAuth } from '../hooks/authHooks'; -const AdminProtectedRoute = (routeProps: RouteProps) => { +interface AdminProtectedRouteProps extends RouteProps { + hasPermission: boolean; +} + +const AdminProtectedRoute = (routeProps: AdminProtectedRouteProps) => { const { isAdminUser } = useAuth(); const { isAuthDisabled, isAuthenticated } = useAuthContext(); - if (isAuthDisabled || isAdminUser) { + if (isAuthDisabled || isAdminUser || routeProps.hasPermission) { return ; } else if (isAuthenticated) { return ; diff --git a/openmetadata-ui/src/main/resources/ui/src/router/GlobalSettingRouter.tsx b/openmetadata-ui/src/main/resources/ui/src/router/GlobalSettingRouter.tsx index f86a7b57511..9878d3082cc 100644 --- a/openmetadata-ui/src/main/resources/ui/src/router/GlobalSettingRouter.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/router/GlobalSettingRouter.tsx @@ -13,11 +13,15 @@ import React from 'react'; import { Redirect, Route, Switch } from 'react-router-dom'; +import { usePermissionProvider } from '../components/PermissionProvider/PermissionProvider'; +import { ResourceEntity } from '../components/PermissionProvider/PermissionProvider.interface'; import { GlobalSettingOptions, GlobalSettingsMenuCategory, } from '../constants/globalSettings.constants'; +import { Operation } from '../generated/entity/policies/policy'; import TeamsPage from '../pages/teams/TeamsPage'; +import { checkPemission } from '../utils/PermissionsUtils'; import { getSettingCategoryPath, getSettingPath } from '../utils/RouterUtils'; import AdminProtectedRoute from './AdminProtectedRoute'; import withSuspenseFallback from './withSuspenseFallback'; @@ -64,6 +68,8 @@ const SlackSettingsPage = withSuspenseFallback( ); const GlobalSettingRouter = () => { + const { permissions } = usePermissionProvider(); + return ( @@ -97,6 +103,11 @@ const GlobalSettingRouter = () => { { { { { { { { { + const allResource = permissions.all; + const entityResource = permissions[resourceType]; + + /** + * If allresource is present then check for permission and return it + */ + if (allResource) { + return allResource.All || allResource[operation]; + } + + return entityResource[operation]; +}; + +/** + * + * @param permission ResourcePermission + * @returns OperationPermission - {Operation:true/false} + */ +export const getOperationPermissions = ( + permission: ResourcePermission +): OperationPermission => { + return permission.permissions.reduce( + (acc: OperationPermission, curr: Permission) => { + return { + ...acc, + [curr.operation as Operation]: curr.access === Access.Allow, + }; + }, + {} as OperationPermission + ); +}; + +/** + * + * @param permissions Take ResourcePermission list + * @returns UIPermission + */ +export const getUIPermission = ( + permissions: ResourcePermission[] +): UIPermission => { + return permissions.reduce((acc: UIPermission, curr: ResourcePermission) => { + return { + ...acc, + [curr.resource as ResourceEntity]: getOperationPermissions(curr), + }; + }, {} as UIPermission); +}; + export const LIST_CAP = 1;