mirror of
https://github.com/Unleash/unleash.git
synced 2025-09-15 17:50:48 +02:00
feat: upgrade AdminAlert to PermissionGuard (#4074)
https://linear.app/unleash/issue/2-1165/improve-adminalert-usage-to-be-more-generic-accept-non-admin Upgrades our `AdminAlert` to a new `PermissionGuard`. **Question**: We don't **need** to, but **should** we be specific about the `ADMIN` permission every time? Technically `PermissionGuard` could have `permissions` as optional and assume `[]` by default, which will add `ADMIN` anyways. However, I feel like we may gain some readability if we're specific about it. WDYT? Single permission:  Multiple permissions: 
This commit is contained in:
parent
d2a98d0338
commit
95a0c7748f
@ -1,7 +1,4 @@
|
|||||||
import { useContext } from 'react';
|
import { PermissionGuard } from 'component/common/PermissionGuard/PermissionGuard';
|
||||||
import AccessContext from 'contexts/AccessContext';
|
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
|
||||||
import { AdminAlert } from 'component/common/AdminAlert/AdminAlert';
|
|
||||||
import { ApiTokenTable } from 'component/common/ApiTokenTable/ApiTokenTable';
|
import { ApiTokenTable } from 'component/common/ApiTokenTable/ApiTokenTable';
|
||||||
import { PageContent } from 'component/common/PageContent/PageContent';
|
import { PageContent } from 'component/common/PageContent/PageContent';
|
||||||
import { PageHeader } from 'component/common/PageHeader/PageHeader';
|
import { PageHeader } from 'component/common/PageHeader/PageHeader';
|
||||||
@ -24,7 +21,6 @@ import {
|
|||||||
} from '@server/types/permissions';
|
} from '@server/types/permissions';
|
||||||
|
|
||||||
export const ApiTokenPage = () => {
|
export const ApiTokenPage = () => {
|
||||||
const { hasAccess } = useContext(AccessContext);
|
|
||||||
const { tokens, loading, refetch } = useApiTokens();
|
const { tokens, loading, refetch } = useApiTokens();
|
||||||
const { deleteToken } = useApiTokensApi();
|
const { deleteToken } = useApiTokensApi();
|
||||||
|
|
||||||
@ -71,13 +67,13 @@ export const ApiTokenPage = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ConditionallyRender
|
<PermissionGuard
|
||||||
condition={hasAccess([
|
permissions={[
|
||||||
READ_CLIENT_API_TOKEN,
|
READ_CLIENT_API_TOKEN,
|
||||||
READ_FRONTEND_API_TOKEN,
|
READ_FRONTEND_API_TOKEN,
|
||||||
ADMIN,
|
ADMIN,
|
||||||
])}
|
]}
|
||||||
show={() => (
|
>
|
||||||
<PageContent
|
<PageContent
|
||||||
header={
|
header={
|
||||||
<PageHeader
|
<PageHeader
|
||||||
@ -114,8 +110,6 @@ export const ApiTokenPage = () => {
|
|||||||
globalFilter={globalFilter}
|
globalFilter={globalFilter}
|
||||||
/>
|
/>
|
||||||
</PageContent>
|
</PageContent>
|
||||||
)}
|
</PermissionGuard>
|
||||||
elseShow={() => <AdminAlert />}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import React from 'react';
|
|
||||||
import { Alert } from '@mui/material';
|
import { Alert } from '@mui/material';
|
||||||
import { PageContent } from 'component/common/PageContent/PageContent';
|
import { PageContent } from 'component/common/PageContent/PageContent';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
@ -8,6 +7,8 @@ import { SamlAuth } from './SamlAuth/SamlAuth';
|
|||||||
import { PasswordAuth } from './PasswordAuth/PasswordAuth';
|
import { PasswordAuth } from './PasswordAuth/PasswordAuth';
|
||||||
import { GoogleAuth } from './GoogleAuth/GoogleAuth';
|
import { GoogleAuth } from './GoogleAuth/GoogleAuth';
|
||||||
import { TabNav } from 'component/common/TabNav/TabNav/TabNav';
|
import { TabNav } from 'component/common/TabNav/TabNav/TabNav';
|
||||||
|
import { PermissionGuard } from 'component/common/PermissionGuard/PermissionGuard';
|
||||||
|
import { ADMIN } from '@server/types/permissions';
|
||||||
|
|
||||||
export const AuthSettings = () => {
|
export const AuthSettings = () => {
|
||||||
const { authenticationType } = useUiConfig().uiConfig;
|
const { authenticationType } = useUiConfig().uiConfig;
|
||||||
@ -36,6 +37,7 @@ export const AuthSettings = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
<PermissionGuard permissions={ADMIN}>
|
||||||
<PageContent header="Single Sign-On">
|
<PageContent header="Single Sign-On">
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={authenticationType === 'enterprise'}
|
condition={authenticationType === 'enterprise'}
|
||||||
@ -45,9 +47,9 @@ export const AuthSettings = () => {
|
|||||||
condition={authenticationType === 'open-source'}
|
condition={authenticationType === 'open-source'}
|
||||||
show={
|
show={
|
||||||
<Alert severity="warning">
|
<Alert severity="warning">
|
||||||
You are running the open-source version of Unleash.
|
You are running the open-source version of
|
||||||
You have to use the Enterprise edition in order
|
Unleash. You have to use the Enterprise edition
|
||||||
configure Single Sign-on.
|
in order configure Single Sign-on.
|
||||||
</Alert>
|
</Alert>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@ -55,9 +57,9 @@ export const AuthSettings = () => {
|
|||||||
condition={authenticationType === 'demo'}
|
condition={authenticationType === 'demo'}
|
||||||
show={
|
show={
|
||||||
<Alert severity="warning">
|
<Alert severity="warning">
|
||||||
You are running Unleash in demo mode. You have to
|
You are running Unleash in demo mode. You have
|
||||||
use the Enterprise edition in order configure Single
|
to use the Enterprise edition in order configure
|
||||||
Sign-on.
|
Single Sign-on.
|
||||||
</Alert>
|
</Alert>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@ -65,9 +67,10 @@ export const AuthSettings = () => {
|
|||||||
condition={authenticationType === 'custom'}
|
condition={authenticationType === 'custom'}
|
||||||
show={
|
show={
|
||||||
<Alert severity="warning">
|
<Alert severity="warning">
|
||||||
You have decided to use custom authentication type.
|
You have decided to use custom authentication
|
||||||
You have to use the Enterprise edition in order
|
type. You have to use the Enterprise edition in
|
||||||
configure Single Sign-on from the user interface.
|
order configure Single Sign-on from the user
|
||||||
|
interface.
|
||||||
</Alert>
|
</Alert>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@ -81,6 +84,7 @@ export const AuthSettings = () => {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</PageContent>
|
</PageContent>
|
||||||
|
</PermissionGuard>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useContext, useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
@ -9,8 +9,6 @@ import {
|
|||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { Alert } from '@mui/material';
|
import { Alert } from '@mui/material';
|
||||||
import { PageContent } from 'component/common/PageContent/PageContent';
|
import { PageContent } from 'component/common/PageContent/PageContent';
|
||||||
import AccessContext from 'contexts/AccessContext';
|
|
||||||
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
|
||||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||||
import useAuthSettings from 'hooks/api/getters/useAuthSettings/useAuthSettings';
|
import useAuthSettings from 'hooks/api/getters/useAuthSettings/useAuthSettings';
|
||||||
import useAuthSettingsApi from 'hooks/api/actions/useAuthSettingsApi/useAuthSettingsApi';
|
import useAuthSettingsApi from 'hooks/api/actions/useAuthSettingsApi/useAuthSettingsApi';
|
||||||
@ -31,7 +29,6 @@ export const GoogleAuth = () => {
|
|||||||
const { setToastData, setToastApiError } = useToast();
|
const { setToastData, setToastApiError } = useToast();
|
||||||
const { uiConfig } = useUiConfig();
|
const { uiConfig } = useUiConfig();
|
||||||
const [data, setData] = useState(initialState);
|
const [data, setData] = useState(initialState);
|
||||||
const { hasAccess } = useContext(AccessContext);
|
|
||||||
const { config } = useAuthSettings('google');
|
const { config } = useAuthSettings('google');
|
||||||
const { updateSettings, errors, loading } = useAuthSettingsApi('google');
|
const { updateSettings, errors, loading } = useAuthSettingsApi('google');
|
||||||
|
|
||||||
@ -41,10 +38,6 @@ export const GoogleAuth = () => {
|
|||||||
}
|
}
|
||||||
}, [config]);
|
}, [config]);
|
||||||
|
|
||||||
if (!hasAccess(ADMIN)) {
|
|
||||||
return <span>You need admin privileges to access this section.</span>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const updateField = (event: React.ChangeEvent<HTMLInputElement>) => {
|
const updateField = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
setData({
|
setData({
|
||||||
...data,
|
...data,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useContext, useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
FormControl,
|
FormControl,
|
||||||
@ -12,8 +12,6 @@ import {
|
|||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { Alert } from '@mui/material';
|
import { Alert } from '@mui/material';
|
||||||
import { PageContent } from 'component/common/PageContent/PageContent';
|
import { PageContent } from 'component/common/PageContent/PageContent';
|
||||||
import AccessContext from 'contexts/AccessContext';
|
|
||||||
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
|
||||||
import { AutoCreateForm } from '../AutoCreateForm/AutoCreateForm';
|
import { AutoCreateForm } from '../AutoCreateForm/AutoCreateForm';
|
||||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||||
import useAuthSettingsApi from 'hooks/api/actions/useAuthSettingsApi/useAuthSettingsApi';
|
import useAuthSettingsApi from 'hooks/api/actions/useAuthSettingsApi/useAuthSettingsApi';
|
||||||
@ -41,7 +39,6 @@ export const OidcAuth = () => {
|
|||||||
const { setToastData, setToastApiError } = useToast();
|
const { setToastData, setToastApiError } = useToast();
|
||||||
const { uiConfig } = useUiConfig();
|
const { uiConfig } = useUiConfig();
|
||||||
const [data, setData] = useState(initialState);
|
const [data, setData] = useState(initialState);
|
||||||
const { hasAccess } = useContext(AccessContext);
|
|
||||||
const { config } = useAuthSettings('oidc');
|
const { config } = useAuthSettings('oidc');
|
||||||
const { updateSettings, errors, loading } = useAuthSettingsApi('oidc');
|
const { updateSettings, errors, loading } = useAuthSettingsApi('oidc');
|
||||||
|
|
||||||
@ -51,14 +48,6 @@ export const OidcAuth = () => {
|
|||||||
}
|
}
|
||||||
}, [config]);
|
}, [config]);
|
||||||
|
|
||||||
if (!hasAccess(ADMIN)) {
|
|
||||||
return (
|
|
||||||
<Alert severity="error">
|
|
||||||
You need to be a root admin to access this section.
|
|
||||||
</Alert>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const updateField = (event: React.ChangeEvent<HTMLInputElement>) => {
|
const updateField = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
setValue(event.target.name, event.target.value);
|
setValue(event.target.name, event.target.value);
|
||||||
};
|
};
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import React, { useContext, useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { Button, FormControlLabel, Grid, Switch } from '@mui/material';
|
import { Button, FormControlLabel, Grid, Switch } from '@mui/material';
|
||||||
import { Alert } from '@mui/material';
|
import { Alert } from '@mui/material';
|
||||||
import { PageContent } from 'component/common/PageContent/PageContent';
|
import { PageContent } from 'component/common/PageContent/PageContent';
|
||||||
import AccessContext from 'contexts/AccessContext';
|
|
||||||
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
|
||||||
import useAuthSettings from 'hooks/api/getters/useAuthSettings/useAuthSettings';
|
import useAuthSettings from 'hooks/api/getters/useAuthSettings/useAuthSettings';
|
||||||
import useAuthSettingsApi, {
|
import useAuthSettingsApi, {
|
||||||
ISimpleAuthSettings,
|
ISimpleAuthSettings,
|
||||||
@ -22,7 +20,6 @@ export const PasswordAuth = () => {
|
|||||||
useState<boolean>(false);
|
useState<boolean>(false);
|
||||||
const { updateSettings, errors, loading } =
|
const { updateSettings, errors, loading } =
|
||||||
useAuthSettingsApi<ISimpleAuthSettings>('simple');
|
useAuthSettingsApi<ISimpleAuthSettings>('simple');
|
||||||
const { hasAccess } = useContext(AccessContext);
|
|
||||||
const [confirmationOpen, setConfirmationOpen] = useState(false);
|
const [confirmationOpen, setConfirmationOpen] = useState(false);
|
||||||
const { data: adminCount } = useAdminCount();
|
const { data: adminCount } = useAdminCount();
|
||||||
const { tokens } = useApiTokens();
|
const { tokens } = useApiTokens();
|
||||||
@ -31,14 +28,6 @@ export const PasswordAuth = () => {
|
|||||||
setDisablePasswordAuth(!!config.disabled);
|
setDisablePasswordAuth(!!config.disabled);
|
||||||
}, [config.disabled]);
|
}, [config.disabled]);
|
||||||
|
|
||||||
if (!hasAccess(ADMIN)) {
|
|
||||||
return (
|
|
||||||
<Alert severity="error">
|
|
||||||
You need to be a root admin to access this section.
|
|
||||||
</Alert>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const updateDisabled = () => {
|
const updateDisabled = () => {
|
||||||
setDisablePasswordAuth(!disablePasswordAuth);
|
setDisablePasswordAuth(!disablePasswordAuth);
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useContext, useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
FormControlLabel,
|
FormControlLabel,
|
||||||
@ -8,8 +8,6 @@ import {
|
|||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { Alert } from '@mui/material';
|
import { Alert } from '@mui/material';
|
||||||
import { PageContent } from 'component/common/PageContent/PageContent';
|
import { PageContent } from 'component/common/PageContent/PageContent';
|
||||||
import AccessContext from 'contexts/AccessContext';
|
|
||||||
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
|
||||||
import { AutoCreateForm } from '../AutoCreateForm/AutoCreateForm';
|
import { AutoCreateForm } from '../AutoCreateForm/AutoCreateForm';
|
||||||
import useToast from 'hooks/useToast';
|
import useToast from 'hooks/useToast';
|
||||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||||
@ -36,7 +34,6 @@ export const SamlAuth = () => {
|
|||||||
const { setToastData, setToastApiError } = useToast();
|
const { setToastData, setToastApiError } = useToast();
|
||||||
const { uiConfig } = useUiConfig();
|
const { uiConfig } = useUiConfig();
|
||||||
const [data, setData] = useState(initialState);
|
const [data, setData] = useState(initialState);
|
||||||
const { hasAccess } = useContext(AccessContext);
|
|
||||||
const { config } = useAuthSettings('saml');
|
const { config } = useAuthSettings('saml');
|
||||||
const { updateSettings, errors, loading } = useAuthSettingsApi('saml');
|
const { updateSettings, errors, loading } = useAuthSettingsApi('saml');
|
||||||
|
|
||||||
@ -46,14 +43,6 @@ export const SamlAuth = () => {
|
|||||||
}
|
}
|
||||||
}, [config]);
|
}, [config]);
|
||||||
|
|
||||||
if (!hasAccess(ADMIN)) {
|
|
||||||
return (
|
|
||||||
<Alert severity="error">
|
|
||||||
You need to be a root admin to access this section.
|
|
||||||
</Alert>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const updateField = (event: React.ChangeEvent<HTMLInputElement>) => {
|
const updateField = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
setValue(event.target.name, event.target.value);
|
setValue(event.target.name, event.target.value);
|
||||||
};
|
};
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import { PageContent } from 'component/common/PageContent/PageContent';
|
import { PageContent } from 'component/common/PageContent/PageContent';
|
||||||
import { useContext, useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import AccessContext from 'contexts/AccessContext';
|
import { PermissionGuard } from 'component/common/PermissionGuard/PermissionGuard';
|
||||||
import { AdminAlert } from 'component/common/AdminAlert/AdminAlert';
|
|
||||||
import { useInstanceStatus } from 'hooks/api/getters/useInstanceStatus/useInstanceStatus';
|
import { useInstanceStatus } from 'hooks/api/getters/useInstanceStatus/useInstanceStatus';
|
||||||
import { Alert } from '@mui/material';
|
import { Alert } from '@mui/material';
|
||||||
import { BillingDashboard } from './BillingDashboard/BillingDashboard';
|
import { BillingDashboard } from './BillingDashboard/BillingDashboard';
|
||||||
@ -19,7 +18,6 @@ export const Billing = () => {
|
|||||||
loading,
|
loading,
|
||||||
} = useInstanceStatus();
|
} = useInstanceStatus();
|
||||||
const { invoices } = useInvoices();
|
const { invoices } = useInvoices();
|
||||||
const { hasAccess } = useContext(AccessContext);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const hardRefresh = async () => {
|
const hardRefresh = async () => {
|
||||||
@ -35,18 +33,14 @@ export const Billing = () => {
|
|||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={isBilling}
|
condition={isBilling}
|
||||||
show={
|
show={
|
||||||
<ConditionallyRender
|
<PermissionGuard permissions={ADMIN}>
|
||||||
condition={hasAccess(ADMIN)}
|
|
||||||
show={() => (
|
|
||||||
<>
|
<>
|
||||||
<BillingDashboard
|
<BillingDashboard
|
||||||
instanceStatus={instanceStatus!}
|
instanceStatus={instanceStatus!}
|
||||||
/>
|
/>
|
||||||
<BillingHistory data={invoices} />
|
<BillingHistory data={invoices} />
|
||||||
</>
|
</>
|
||||||
)}
|
</PermissionGuard>
|
||||||
elseShow={() => <AdminAlert />}
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
elseShow={
|
elseShow={
|
||||||
<Alert severity="error">
|
<Alert severity="error">
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Navigate } from 'react-router-dom';
|
import { Navigate } from 'react-router-dom';
|
||||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||||
import InvoiceAdminPage from 'component/admin/invoice/InvoiceAdminPage';
|
import { InvoiceAdminPage } from 'component/admin/invoice/InvoiceAdminPage';
|
||||||
|
|
||||||
const FlaggedBillingRedirect = () => {
|
const FlaggedBillingRedirect = () => {
|
||||||
const { uiConfig, loading } = useUiConfig();
|
const { uiConfig, loading } = useUiConfig();
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { PermissionGuard } from 'component/common/PermissionGuard/PermissionGuard';
|
||||||
import { AdminAlert } from 'component/common/AdminAlert/AdminAlert';
|
|
||||||
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
||||||
import AccessContext from 'contexts/AccessContext';
|
|
||||||
import React, { useContext } from 'react';
|
|
||||||
import { PageContent } from 'component/common/PageContent/PageContent';
|
import { PageContent } from 'component/common/PageContent/PageContent';
|
||||||
import { PageHeader } from 'component/common/PageHeader/PageHeader';
|
import { PageHeader } from 'component/common/PageHeader/PageHeader';
|
||||||
import { Box } from '@mui/material';
|
import { Box } from '@mui/material';
|
||||||
@ -10,19 +7,13 @@ import { CorsHelpAlert } from 'component/admin/cors/CorsHelpAlert';
|
|||||||
import { CorsForm } from 'component/admin/cors/CorsForm';
|
import { CorsForm } from 'component/admin/cors/CorsForm';
|
||||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||||
|
|
||||||
export const CorsAdmin = () => {
|
export const CorsAdmin = () => (
|
||||||
const { hasAccess } = useContext(AccessContext);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
<div>
|
||||||
<ConditionallyRender
|
<PermissionGuard permissions={ADMIN}>
|
||||||
condition={hasAccess(ADMIN)}
|
<CorsPage />
|
||||||
show={<CorsPage />}
|
</PermissionGuard>
|
||||||
elseShow={<AdminAlert />}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
|
||||||
const CorsPage = () => {
|
const CorsPage = () => {
|
||||||
const { uiConfig, loading } = useUiConfig();
|
const { uiConfig, loading } = useUiConfig();
|
||||||
|
@ -1,20 +1,11 @@
|
|||||||
import { AdminAlert } from 'component/common/AdminAlert/AdminAlert';
|
import { PermissionGuard } from 'component/common/PermissionGuard/PermissionGuard';
|
||||||
import { GroupsList } from './GroupsList/GroupsList';
|
import { GroupsList } from './GroupsList/GroupsList';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
|
||||||
import { useContext } from 'react';
|
|
||||||
import AccessContext from 'contexts/AccessContext';
|
|
||||||
import { ADMIN } from '@server/types/permissions';
|
import { ADMIN } from '@server/types/permissions';
|
||||||
|
|
||||||
export const GroupsAdmin = () => {
|
export const GroupsAdmin = () => (
|
||||||
const { hasAccess } = useContext(AccessContext);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
<div>
|
||||||
<ConditionallyRender
|
<PermissionGuard permissions={ADMIN}>
|
||||||
condition={hasAccess(ADMIN)}
|
<GroupsList />
|
||||||
show={<GroupsList />}
|
</PermissionGuard>
|
||||||
elseShow={<AdminAlert />}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
@ -1,25 +1,11 @@
|
|||||||
import { useContext } from 'react';
|
|
||||||
import InvoiceList from './InvoiceList';
|
import InvoiceList from './InvoiceList';
|
||||||
import AccessContext from 'contexts/AccessContext';
|
|
||||||
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { PermissionGuard } from 'component/common/PermissionGuard/PermissionGuard';
|
||||||
import { Alert } from '@mui/material';
|
|
||||||
|
|
||||||
const InvoiceAdminPage = () => {
|
export const InvoiceAdminPage = () => (
|
||||||
const { hasAccess } = useContext(AccessContext);
|
|
||||||
return (
|
|
||||||
<div>
|
<div>
|
||||||
<ConditionallyRender
|
<PermissionGuard permissions={ADMIN}>
|
||||||
condition={hasAccess(ADMIN)}
|
<InvoiceList />
|
||||||
show={<InvoiceList />}
|
</PermissionGuard>
|
||||||
elseShow={
|
|
||||||
<Alert severity="error">
|
|
||||||
You need to be instance admin to access this section.
|
|
||||||
</Alert>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
|
||||||
export default InvoiceAdminPage;
|
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { PermissionGuard } from 'component/common/PermissionGuard/PermissionGuard';
|
||||||
import { AdminAlert } from 'component/common/AdminAlert/AdminAlert';
|
|
||||||
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
||||||
import AccessContext from 'contexts/AccessContext';
|
|
||||||
import React, { useContext } from 'react';
|
|
||||||
import { PageContent } from 'component/common/PageContent/PageContent';
|
import { PageContent } from 'component/common/PageContent/PageContent';
|
||||||
import { PageHeader } from 'component/common/PageHeader/PageHeader';
|
import { PageHeader } from 'component/common/PageHeader/PageHeader';
|
||||||
import { Box, styled } from '@mui/material';
|
import { Box, styled } from '@mui/material';
|
||||||
@ -10,19 +7,13 @@ import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
|||||||
import { MaintenanceTooltip } from './MaintenanceTooltip';
|
import { MaintenanceTooltip } from './MaintenanceTooltip';
|
||||||
import { MaintenanceToggle } from './MaintenanceToggle';
|
import { MaintenanceToggle } from './MaintenanceToggle';
|
||||||
|
|
||||||
export const MaintenanceAdmin = () => {
|
export const MaintenanceAdmin = () => (
|
||||||
const { hasAccess } = useContext(AccessContext);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
<div>
|
||||||
<ConditionallyRender
|
<PermissionGuard permissions={ADMIN}>
|
||||||
condition={hasAccess(ADMIN)}
|
<MaintenancePage />
|
||||||
show={<MaintenancePage />}
|
</PermissionGuard>
|
||||||
elseShow={<AdminAlert />}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
|
||||||
const StyledBox = styled(Box)(({ theme }) => ({
|
const StyledBox = styled(Box)(({ theme }) => ({
|
||||||
display: 'grid',
|
display: 'grid',
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import { useContext, useState } from 'react';
|
import { useState } from 'react';
|
||||||
import AccessContext from 'contexts/AccessContext';
|
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
||||||
import { RolesTable } from './RolesTable/RolesTable';
|
import { RolesTable } from './RolesTable/RolesTable';
|
||||||
import { AdminAlert } from 'component/common/AdminAlert/AdminAlert';
|
import { PermissionGuard } from 'component/common/PermissionGuard/PermissionGuard';
|
||||||
import { PageContent } from 'component/common/PageContent/PageContent';
|
import { PageContent } from 'component/common/PageContent/PageContent';
|
||||||
import { Tab, Tabs, styled, useMediaQuery } from '@mui/material';
|
import { Tab, Tabs, styled, useMediaQuery } from '@mui/material';
|
||||||
import { Route, Routes, useLocation } from 'react-router-dom';
|
import { Route, Routes, useLocation } from 'react-router-dom';
|
||||||
@ -45,7 +44,6 @@ const StyledActions = styled('div')({
|
|||||||
|
|
||||||
export const Roles = () => {
|
export const Roles = () => {
|
||||||
const { uiConfig } = useUiConfig();
|
const { uiConfig } = useUiConfig();
|
||||||
const { hasAccess } = useContext(AccessContext);
|
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
|
|
||||||
const { roles, projectRoles, loading } = useRoles();
|
const { roles, projectRoles, loading } = useRoles();
|
||||||
@ -84,9 +82,7 @@ export const Roles = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<ConditionallyRender
|
<PermissionGuard permissions={[READ_ROLE, ADMIN]}>
|
||||||
condition={hasAccess(READ_ROLE)}
|
|
||||||
show={
|
|
||||||
<StyledPageContent
|
<StyledPageContent
|
||||||
headerClass="page-header"
|
headerClass="page-header"
|
||||||
bodyClass="page-body"
|
bodyClass="page-body"
|
||||||
@ -102,24 +98,19 @@ export const Roles = () => {
|
|||||||
variant="scrollable"
|
variant="scrollable"
|
||||||
allowScrollButtonsMobile
|
allowScrollButtonsMobile
|
||||||
>
|
>
|
||||||
{tabs.map(
|
{tabs.map(({ label, path, total }) => (
|
||||||
({ label, path, total }) => (
|
|
||||||
<Tab
|
<Tab
|
||||||
key={label}
|
key={label}
|
||||||
value={path}
|
value={path}
|
||||||
label={
|
label={
|
||||||
<CenteredNavLink
|
<CenteredNavLink to={path}>
|
||||||
to={path}
|
|
||||||
>
|
|
||||||
<span>
|
<span>
|
||||||
{label} (
|
{label} ({total})
|
||||||
{total})
|
|
||||||
</span>
|
</span>
|
||||||
</CenteredNavLink>
|
</CenteredNavLink>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
)
|
))}
|
||||||
)}
|
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</StyledTabsContainer>
|
</StyledTabsContainer>
|
||||||
<StyledActions>
|
<StyledActions>
|
||||||
@ -128,12 +119,8 @@ export const Roles = () => {
|
|||||||
show={
|
show={
|
||||||
<>
|
<>
|
||||||
<Search
|
<Search
|
||||||
initialValue={
|
initialValue={searchValue}
|
||||||
searchValue
|
onChange={setSearchValue}
|
||||||
}
|
|
||||||
onChange={
|
|
||||||
setSearchValue
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
<PageHeader.Divider />
|
<PageHeader.Divider />
|
||||||
</>
|
</>
|
||||||
@ -197,9 +184,7 @@ export const Roles = () => {
|
|||||||
/>
|
/>
|
||||||
</Routes>
|
</Routes>
|
||||||
</StyledPageContent>
|
</StyledPageContent>
|
||||||
}
|
</PermissionGuard>
|
||||||
elseShow={<AdminAlert />}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,20 +1,11 @@
|
|||||||
import { useContext } from 'react';
|
|
||||||
import AccessContext from 'contexts/AccessContext';
|
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
|
||||||
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
||||||
import { AdminAlert } from 'component/common/AdminAlert/AdminAlert';
|
import { PermissionGuard } from 'component/common/PermissionGuard/PermissionGuard';
|
||||||
import { ServiceAccountsTable } from './ServiceAccountsTable/ServiceAccountsTable';
|
import { ServiceAccountsTable } from './ServiceAccountsTable/ServiceAccountsTable';
|
||||||
|
|
||||||
export const ServiceAccounts = () => {
|
export const ServiceAccounts = () => (
|
||||||
const { hasAccess } = useContext(AccessContext);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
<div>
|
||||||
<ConditionallyRender
|
<PermissionGuard permissions={ADMIN}>
|
||||||
condition={hasAccess(ADMIN)}
|
<ServiceAccountsTable />
|
||||||
show={<ServiceAccountsTable />}
|
</PermissionGuard>
|
||||||
elseShow={<AdminAlert />}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
@ -1,24 +1,15 @@
|
|||||||
import { useContext } from 'react';
|
|
||||||
import UsersList from './UsersList/UsersList';
|
import UsersList from './UsersList/UsersList';
|
||||||
import AccessContext from 'contexts/AccessContext';
|
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
|
||||||
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
||||||
import { AdminAlert } from 'component/common/AdminAlert/AdminAlert';
|
import { PermissionGuard } from 'component/common/PermissionGuard/PermissionGuard';
|
||||||
import { InviteLinkBar } from './InviteLinkBar/InviteLinkBar';
|
import { InviteLinkBar } from './InviteLinkBar/InviteLinkBar';
|
||||||
|
|
||||||
export const UsersAdmin = () => {
|
export const UsersAdmin = () => (
|
||||||
const { hasAccess } = useContext(AccessContext);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
<div>
|
||||||
<InviteLinkBar />
|
<InviteLinkBar />
|
||||||
<ConditionallyRender
|
<PermissionGuard permissions={ADMIN}>
|
||||||
condition={hasAccess(ADMIN)}
|
<UsersList />
|
||||||
show={<UsersList />}
|
</PermissionGuard>
|
||||||
elseShow={<AdminAlert />}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
|
||||||
export default UsersAdmin;
|
export default UsersAdmin;
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
import { Alert } from '@mui/material';
|
|
||||||
|
|
||||||
export const AdminAlert = () => {
|
|
||||||
return (
|
|
||||||
<Alert severity="error">
|
|
||||||
You need instance admin to access this section.
|
|
||||||
</Alert>
|
|
||||||
);
|
|
||||||
};
|
|
@ -0,0 +1,54 @@
|
|||||||
|
import { useContext } from 'react';
|
||||||
|
import { Alert, styled } from '@mui/material';
|
||||||
|
import { ADMIN } from '@server/types/permissions';
|
||||||
|
import AccessContext from 'contexts/AccessContext';
|
||||||
|
|
||||||
|
const StyledList = styled('ul')(({ theme }) => ({
|
||||||
|
paddingInlineStart: theme.spacing(2),
|
||||||
|
}));
|
||||||
|
|
||||||
|
interface IPermissionGuardProps {
|
||||||
|
permissions: string | string[];
|
||||||
|
children: JSX.Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const PermissionGuard = ({
|
||||||
|
permissions,
|
||||||
|
children,
|
||||||
|
}: IPermissionGuardProps) => {
|
||||||
|
const { hasAccess } = useContext(AccessContext);
|
||||||
|
|
||||||
|
const permissionsArray = Array.isArray(permissions)
|
||||||
|
? permissions
|
||||||
|
: [permissions];
|
||||||
|
|
||||||
|
if (!permissionsArray.includes(ADMIN)) {
|
||||||
|
permissionsArray.push(ADMIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasAccess(permissionsArray)) {
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (permissionsArray.length === 1) {
|
||||||
|
return (
|
||||||
|
<Alert severity="error">
|
||||||
|
You need the <strong>{permissionsArray[0]}</strong> permission
|
||||||
|
to access this section.
|
||||||
|
</Alert>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Alert severity="error">
|
||||||
|
You need one of the following permissions to access this section:
|
||||||
|
<StyledList>
|
||||||
|
{permissionsArray.sort().map(permission => (
|
||||||
|
<li key={permission}>
|
||||||
|
<strong>{permission}</strong>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</StyledList>
|
||||||
|
</Alert>
|
||||||
|
);
|
||||||
|
};
|
@ -1,18 +1,9 @@
|
|||||||
import React, { useContext } from 'react';
|
|
||||||
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { PermissionGuard } from 'component/common/PermissionGuard/PermissionGuard';
|
||||||
import AccessContext from 'contexts/AccessContext';
|
|
||||||
import { AdminAlert } from 'component/common/AdminAlert/AdminAlert';
|
|
||||||
import { EventLog } from 'component/events/EventLog/EventLog';
|
import { EventLog } from 'component/events/EventLog/EventLog';
|
||||||
|
|
||||||
export const EventPage = () => {
|
export const EventPage = () => (
|
||||||
const { hasAccess } = useContext(AccessContext);
|
<PermissionGuard permissions={ADMIN}>
|
||||||
|
<EventLog title="Event log" />
|
||||||
return (
|
</PermissionGuard>
|
||||||
<ConditionallyRender
|
);
|
||||||
condition={hasAccess(ADMIN)}
|
|
||||||
show={() => <EventLog title="Event log" />}
|
|
||||||
elseShow={<AdminAlert />}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
@ -1,20 +1,11 @@
|
|||||||
import { useContext } from 'react';
|
|
||||||
import AccessContext from 'contexts/AccessContext';
|
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
|
||||||
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
import { ADMIN } from 'component/providers/AccessProvider/permissions';
|
||||||
import { AdminAlert } from 'component/common/AdminAlert/AdminAlert';
|
import { PermissionGuard } from 'component/common/PermissionGuard/PermissionGuard';
|
||||||
import { LoginHistoryTable } from './LoginHistoryTable/LoginHistoryTable';
|
import { LoginHistoryTable } from './LoginHistoryTable/LoginHistoryTable';
|
||||||
|
|
||||||
export const LoginHistory = () => {
|
export const LoginHistory = () => (
|
||||||
const { hasAccess } = useContext(AccessContext);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
<div>
|
||||||
<ConditionallyRender
|
<PermissionGuard permissions={ADMIN}>
|
||||||
condition={hasAccess(ADMIN)}
|
<LoginHistoryTable />
|
||||||
show={<LoginHistoryTable />}
|
</PermissionGuard>
|
||||||
elseShow={<AdminAlert />}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
Loading…
Reference in New Issue
Block a user