Merge: - client: block/unblock client without requesting stats

Closes #896

Squashed commit of the following:

commit 66b781438aa668a16b19455c3e0dc5100417d869
Author: Ildar Kamalov <i.kamalov@adguard.com>
Date:   Mon Feb 3 12:59:25 2020 +0300

    - client: block/unblock client without requesting stats

commit e70f62738d549e32339bae3d5e996a912b99c21d
Author: Ildar Kamalov <i.kamalov@adguard.com>
Date:   Mon Feb 3 12:22:13 2020 +0300

    - client: get current access settings before set

commit 65c59d1d55f3255f33f917b61b6ab2c6c2e54271
Author: Ildar Kamalov <i.kamalov@adguard.com>
Date:   Mon Feb 3 12:21:12 2020 +0300

    * client: mode svg-url-loader to devDependencies
This commit is contained in:
Ildar Kamalov
2020-02-04 15:48:07 +03:00
parent d4069f824a
commit a5c2ad1b2f
8 changed files with 63 additions and 45 deletions

View File

@@ -3,7 +3,6 @@ import { t } from 'i18next';
import apiClient from '../api/Api';
import { addErrorToast, addSuccessToast } from './index';
import { getStats, getStatsConfig } from './stats';
import { normalizeTextarea } from '../helpers/helpers';
import { ACTION } from '../helpers/constants';
@@ -50,11 +49,13 @@ export const toggleClientBlockRequest = createAction('TOGGLE_CLIENT_BLOCK_REQUES
export const toggleClientBlockFailure = createAction('TOGGLE_CLIENT_BLOCK_FAILURE');
export const toggleClientBlockSuccess = createAction('TOGGLE_CLIENT_BLOCK_SUCCESS');
export const toggleClientBlock = (type, ip) => async (dispatch, getState) => {
export const toggleClientBlock = (type, ip) => async (dispatch) => {
dispatch(toggleClientBlockRequest());
try {
const { allowed_clients, disallowed_clients, blocked_hosts } = getState().access;
let updatedDisallowedClients = normalizeTextarea(disallowed_clients);
const {
allowed_clients, disallowed_clients, blocked_hosts,
} = await apiClient.getAccessList();
let updatedDisallowedClients = disallowed_clients;
if (type === ACTION.unblock && updatedDisallowedClients.includes(ip)) {
updatedDisallowedClients = updatedDisallowedClients.filter(client => client !== ip);
@@ -63,23 +64,19 @@ export const toggleClientBlock = (type, ip) => async (dispatch, getState) => {
}
const values = {
allowed_clients: normalizeTextarea(allowed_clients),
blocked_hosts: normalizeTextarea(blocked_hosts),
allowed_clients,
blocked_hosts,
disallowed_clients: updatedDisallowedClients,
};
await apiClient.setAccessList(values);
dispatch(toggleClientBlockSuccess());
dispatch(toggleClientBlockSuccess(values));
if (type === ACTION.unblock) {
dispatch(addSuccessToast(t('client_unblocked', { ip })));
} else if (type === ACTION.block) {
dispatch(addSuccessToast(t('client_blocked', { ip })));
}
dispatch(getStats());
dispatch(getStatsConfig());
dispatch(getAccessList());
} catch (error) {
dispatch(addErrorToast({ error }));
dispatch(toggleClientBlockFailure());

View File

@@ -2,7 +2,7 @@ import { createAction } from 'redux-actions';
import apiClient from '../api/Api';
import { addErrorToast, addSuccessToast } from './index';
import { normalizeTopStats, secondsToMilliseconds, getParamsForClientsSearch, addClientInfo, addClientStatus } from '../helpers/helpers';
import { normalizeTopStats, secondsToMilliseconds, getParamsForClientsSearch, addClientInfo } from '../helpers/helpers';
export const getStatsConfigRequest = createAction('GET_STATS_CONFIG_REQUEST');
export const getStatsConfigFailure = createAction('GET_STATS_CONFIG_FAILURE');
@@ -46,15 +46,12 @@ export const getStats = () => async (dispatch) => {
const normalizedTopClients = normalizeTopStats(stats.top_clients);
const clientsParams = getParamsForClientsSearch(normalizedTopClients, 'name');
const clients = await apiClient.findClients(clientsParams);
const accessData = await apiClient.getAccessList();
const { disallowed_clients } = accessData;
const topClientsWithInfo = addClientInfo(normalizedTopClients, clients, 'name');
const topClientsWithStatus = addClientStatus(topClientsWithInfo, disallowed_clients, 'name');
const normalizedStats = {
...stats,
top_blocked_domains: normalizeTopStats(stats.top_blocked_domains),
top_clients: topClientsWithStatus,
top_clients: topClientsWithInfo,
top_queried_domains: normalizeTopStats(stats.top_queried_domains),
avg_processing_time: secondsToMilliseconds(stats.avg_processing_time),
};

View File

@@ -57,10 +57,12 @@ const renderBlockingButton = (blocked, ip, handleClick, processing) => {
);
};
const clientCell = (t, toggleClientStatus, processing) =>
const isBlockedClient = (clients, ip) => !!(clients && clients.includes(ip));
const clientCell = (t, toggleClientStatus, processing, disallowedClients) =>
function cell(row) {
const { original, value } = row;
const { blocked } = original;
const { value } = row;
const blocked = isBlockedClient(disallowedClients, value);
return (
<Fragment>
@@ -80,6 +82,7 @@ const Clients = ({
dnsQueries,
toggleClientStatus,
processingAccessSet,
disallowedClients,
}) => (
<Card
title={t('top_clients')}
@@ -102,7 +105,7 @@ const Clients = ({
accessor: 'ip',
sortMethod: (a, b) =>
parseInt(a.replace(/\./g, ''), 10) - parseInt(b.replace(/\./g, ''), 10),
Cell: clientCell(t, toggleClientStatus, processingAccessSet),
Cell: clientCell(t, toggleClientStatus, processingAccessSet, disallowedClients),
},
{
Header: <Trans>requests_count</Trans>,
@@ -122,9 +125,9 @@ const Clients = ({
return {};
}
const { blocked } = rowInfo.original;
const { ip } = rowInfo.original;
if (blocked) {
if (isBlockedClient(disallowedClients, ip)) {
return {
className: 'red',
};
@@ -148,6 +151,7 @@ Clients.propTypes = {
t: PropTypes.func.isRequired,
toggleClientStatus: PropTypes.func.isRequired,
processingAccessSet: PropTypes.bool.isRequired,
disallowedClients: PropTypes.string.isRequired,
};
export default withNamespaces()(Clients);

View File

@@ -19,6 +19,7 @@ class Dashboard extends Component {
}
getAllStats = () => {
this.props.getAccessList();
this.props.getStats();
this.props.getStatsConfig();
};
@@ -53,7 +54,8 @@ class Dashboard extends Component {
dashboard, stats, access, t,
} = this.props;
const statsProcessing = stats.processingStats
|| stats.processingGetConfig;
|| stats.processingGetConfig
|| access.processing;
const subtitle =
stats.interval === 1
@@ -130,6 +132,7 @@ class Dashboard extends Component {
refreshButton={refreshButton}
toggleClientStatus={this.toggleClientStatus}
processingAccessSet={access.processingSet}
disallowedClients={access.disallowed_clients}
/>
</div>
<div className="col-lg-6">

View File

@@ -122,17 +122,6 @@ export const addClientInfo = (data, clients, param) => (
})
);
export const addClientStatus = (data, disallowedClients, param) => (
data.map((row) => {
const clientIp = row[param];
const blocked = !!(disallowedClients && disallowedClients.includes(clientIp));
return {
...row,
blocked,
};
})
);
export const normalizeFilteringStatus = (filteringStatus) => {
const {
enabled, filters, user_rules: userRules, interval,

View File

@@ -34,7 +34,21 @@ const access = handleActions(
[actions.toggleClientBlockRequest]: state => ({ ...state, processingSet: true }),
[actions.toggleClientBlockFailure]: state => ({ ...state, processingSet: false }),
[actions.toggleClientBlockSuccess]: state => ({ ...state, processingSet: false }),
[actions.toggleClientBlockSuccess]: (state, { payload }) => {
const {
allowed_clients,
disallowed_clients,
blocked_hosts,
} = payload;
const newState = {
...state,
allowed_clients: (allowed_clients && allowed_clients.join('\n')) || '',
disallowed_clients: (disallowed_clients && disallowed_clients.join('\n')) || '',
blocked_hosts: (blocked_hosts && blocked_hosts.join('\n')) || '',
processingSet: false,
};
return newState;
},
},
{
processing: true,