+ client: add whois info to dashboard and logs

This commit is contained in:
Ildar Kamalov 2019-09-23 16:02:47 +03:00
parent 9e4f80f3c1
commit a52715e086
6 changed files with 86 additions and 46 deletions

View File

@ -6,8 +6,9 @@ import { Trans, withNamespaces } from 'react-i18next';
import Card from '../ui/Card'; import Card from '../ui/Card';
import Cell from '../ui/Cell'; import Cell from '../ui/Cell';
import { getPercent, getClientName } from '../../helpers/helpers'; import { getPercent } from '../../helpers/helpers';
import { STATUS_COLORS } from '../../helpers/constants'; import { STATUS_COLORS } from '../../helpers/constants';
import { formatClientCell } from '../../helpers/formatClientCell';
const getClientsPercentColor = (percent) => { const getClientsPercentColor = (percent) => {
if (percent > 50) { if (percent > 50) {
@ -18,31 +19,6 @@ const getClientsPercentColor = (percent) => {
return STATUS_COLORS.red; return STATUS_COLORS.red;
}; };
const ipCell = (clients, autoClients) =>
function cell(row) {
let client;
const { value } = row;
const clientName = getClientName(clients, value) || getClientName(autoClients, value);
if (clientName) {
client = (
<span>
{clientName} <small>({value})</small>
</span>
);
} else {
client = value;
}
return (
<div className="logs__row logs__row--overflow">
<span className="logs__text" title={value}>
{client}
</span>
</div>
);
};
const countCell = dnsQueries => const countCell = dnsQueries =>
function cell(row) { function cell(row) {
const { value } = row; const { value } = row;
@ -52,6 +28,17 @@ const countCell = dnsQueries =>
return <Cell value={value} percent={percent} color={percentColor} />; return <Cell value={value} percent={percent} color={percentColor} />;
}; };
const clientCell = (clients, autoClients) =>
function cell(row) {
const { value } = row;
return (
<div className="logs__row logs__row--overflow logs__row--column">
{formatClientCell(value, clients, autoClients)}
</div>
);
};
const Clients = ({ const Clients = ({
t, refreshButton, topClients, subtitle, clients, autoClients, dnsQueries, t, refreshButton, topClients, subtitle, clients, autoClients, dnsQueries,
}) => ( }) => (
@ -72,7 +59,7 @@ const Clients = ({
accessor: 'ip', accessor: 'ip',
sortMethod: (a, b) => sortMethod: (a, b) =>
parseInt(a.replace(/\./g, ''), 10) - parseInt(b.replace(/\./g, ''), 10), parseInt(a.replace(/\./g, ''), 10) - parseInt(b.replace(/\./g, ''), 10),
Cell: ipCell(clients, autoClients), Cell: clientCell(clients, autoClients),
}, },
{ {
Header: <Trans>requests_count</Trans>, Header: <Trans>requests_count</Trans>,

View File

@ -10,8 +10,9 @@
} }
.logs__row--column { .logs__row--column {
align-items: flex-start;
flex-direction: column; flex-direction: column;
align-items: flex-start;
justify-content: center;
} }
.logs__row--overflow { .logs__row--overflow {
@ -41,6 +42,7 @@
} }
.logs__text--wrap { .logs__text--wrap {
line-height: 1.4;
white-space: normal; white-space: normal;
} }

View File

@ -6,9 +6,11 @@ import endsWith from 'lodash/endsWith';
import { Trans, withNamespaces } from 'react-i18next'; import { Trans, withNamespaces } from 'react-i18next';
import { HashLink as Link } from 'react-router-hash-link'; import { HashLink as Link } from 'react-router-hash-link';
import { formatTime, formatDateTime, getClientName } from '../../helpers/helpers'; import { formatTime, formatDateTime } from '../../helpers/helpers';
import { SERVICES, FILTERED_STATUS } from '../../helpers/constants'; import { SERVICES, FILTERED_STATUS } from '../../helpers/constants';
import { getTrackerData } from '../../helpers/trackers/trackers'; import { getTrackerData } from '../../helpers/trackers/trackers';
import { formatClientCell } from '../../helpers/formatClientCell';
import PageTitle from '../ui/PageTitle'; import PageTitle from '../ui/PageTitle';
import Card from '../ui/Card'; import Card from '../ui/Card';
import Loading from '../ui/Loading'; import Loading from '../ui/Loading';
@ -190,24 +192,16 @@ class Logs extends Component {
getClientCell = ({ original, value }) => { getClientCell = ({ original, value }) => {
const { dashboard } = this.props; const { dashboard } = this.props;
const { clients, autoClients } = dashboard;
const { reason, domain } = original; const { reason, domain } = original;
const isFiltered = this.checkFiltered(reason); const isFiltered = this.checkFiltered(reason);
const isRewrite = this.checkRewrite(reason); const isRewrite = this.checkRewrite(reason);
const clientName =
getClientName(dashboard.clients, value) || getClientName(dashboard.autoClients, value);
let client = value;
if (clientName) {
client = (
<span>
{clientName} <small>({value})</small>
</span>
);
}
return ( return (
<Fragment> <Fragment>
<div className="logs__row">{client}</div> <div className="logs__row logs__row--overflow logs__row--column">
{formatClientCell(value, clients, autoClients)}
</div>
{isRewrite ? ( {isRewrite ? (
<div className="logs__action"> <div className="logs__action">
<Link to="/dns#rewrites" className="btn btn-sm btn-outline-primary"> <Link to="/dns#rewrites" className="btn btn-sm btn-outline-primary">
@ -273,8 +267,8 @@ class Logs extends Component {
{ {
Header: t('client_table_header'), Header: t('client_table_header'),
accessor: 'client', accessor: 'client',
maxWidth: 220, maxWidth: 240,
minWidth: 220, minWidth: 240,
Cell: this.getClientCell, Cell: this.getClientCell,
}, },
]; ];

View File

@ -128,7 +128,7 @@ class ClientsTable extends Component {
{ {
Header: this.props.t('blocked_services'), Header: this.props.t('blocked_services'),
accessor: 'blocked_services', accessor: 'blocked_services',
minWidth: 210, minWidth: 180,
Cell: (row) => { Cell: (row) => {
const { value, original } = row; const { value, original } = row;
@ -156,6 +156,7 @@ class ClientsTable extends Component {
{ {
Header: this.props.t('requests_count'), Header: this.props.t('requests_count'),
accessor: 'statistics', accessor: 'statistics',
minWidth: 120,
Cell: (row) => { Cell: (row) => {
const clientIP = row.original.ip; const clientIP = row.original.ip;
const clientStats = clientIP && this.getStats(clientIP, this.props.topClients); const clientStats = clientIP && this.getStats(clientIP, this.props.topClients);

View File

@ -0,0 +1,32 @@
import React, { Fragment } from 'react';
import { getClientInfo } from './helpers';
export const formatClientCell = (value, clients, autoClients) => {
const clientInfo = getClientInfo(clients, value) || getClientInfo(autoClients, value);
const { name, whois } = clientInfo;
if (whois && name) {
return (
<Fragment>
<div className="logs__text logs__text--wrap" title={`${name} (${value})`}>
{name} <small className="text-muted-dark">({value})</small>
</div>
<div className="logs__text logs__text--wrap" title={whois}>
<small className="text-muted">{whois}</small>
</div>
</Fragment>
);
} else if (name) {
return (
<span className="logs__text logs__text--wrap" title={`${name} (${value})`}>
{name} <small>({value})</small>
</span>
);
}
return (
<span className="logs__text" title={value}>
{value}
</span>
);
};

View File

@ -245,9 +245,33 @@ export const redirectToCurrentProtocol = (values, httpPort = 80) => {
export const normalizeTextarea = text => text && text.replace(/[;, ]/g, '\n').split('\n').filter(n => n); export const normalizeTextarea = text => text && text.replace(/[;, ]/g, '\n').split('\n').filter(n => n);
export const getClientName = (clients, ip) => { const formatWhois = (whois) => {
if (!whois) {
return '';
}
const keys = Object.keys(whois);
if (keys.length > 0) {
return (
keys.map(key => whois[key])
);
}
return '';
};
export const getClientInfo = (clients, ip) => {
const client = clients.find(item => ip === item.ip); const client = clients.find(item => ip === item.ip);
return (client && client.name) || '';
if (!client) {
return '';
}
const { name, whois_info } = client;
const formattedWhois = formatWhois(whois_info);
const whois = formattedWhois && formattedWhois.length > 0 && formattedWhois.join(' | ');
return { name, whois };
}; };
export const sortClients = (clients) => { export const sortClients = (clients) => {