mirror of https://github.com/buster-so/buster.git
restrict certain routes to admins
This commit is contained in:
parent
aa190a73de
commit
4de70a3420
|
@ -1,8 +1,8 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { SettingsEmptyState } from '../_SettingsEmptyState';
|
import { SettingsEmptyState } from '../../_components/SettingsEmptyState';
|
||||||
import { SettingsPageHeader } from '../_SettingsPageHeader';
|
import { SettingsPageHeader } from '../../_components/SettingsPageHeader';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return (
|
return (
|
|
@ -1,6 +1,6 @@
|
||||||
'use client';
|
'use client';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { SettingsPageHeader } from '../_SettingsPageHeader';
|
import { SettingsPageHeader } from '../../_components/SettingsPageHeader';
|
||||||
import { PermissionSearch, NewDatasetGroupModal } from '@appComponents/PermissionComponents';
|
import { PermissionSearch, NewDatasetGroupModal } from '@appComponents/PermissionComponents';
|
||||||
import { useDebounceSearch } from '@/hooks/useDebounceSearch';
|
import { useDebounceSearch } from '@/hooks/useDebounceSearch';
|
||||||
import { useListDatasetGroups } from '@/api/buster_rest';
|
import { useListDatasetGroups } from '@/api/buster_rest';
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { BusterRoutes, createBusterRoute } from '@/routes/busterRoutes';
|
||||||
|
import { useCheckIfUserIsAdmin_server } from '@/server_context/user';
|
||||||
|
import { redirect } from 'next/navigation';
|
||||||
|
|
||||||
|
export default async function Layout({ children }: { children: React.ReactNode }) {
|
||||||
|
const isAdmin = await useCheckIfUserIsAdmin_server();
|
||||||
|
|
||||||
|
if (!isAdmin) {
|
||||||
|
return redirect(
|
||||||
|
createBusterRoute({
|
||||||
|
route: BusterRoutes.SETTINGS_GENERAL
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <>{children}</>;
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
'use client';
|
'use client';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { SettingsPageHeader } from '../_SettingsPageHeader';
|
import { SettingsPageHeader } from '../../_components/SettingsPageHeader';
|
||||||
import { PermissionSearch, NewPermissionGroupModal } from '@appComponents/PermissionComponents';
|
import { PermissionSearch, NewPermissionGroupModal } from '@appComponents/PermissionComponents';
|
||||||
import { useDebounceSearch } from '@/hooks/useDebounceSearch';
|
import { useDebounceSearch } from '@/hooks/useDebounceSearch';
|
||||||
import { useListAllPermissionGroups } from '@/api/buster_rest';
|
import { useListAllPermissionGroups } from '@/api/buster_rest';
|
|
@ -11,7 +11,7 @@ import React, { useMemo, useState } from 'react';
|
||||||
import { Text } from '@/components/text';
|
import { Text } from '@/components/text';
|
||||||
import { OrganizationUserRoleText } from './config';
|
import { OrganizationUserRoleText } from './config';
|
||||||
import { BusterRoutes, createBusterRoute } from '@/routes';
|
import { BusterRoutes, createBusterRoute } from '@/routes';
|
||||||
import { ListUserItem } from '../../_components/ListContent';
|
import { ListUserItem } from '../../../_components/ListContent';
|
||||||
|
|
||||||
export const ListUsersComponent: React.FC<{
|
export const ListUsersComponent: React.FC<{
|
||||||
users: OrganizationUser[];
|
users: OrganizationUser[];
|
|
@ -1,7 +1,7 @@
|
||||||
import { prefetchGetUserPermissionGroups } from '@/api/buster_rest/users';
|
import { prefetchGetUserPermissionGroups } from '@/api/buster_rest/users';
|
||||||
import { HydrationBoundary, dehydrate } from '@tanstack/react-query';
|
import { HydrationBoundary, dehydrate } from '@tanstack/react-query';
|
||||||
import { UserPermissionGroupsController } from './UserPermissionGroupsController';
|
import { UserPermissionGroupsController } from './UserPermissionGroupsController';
|
||||||
import { useCheckIfUserIsAdmin_server } from '../../../../../../server_context/user';
|
import { useCheckIfUserIsAdmin_server } from '../../../../../../../server_context/user';
|
||||||
import { redirect } from 'next/navigation';
|
import { redirect } from 'next/navigation';
|
||||||
import { BusterRoutes, createBusterRoute } from '@/routes';
|
import { BusterRoutes, createBusterRoute } from '@/routes';
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { SettingsPageHeader } from '../_SettingsPageHeader';
|
import { SettingsPageHeader } from '../../_components/SettingsPageHeader';
|
||||||
import { useDebounceSearch } from '@/hooks/useDebounceSearch';
|
import { useDebounceSearch } from '@/hooks/useDebounceSearch';
|
||||||
import { useGetOrganizationUsers } from '@/api/buster_rest';
|
import { useGetOrganizationUsers } from '@/api/buster_rest';
|
||||||
import { useUserConfigContextSelector } from '@/context/Users';
|
import { useUserConfigContextSelector } from '@/context/Users';
|
||||||
import { ListUsersComponent } from './ListUsersComponent';
|
import { ListUsersComponent } from './ListUsersComponent';
|
||||||
import { PermissionSearch } from '../../_components/PermissionComponents';
|
import { PermissionSearch } from '../../../_components/PermissionComponents';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
const userOrganization = useUserConfigContextSelector((x) => x.userOrganizations);
|
const userOrganization = useUserConfigContextSelector((x) => x.userOrganizations);
|
|
@ -1,5 +1,5 @@
|
||||||
import { useCheckIfUserIsAdmin_server } from '../../../../../server_context/user';
|
import { useCheckIfUserIsAdmin_server } from '../../../../../server_context/user';
|
||||||
import { SettingsPageHeader } from '../../_SettingsPageHeader';
|
import { SettingsPageHeader } from '../../_components/SettingsPageHeader';
|
||||||
import { ApiKeysController } from './ApiKeysController';
|
import { ApiKeysController } from './ApiKeysController';
|
||||||
import { createBusterRoute, BusterRoutes } from '@/routes';
|
import { createBusterRoute, BusterRoutes } from '@/routes';
|
||||||
import { redirect } from 'next/navigation';
|
import { redirect } from 'next/navigation';
|
||||||
|
|
|
@ -1,7 +1,20 @@
|
||||||
import { SettingsEmptyState } from '../../_SettingsEmptyState';
|
import { SettingsEmptyState } from '../../_components/SettingsEmptyState';
|
||||||
import { SettingsPageHeader } from '../../_SettingsPageHeader';
|
import { SettingsPageHeader } from '../../_components/SettingsPageHeader';
|
||||||
|
import { redirect } from 'next/navigation';
|
||||||
|
import { BusterRoutes, createBusterRoute } from '@/routes/busterRoutes';
|
||||||
|
import { useCheckIfUserIsAdmin_server } from '@/server_context/user';
|
||||||
|
|
||||||
|
export default async function Page() {
|
||||||
|
const isAdmin = await useCheckIfUserIsAdmin_server();
|
||||||
|
|
||||||
|
if (!isAdmin) {
|
||||||
|
return redirect(
|
||||||
|
createBusterRoute({
|
||||||
|
route: BusterRoutes.SETTINGS_GENERAL
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default function Page() {
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<SettingsPageHeader title="Billing" description="Manage invoice, payment methods, & more" />
|
<SettingsPageHeader title="Billing" description="Manage invoice, payment methods, & more" />
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { BusterRoutes, createBusterRoute } from '@/routes';
|
import { BusterRoutes, createBusterRoute } from '@/routes';
|
||||||
import { HeaderContainer } from '../_HeaderContainer';
|
import { HeaderContainer } from '../../_HeaderContainer';
|
||||||
import { useContext, useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { DatabaseNames, DataSourceTypes, SUPPORTED_DATASOURCES } from '@/api/buster_rest';
|
import { DatabaseNames, DataSourceTypes, SUPPORTED_DATASOURCES } from '@/api/buster_rest';
|
||||||
|
|
||||||
import { AppDataSourceIcon } from '@/components/icons/AppDataSourceIcons';
|
import { AppDataSourceIcon } from '@/components/icons/AppDataSourceIcons';
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { BusterRoutes, createBusterRoute } from '@/routes/busterRoutes';
|
||||||
|
import { useCheckIfUserIsAdmin_server } from '@/server_context/user';
|
||||||
|
import { redirect } from 'next/navigation';
|
||||||
|
|
||||||
|
export default function Layout({ children }: { children: React.ReactNode }) {
|
||||||
|
const isAdmin = useCheckIfUserIsAdmin_server();
|
||||||
|
|
||||||
|
if (!isAdmin) {
|
||||||
|
return redirect(
|
||||||
|
createBusterRoute({
|
||||||
|
route: BusterRoutes.SETTINGS_DATASOURCES
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return <>{children}</>;
|
||||||
|
}
|
|
@ -13,10 +13,12 @@ import Link from 'next/link';
|
||||||
import { BusterRoutes, createBusterRoute } from '@/routes';
|
import { BusterRoutes, createBusterRoute } from '@/routes';
|
||||||
import { useMount } from 'ahooks';
|
import { useMount } from 'ahooks';
|
||||||
import { Text } from '@/components';
|
import { Text } from '@/components';
|
||||||
import { SettingsEmptyState } from '../../_SettingsEmptyState';
|
import { SettingsEmptyState } from '../../_components/SettingsEmptyState';
|
||||||
import { useAppLayoutContextSelector } from '@/context/BusterAppLayout';
|
import { useAppLayoutContextSelector } from '@/context/BusterAppLayout';
|
||||||
|
import { useUserConfigContextSelector } from '@/context/Users';
|
||||||
|
|
||||||
export const DatasourceList: React.FC = () => {
|
export const DatasourceList: React.FC = () => {
|
||||||
|
const isAdmin = useUserConfigContextSelector((state) => state.isAdmin);
|
||||||
const dataSourcesList = useDataSourceContextSelector((state) => state.dataSourcesList);
|
const dataSourcesList = useDataSourceContextSelector((state) => state.dataSourcesList);
|
||||||
const loadingDatasources = useDataSourceContextSelector((state) => state.loadingDatasources);
|
const loadingDatasources = useDataSourceContextSelector((state) => state.loadingDatasources);
|
||||||
const initDataSourceList = useDataSourceContextSelector((state) => state.initDataSourceList);
|
const initDataSourceList = useDataSourceContextSelector((state) => state.initDataSourceList);
|
||||||
|
@ -29,7 +31,7 @@ export const DatasourceList: React.FC = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col space-y-4">
|
<div className="flex flex-col space-y-4">
|
||||||
<AddSourceHeader />
|
<AddSourceHeader isAdmin={isAdmin} />
|
||||||
|
|
||||||
{loadingDatasources ? (
|
{loadingDatasources ? (
|
||||||
<SkeletonLoader />
|
<SkeletonLoader />
|
||||||
|
@ -37,6 +39,7 @@ export const DatasourceList: React.FC = () => {
|
||||||
<DataSourceItems sources={dataSourcesList} />
|
<DataSourceItems sources={dataSourcesList} />
|
||||||
) : (
|
) : (
|
||||||
<SettingsEmptyState
|
<SettingsEmptyState
|
||||||
|
showButton={isAdmin}
|
||||||
title={`You don't have any data sources yet.`}
|
title={`You don't have any data sources yet.`}
|
||||||
description={`You don’t have any datasources. As soon as you do, they will start to appear here.`}
|
description={`You don’t have any datasources. As soon as you do, they will start to appear here.`}
|
||||||
buttonText="New datasource"
|
buttonText="New datasource"
|
||||||
|
@ -52,7 +55,7 @@ export const DatasourceList: React.FC = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const AddSourceHeader: React.FC<{}> = () => {
|
const AddSourceHeader: React.FC<{ isAdmin: boolean }> = ({ isAdmin }) => {
|
||||||
return (
|
return (
|
||||||
<div className="flex w-full justify-between">
|
<div className="flex w-full justify-between">
|
||||||
<Text>Your data sources</Text>
|
<Text>Your data sources</Text>
|
||||||
|
@ -60,9 +63,11 @@ const AddSourceHeader: React.FC<{}> = () => {
|
||||||
href={createBusterRoute({
|
href={createBusterRoute({
|
||||||
route: BusterRoutes.SETTINGS_DATASOURCES_ADD
|
route: BusterRoutes.SETTINGS_DATASOURCES_ADD
|
||||||
})}>
|
})}>
|
||||||
<Button type="text" icon={<AppMaterialIcons icon="add" />}>
|
{isAdmin && (
|
||||||
New datasource
|
<Button type="text" icon={<AppMaterialIcons icon="add" />}>
|
||||||
</Button>
|
New datasource
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { AppMaterialIcons, BackButton } from '@/components';
|
import { BackButton } from '@/components';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { createStyles } from 'antd-style';
|
import { createStyles } from 'antd-style';
|
||||||
import Link from 'next/link';
|
|
||||||
import { Text } from '@/components';
|
|
||||||
|
|
||||||
const useStyles = createStyles(({ css, token }) => ({
|
const useStyles = createStyles(({ css, token }) => ({
|
||||||
icon: {
|
icon: {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Divider } from 'antd';
|
|
||||||
import { DatasourceList } from './_DatasourceList';
|
import { DatasourceList } from './_DatasourceList';
|
||||||
import { SettingsPageHeader } from '../../_SettingsPageHeader';
|
import { SettingsPageHeader } from '../../_components/SettingsPageHeader';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { SettingsEmptyState } from '../../_SettingsEmptyState';
|
import { SettingsEmptyState } from '../../_components/SettingsEmptyState';
|
||||||
import { SettingsPageHeader } from '../../_SettingsPageHeader';
|
import { SettingsPageHeader } from '../../_components/SettingsPageHeader';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { SettingsEmptyState } from '../../_SettingsEmptyState';
|
import { SettingsEmptyState } from '../../_components/SettingsEmptyState';
|
||||||
import { SettingsPageHeader } from '../../_SettingsPageHeader';
|
import { SettingsPageHeader } from '../../_components/SettingsPageHeader';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { SettingsEmptyState } from '../../_SettingsEmptyState';
|
import { SettingsEmptyState } from '../../_components/SettingsEmptyState';
|
||||||
import { SettingsPageHeader } from '../../_SettingsPageHeader';
|
import { SettingsPageHeader } from '../../_components/SettingsPageHeader';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { SettingsEmptyState } from '../../_SettingsEmptyState';
|
import { SettingsEmptyState } from '../../_components/SettingsEmptyState';
|
||||||
import { SettingsPageHeader } from '../../_SettingsPageHeader';
|
import { SettingsPageHeader } from '../../_components/SettingsPageHeader';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { SettingsEmptyState } from '../../_SettingsEmptyState';
|
import { SettingsEmptyState } from '../../_components/SettingsEmptyState';
|
||||||
import { SettingsPageHeader } from '../../_SettingsPageHeader';
|
import { SettingsPageHeader } from '../../_components/SettingsPageHeader';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { SettingsEmptyState } from '../../_SettingsEmptyState';
|
import { SettingsEmptyState } from '../../_components/SettingsEmptyState';
|
||||||
import { SettingsPageHeader } from '../../_SettingsPageHeader';
|
import { SettingsPageHeader } from '../../_components/SettingsPageHeader';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return (
|
return (
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue