+ client: Move the client access check to the server-side

Squashed commit of the following:

commit 1aab0f62e94ce665a1b996552fac41dc4e769b4d
Merge: cdf5eb6e c1f5fdae
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Thu Sep 24 15:36:05 2020 +0300

    Merge branch '1920-client-find' into feature/1925

commit cdf5eb6ea67a665d21a3155d8cf89bba9a5a9948
Merge: b6c20b1c 10f67bd3
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Wed Sep 23 20:28:51 2020 +0300

    Merge branch 'master' into feature/1925

commit b6c20b1c7359a0e5902405b0551712f936848a80
Merge: 97d388ef 96512433
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Sep 15 10:44:25 2020 +0300

    Merge branch 'master' into feature/1925

commit 97d388ef6571d590f21da00f86d889e881ca0c3d
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Sep 15 10:30:50 2020 +0300

    Extract buttons

commit ca45fde11fc2b2812ff2b84dbd67aff0b5341be1
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Thu Sep 10 12:46:09 2020 +0300

    Handle errors in updateLogs

commit f15e03c2e5a7115db984f70f72b0ddd870ece73d
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Thu Sep 10 12:39:34 2020 +0300

    Update mobile block status on click

commit 033b28db3b324f6d529ac1a0ef657886cdbe02bd
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Wed Sep 9 20:53:42 2020 +0300

    Fix mobile block buttons, auto open page on web serve start

commit 2730937b23309167a066b9154728ac53ffe81a49
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Wed Sep 9 13:58:37 2020 +0300

    Disable allow this client button when isNotInAllowedList is true

commit 818cf869d63654c184762ad2701c4429a3e3011e
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Wed Sep 9 13:06:01 2020 +0300

    Update client block state on option click

commit a072b8983757f419645c0207ea78e6e867c440cb
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Sep 8 20:17:16 2020 +0300

    Adapt to api changes

commit 28ab2bd8b3f14f60bc822b5a69fa1801db67d816
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Sep 8 14:12:20 2020 +0300

    Change query log block confirm messages

commit 9b0b6f6f9b1ec168fa71dbedd036152da59006e3
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Sep 8 12:00:46 2020 +0300

    Refactor inner work with disallowed

commit 05f76154b8f489738d032fdaa835edb371ce70c7
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Mon Sep 7 16:11:37 2020 +0300

    + client: Move the client access check to the server-side
This commit is contained in:
Artem Baskal
2020-09-24 15:48:37 +03:00
parent c1f5fdaee4
commit c72cd58f69
13 changed files with 175 additions and 380 deletions

View File

