Skip to content

Commit

Permalink
Add basic cidr range player query
Browse files Browse the repository at this point in the history
  • Loading branch information
leighmacdonald committed Mar 31, 2024
1 parent a31b350 commit 1c27667
Show file tree
Hide file tree
Showing 18 changed files with 440 additions and 392 deletions.
4 changes: 3 additions & 1 deletion docker/docker-compose-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ services:
command: ./gbans serve

postgres:
image: postgis/postgis:15-3.3
build:
context: "."
dockerfile: postgres-ip4r.Dockerfile
restart: always
shm_size: 1gb
ports:
Expand Down
7 changes: 7 additions & 0 deletions docker/postgres-ip4r.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM postgres:15-bullseye

RUN apt-get update \
&& apt-cache showpkg postgresql-$PG_MAJOR-ip4r \
&& apt-get install -y --no-install-recommends \
postgresql-$PG_MAJOR-ip4r \
&& rm -rf /var/lib/apt/lists/*
37 changes: 11 additions & 26 deletions frontend/src/api/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,38 +231,23 @@ export const apiGetNotifications = async (
);
};

export type PersonConnectionQuery = {
cidr?: string;
source_id?: string;
server_id?: number;
asn?: number;
} & QueryFilter<PersonConnection>;

export type PersonConnectionSteamIDQuery = {
export type ConnectionQuery = {
cidr: string;
source_id: string;
server_id?: number;
asn: number;
} & QueryFilter<PersonConnection>;

export const apiGetConnections = async (
opts: PersonConnectionQuery,
abortController: AbortController
) => {
const resp = await apiCall<
LazyResult<PersonConnection>,
PersonConnectionQuery
>(`/api/connections`, 'POST', opts, abortController);

resp.data = resp.data.map(transformCreatedOnDate);
return resp;
};

export const apiGetConnectionsSteam = async (
opts: PersonConnectionSteamIDQuery,
opts: ConnectionQuery,
abortController: AbortController
) => {
const resp = await apiCall<
LazyResult<PersonConnection>,
PersonConnectionQuery
>(`/api/connections/steam`, 'POST', opts, abortController);
const resp = await apiCall<LazyResult<PersonConnection>, ConnectionQuery>(
`/api/connections`,
'POST',
opts,
abortController
);

resp.data = resp.data.map(transformCreatedOnDate);
return resp;
Expand Down
171 changes: 171 additions & 0 deletions frontend/src/component/FindPlayerByIP.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
import { ChangeEvent, useState } from 'react';
import SearchIcon from '@mui/icons-material/Search';
import Tooltip from '@mui/material/Tooltip';
import Typography from '@mui/material/Typography';
import Grid from '@mui/material/Unstable_Grid2';
import { Formik } from 'formik';
import { PersonConnection } from '../api';
import { useConnections } from '../hooks/useConnections.ts';
import { Order, RowsPerPage } from '../util/table.ts';
import { renderDateTime } from '../util/text.tsx';
import { LoadingPlaceholder } from './LoadingPlaceholder.tsx';
import {
CIDRInputFieldProps,
NetworkRangeField
} from './formik/NetworkRangeField.tsx';
import { SubmitButton } from './modal/Buttons.tsx';
import { LazyTable } from './table/LazyTable.tsx';

export const FindPlayerByIP = () => {
const [sortOrder, setSortOrder] = useState<Order>('desc');
const [sortColumn, setSortColumn] =
useState<keyof PersonConnection>('created_on');
const [rowPerPageCount, setRowPerPageCount] = useState<number>(
RowsPerPage.Ten
);
const [cidr, setCIDR] = useState('');
const [page, setPage] = useState(0);

const {
data: rows,
count,
loading
} = useConnections({
limit: rowPerPageCount,
offset: page * rowPerPageCount,
desc: sortOrder == 'desc',
order_by: sortColumn,
cidr: cidr,
asn: 0,
source_id: ''
});

const onSubmit = (values: CIDRInputFieldProps) => {
setCIDR(values.cidr);
};

return (
<Grid container>
<Grid xs={12}>
<Formik onSubmit={onSubmit} initialValues={{ cidr: '' }}>
<Grid
container
direction="row"
alignItems="top"
justifyContent="center"
spacing={2}
>
<Grid xs>
<NetworkRangeField />
</Grid>
<Grid xs={2}>
<SubmitButton
label={'Submit'}
fullWidth
disabled={loading}
startIcon={<SearchIcon />}
/>
</Grid>
</Grid>
</Formik>
</Grid>
<Grid xs={12}>
{loading ? (
<LoadingPlaceholder />
) : (
<LazyTable<PersonConnection>
showPager={true}
count={count}
rows={rows}
page={page}
rowsPerPage={rowPerPageCount}
sortOrder={sortOrder}
sortColumn={sortColumn}
onSortColumnChanged={async (column) => {
setSortColumn(column);
}}
onSortOrderChanged={async (direction) => {
setSortOrder(direction);
}}
onPageChange={(_, newPage: number) => {
setPage(newPage);
}}
onRowsPerPageChange={(
event: ChangeEvent<
HTMLInputElement | HTMLTextAreaElement
>
) => {
setRowPerPageCount(
parseInt(event.target.value, 10)
);
setPage(0);
}}
columns={[
{
label: 'Created',
tooltip: 'Created On',
sortKey: 'created_on',
sortType: 'date',
align: 'left',
width: '150px',
sortable: true,
renderer: (obj: PersonConnection) => (
<Typography variant={'body1'}>
{renderDateTime(obj.created_on)}
</Typography>
)
},
{
label: 'Name',
tooltip: 'Name',
sortKey: 'persona_name',
sortType: 'string',
align: 'left',
width: '200px',
sortable: true
},
{
label: 'SteamID',
tooltip: 'Name',
sortKey: 'steam_id',
sortType: 'string',
align: 'left',
width: '200px',
sortable: true
},
{
label: 'IP Address',
tooltip: 'IP Address',
sortKey: 'ip_addr',
sortType: 'string',
align: 'left',
width: '150px',
sortable: true
},
{
label: 'Server',
tooltip: 'IP Address',
sortKey: 'ip_addr',
sortType: 'string',
align: 'left',
sortable: true,
renderer: (obj: PersonConnection) => {
return (
<Tooltip
title={obj.server_name ?? 'Unknown'}
>
<Typography variant={'body1'}>
{obj.server_name_short ??
'Unknown'}
</Typography>
</Tooltip>
);
}
}
]}
/>
)}
</Grid>
</Grid>
);
};
104 changes: 104 additions & 0 deletions frontend/src/component/FindPlayerIPs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { ChangeEvent, useState } from 'react';
import SearchIcon from '@mui/icons-material/Search';
import Grid from '@mui/material/Unstable_Grid2';
import { Formik } from 'formik';
import { PersonConnection } from '../api';
import { useConnections } from '../hooks/useConnections.ts';
import { Order, RowsPerPage } from '../util/table.ts';
import { LoadingPlaceholder } from './LoadingPlaceholder.tsx';
import { TargetIDField, TargetIDInputValue } from './formik/TargetIdField.tsx';
import { SubmitButton } from './modal/Buttons.tsx';
import { LazyTable } from './table/LazyTable.tsx';
import { connectionColumns } from './table/connectionColumns.tsx';

export const FindPlayerIPs = () => {
const [sortOrder, setSortOrder] = useState<Order>('desc');
const [sortColumn, setSortColumn] =
useState<keyof PersonConnection>('created_on');
const [rowPerPageCount, setRowPerPageCount] = useState<number>(
RowsPerPage.Ten
);
const [steamID, setSteamID] = useState('');
const [page, setPage] = useState(0);

const {
data: rows,
count,
loading
} = useConnections({
limit: rowPerPageCount,
offset: page * rowPerPageCount,
desc: sortOrder == 'desc',
order_by: sortColumn,
source_id: steamID,
asn: 0,
cidr: ''
});

const onSubmit = (values: TargetIDInputValue) => {
setSteamID(values.target_id);
};

return (
<Grid container spacing={2}>
<Grid xs={12}>
<Formik onSubmit={onSubmit} initialValues={{ target_id: '' }}>
<Grid
container
direction="row"
alignItems="top"
justifyContent="center"
spacing={2}
>
<Grid xs>
<TargetIDField />
</Grid>
<Grid xs={2}>
<SubmitButton
label={'Submit'}
fullWidth
disabled={loading}
startIcon={<SearchIcon />}
/>
</Grid>
</Grid>
</Formik>
</Grid>
<Grid xs={12}>
{loading ? (
<LoadingPlaceholder />
) : (
<LazyTable<PersonConnection>
showPager={true}
count={count}
rows={rows}
page={page}
rowsPerPage={rowPerPageCount}
sortOrder={sortOrder}
sortColumn={sortColumn}
onSortColumnChanged={async (column) => {
setSortColumn(column);
}}
onSortOrderChanged={async (direction) => {
setSortOrder(direction);
}}
onPageChange={(_, newPage: number) => {
setPage(newPage);
}}
onRowsPerPageChange={(
event: ChangeEvent<
HTMLInputElement | HTMLTextAreaElement
>
) => {
setRowPerPageCount(
parseInt(event.target.value, 10)
);
setPage(0);
}}
columns={connectionColumns}
/>
)}
</Grid>
</Grid>
);
};
4 changes: 2 additions & 2 deletions frontend/src/component/table/ConnectionHistoryTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ChangeEvent, useEffect, useState } from 'react';
import {
apiGetConnections,
PersonConnection,
PersonConnectionQuery
ConnectionQuery
} from '../../api';
import { logErr } from '../../util/errors';
import { Order, RowsPerPage } from '../../util/table.ts';
Expand All @@ -25,7 +25,7 @@ export const ConnectionHistoryTable = ({ steam_id }: { steam_id?: string }) => {

useEffect(() => {
const abortController = new AbortController();
const opts: PersonConnectionQuery = {
const opts: ConnectionQuery = {
limit: rowPerPageCount,
offset: page * rowPerPageCount,
order_by: sortColumn,
Expand Down
Loading

0 comments on commit 1c27667

Please sign in to comment.