@@ -11,12 +11,16 @@ import IconTooltip from './IconTooltip';
import { renderFormattedClientCell } from '../../../helpers/renderFormattedClientCell';
import { toggleClientBlock } from '../../../actions/access';
import { getBlockClientInfo } from './helpers';
import { getStats } from '../../../actions/stats';
import { updateLogs } from '../../../actions/queryLogs';
const ClientCell = ({
client,
domain,
info,
info: { name, whois_info },
info: {
name, whois_info, disallowed, disallowed_rule,
},
reason,
}) => {
const { t } = useTranslation();
@@ -26,11 +30,6 @@ const ClientCell = ({
const isDetailed = useSelector((state) => state.queryLogs.isDetailed);
const [isOptionsOpened, setOptionsOpened] = useState(false);
const disallowed_clients = useSelector(
(state) => state.access.disallowed_clients,
shallowEqual,
);
const autoClient = autoClients.find((autoClient) => autoClient.name === client);
const source = autoClient?.source;
const whoisAvailable = whois_info && Object.keys(whois_info).length > 0;
@@ -66,43 +65,50 @@ const ClientCell = ({
const {
confirmMessage,
buttonKey: blockingClientKey,
type,
} = getBlockClientInfo(client, disallowed_clients);
isNotInAllowedList,
} = getBlockClientInfo(client, disallowed, disallowed_rule);
const blockingForClientKey = isFiltered ? 'unblock_for_this_client_only' : 'block_for_this_client_only';
const clientNameBlockingFor = getBlockingClientName(clients, client);
const BUTTON_OPTIONS_TO_ACTION_MAP = {
[blockingForClientKey]: () => {
dispatch(toggleBlockingForClient(buttonType, domain, clientNameBlockingFor));
const BUTTON_OPTIONS = [
{
name: blockingForClientKey,
onClick: () => {
dispatch(toggleBlockingForClient(buttonType, domain, clientNameBlockingFor));
},
},
[blockingClientKey]: () => {
const message = `${type === BLOCK_ACTIONS.BLOCK ? t('adg_will_drop_dns_queries') : ''} ${t(confirmMessage, { ip: client })}`;
if (window.confirm(message)) {
dispatch(toggleClientBlock(type, client));
}
{
name: blockingClientKey,
onClick: async () => {
if (window.confirm(confirmMessage)) {
await dispatch(toggleClientBlock(client, disallowed, disallowed_rule));
await dispatch(updateLogs());
}
},
disabled: isNotInAllowedList,
},
};
];
const onClick = async () => {
await dispatch(toggleBlocking(buttonType, domain));
await dispatch(getStats());
};
const getOptions = (optionToActionMap) => {
const options = Object.entries(optionToActionMap);
const getOptions = (options) => {
if (options.length === 0) {
return null;
}
return <>{options
.map(([name, onClick]) => <div
return <>{options.map(({ name, onClick, disabled }) => <button
key={name}
className="button-action--arrow-option px-4 py-2"
onClick={onClick}
disabled={disabled}
>{t(name)}
</div>)}</>;
</button>)}</>;
};
const content = getOptions(BUTTON_OPTIONS_TO_ACTION_MAP);
const content = getOptions(BUTTON_OPTIONS);
const buttonClass = classNames('button-action button-action--main', {
'button-action--unblock': isFiltered,
@@ -168,6 +174,8 @@ ClientCell.propTypes = {
city: propTypes.string,
orgname: propTypes.string,
}),
disallowed: propTypes.bool.isRequired,
disallowed_rule: propTypes.string.isRequired,
}),
]),
reason: propTypes.string.isRequired,

View File

@@ -1,19 +1,18 @@
import { getIpMatchListStatus } from '../../../../helpers/helpers';
import { BLOCK_ACTIONS, IP_MATCH_LIST_STATUS } from '../../../../helpers/constants';
import i18next from 'i18next';
export const BUTTON_PREFIX = 'btn_';
export const getBlockClientInfo = (client, disallowed_clients) => {
const ipMatchListStatus = getIpMatchListStatus(client, disallowed_clients);
export const getBlockClientInfo = (ip, disallowed, disallowed_rule) => {
const confirmMessage = disallowed
? i18next.t('client_confirm_unblock', { ip: disallowed_rule })
: `${i18next.t('adg_will_drop_dns_queries')} ${i18next.t('client_confirm_block', { ip })}`;
const isNotFound = ipMatchListStatus === IP_MATCH_LIST_STATUS.NOT_FOUND;
const type = isNotFound ? BLOCK_ACTIONS.BLOCK : BLOCK_ACTIONS.UNBLOCK;
const buttonKey = i18next.t(disallowed ? 'allow_this_client' : 'disallow_this_client');
const isNotInAllowedList = disallowed && disallowed_rule === '';
const confirmMessage = isNotFound ? 'client_confirm_block' : 'client_confirm_unblock';
const buttonKey = isNotFound ? 'disallow_this_client' : 'allow_this_client';
return {
confirmMessage,
buttonKey,
type,
isNotInAllowedList,
};
};

View File

@@ -32,6 +32,7 @@ import ClientCell from './ClientCell';
import '../Logs.css';
import { toggleClientBlock } from '../../../actions/access';
import { getBlockClientInfo, BUTTON_PREFIX } from './helpers';
import { updateLogs } from '../../../actions/queryLogs';
const Row = memo(({
style,
@@ -49,21 +50,19 @@ const Row = memo(({
const whitelistFilters = useSelector((state) => state.filtering.whitelistFilters, shallowEqual);
const autoClients = useSelector((state) => state.dashboard.autoClients, shallowEqual);
const disallowed_clients = useSelector(
(state) => state.access.disallowed_clients,
shallowEqual,
);
const clients = useSelector((state) => state.dashboard.clients);
const onClick = () => {
if (!isSmallScreen) { return; }
if (!isSmallScreen) {
return;
}
const {
answer_dnssec,
client,
domain,
elapsedMs,
info,
info: { disallowed, disallowed_rule },
reason,
response,
time,
@@ -94,7 +93,7 @@ const Row = memo(({
const isFiltered = checkFiltered(reason);
const isBlocked = reason === FILTERED_STATUS.FILTERED_BLACK_LIST
|| reason === FILTERED_STATUS.FILTERED_BLOCKED_SERVICE;
|| reason === FILTERED_STATUS.FILTERED_BLOCKED_SERVICE;
const buttonType = isFiltered ? BLOCK_ACTIONS.UNBLOCK : BLOCK_ACTIONS.BLOCK;
const onToggleBlock = () => {
@@ -113,8 +112,8 @@ const Row = memo(({
const {
confirmMessage,
buttonKey: blockingClientKey,
type: blockType,
} = getBlockClientInfo(client, disallowed_clients);
isNotInAllowedList,
} = getBlockClientInfo(client, disallowed, disallowed_rule);
const blockingForClientKey = isFiltered ? 'unblock_for_this_client_only' : 'block_for_this_client_only';
const clientNameBlockingFor = getBlockingClientName(clients, client);
@@ -123,13 +122,33 @@ const Row = memo(({
dispatch(toggleBlockingForClient(buttonType, domain, clientNameBlockingFor));
};
const onBlockingClientClick = () => {
const message = `${blockType === BLOCK_ACTIONS.BLOCK ? t('adg_will_drop_dns_queries') : ''} ${t(confirmMessage, { ip: client })}`;
if (window.confirm(message)) {
dispatch(toggleClientBlock(blockType, client));
const onBlockingClientClick = async () => {
if (window.confirm(confirmMessage)) {
await dispatch(toggleClientBlock(client, disallowed, disallowed_rule));
await dispatch(updateLogs());
setModalOpened(false);
}
};
const blockButton = <button
className={classNames('title--border text-center button-action--arrow-option', { 'bg--danger': !isBlocked })}
onClick={onToggleBlock}>
{t(buttonType)}
</button>;
const blockForClientButton = <button
className='text-center font-weight-bold py-2 button-action--arrow-option'
onClick={onBlockingForClientClick}>
{t(blockingForClientKey)}
</button>;
const blockClientButton = <button
className='text-center font-weight-bold py-2 button-action--arrow-option'
onClick={onBlockingClientClick}
disabled={isNotInAllowedList}>
{t(blockingClientKey)}
</button>;
const detailedData = {
time_table_header: formatTime(time, LONG_TIME_FORMAT),
date: formatDateTime(time, DEFAULT_SHORT_DATE_FORMAT_OPTIONS),
@@ -144,12 +163,12 @@ const Row = memo(({
table_name: tracker?.name,
category_label: hasTracker && captitalizeWords(tracker.category),
tracker_source: hasTracker && sourceData
&& <a
href={sourceData.url}
target="_blank"
rel="noopener noreferrer"
className="link--green">{sourceData.name}
</a>,
&& <a
href={sourceData.url}
target="_blank"
rel="noopener noreferrer"
className="link--green">{sourceData.name}
</a>,
response_details: 'title',
install_settings_dns: upstream,
elapsed: formattedElapsedMs,
@@ -166,12 +185,9 @@ const Row = memo(({
source_label: source,
validated_with_dnssec: dnssec_enabled ? Boolean(answer_dnssec) : false,
original_response: originalResponse?.join('\n'),
[BUTTON_PREFIX + buttonType]: <div onClick={onToggleBlock}
className={classNames('title--border text-center', {
'bg--danger': isBlocked,
})}>{t(buttonType)}</div>,
[BUTTON_PREFIX + blockingForClientKey]: <div onClick={onBlockingForClientClick} className='text-center font-weight-bold py-2'>{t(blockingForClientKey)}</div>,
[BUTTON_PREFIX + blockingClientKey]: <div onClick={onBlockingClientClick} className='text-center font-weight-bold py-2'>{t(blockingClientKey)}</div>,
[BUTTON_PREFIX + buttonType]: blockButton,
[BUTTON_PREFIX + blockingForClientKey]: blockForClientButton,
[BUTTON_PREFIX + blockingClientKey]: blockClientButton,
};
setDetailedDataCurrent(processContent(detailedData));

View File

@@ -96,7 +96,7 @@
}
.bg--danger {
color: var(--danger);
color: var(--danger) !important;
}
.form-control--search {
@@ -293,7 +293,20 @@
background: var(--btn-unblock-disabled);
}
.button-action--arrow-option:hover {
.button-action--arrow-option {
background: transparent;
border: 0;
display: block;
width: 100%;
text-align: left;
color: inherit;
}
.button-action--arrow-option:disabled {
display: none;
}
.tooltip-custom__container .button-action--arrow-option:not(:disabled):hover {
cursor: pointer;
background: var(--gray-f3);
overflow: hidden;
@@ -327,7 +340,7 @@
}
.logs__row--red {
background-color: var(--red);
background-color: var(--red) !important;
}
.logs__row--white {