+ client, querylog: Add blocked service filter support

Close #2124

Squashed commit of the following:

commit 574726e88e4fe7df745dfc964706e1e26f8da59f
Merge: 3bc770fb dc61744d
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Wed Sep 23 19:32:38 2020 +0300

    Merge branch 'master' into feature/2124

commit 3bc770fba6d06bbd965ee181aed7b0a050175f58
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Wed Sep 23 11:22:07 2020 +0300

    minor

commit 90c0d739d1bd09dbcf5f27ff9e6c3f761bf81686
Merge: 5d1f2642 1d36abd1
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Wed Sep 23 11:17:24 2020 +0300

    Merge branch 'master' into feature/2124

commit 5d1f264212686ac7ecab30401b4f0e3c020dbee9
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Sep 22 17:23:08 2020 +0300

    Display elapsed if there is no service_name in blocked service

commit af86cedc31d566238764e02c5c8e465fa41292c6
Merge: b61976a7 756f97ed
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Sep 22 16:55:40 2020 +0300

    Merge branch 'master' into feature/2124

commit b61976a7f811e1d01327cad8b0925bd110c6e135
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Sep 22 16:52:48 2020 +0300

    Rename params to blocked_services, update service name display on client

commit d5b8e5f7b2c4a3d6701cf8845d31b28f55c6a808
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Sep 22 15:59:46 2020 +0300

    Update docs, return global blocked status

commit adc9a294f76070dea2d845155814c21c52fc6c7f
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Sep 22 15:24:34 2020 +0300

    + querylog: Extract filteringStatusBlockedService

commit ee8c1dce0d7520be0d0fcfe6f798dd11f13c9262
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Sep 22 13:54:16 2020 +0300

    + client: Add blocked service filter support
This commit is contained in:
Artem Baskal 2020-09-23 19:47:02 +03:00
parent dc61744d47
commit 10f67bd383
9 changed files with 58 additions and 17 deletions

View file

@ -1471,7 +1471,8 @@ Strict matching can be enabled by enclosing the value in double quotes: e.g. `"a
`response_status`: `response_status`:
* all * all
* filtered - all kinds of filtering * filtered - all kinds of filtering
* blocked - blocked or blocked service * blocked - blocked or blocked services
* blocked_services - blocked services
* blocked_safebrowsing - blocked by safebrowsing * blocked_safebrowsing - blocked by safebrowsing
* blocked_parental - blocked by parental control * blocked_parental - blocked by parental control
* whitelisted - whitelisted * whitelisted - whitelisted

View file

@ -528,6 +528,7 @@
"check_reason": "Reason: {{reason}}", "check_reason": "Reason: {{reason}}",
"check_rule": "Rule: {{rule}}", "check_rule": "Rule: {{rule}}",
"check_service": "Service name: {{service}}", "check_service": "Service name: {{service}}",
"service_name": "Service name",
"check_not_found": "Not found in your filter lists", "check_not_found": "Not found in your filter lists",
"client_confirm_block": "Are you sure you want to block the client \"{{ip}}\"?", "client_confirm_block": "Are you sure you want to block the client \"{{ip}}\"?",
"client_confirm_unblock": "Are you sure you want to unblock the client \"{{ip}}\"?", "client_confirm_unblock": "Are you sure you want to unblock the client \"{{ip}}\"?",

View file

@ -14,7 +14,6 @@ import IconTooltip from './IconTooltip';
const DomainCell = ({ const DomainCell = ({
answer_dnssec, answer_dnssec,
service_name,
client_proto, client_proto,
domain, domain,
time, time,
@ -50,10 +49,6 @@ const DomainCell = ({
protocol, protocol,
}; };
if (service_name) {
requestDetailsObj.check_service = service_name;
}
const sourceData = getSourceData(tracker); const sourceData = getSourceData(tracker);
const knownTrackerDataObj = { const knownTrackerDataObj = {
@ -103,7 +98,7 @@ const DomainCell = ({
xlinkHref='privacy' contentItemClass='key-colon' renderContent={renderContent} xlinkHref='privacy' contentItemClass='key-colon' renderContent={renderContent}
place='bottom' /> place='bottom' />
<div className={valueClass}> <div className={valueClass}>
<div className="text-truncate" title={domain}>{service_name || domain}</div> <div className="text-truncate" title={domain}>{domain}</div>
{details && isDetailed {details && isDetailed
&& <div className="detailed-info d-none d-sm-block text-truncate" && <div className="detailed-info d-none d-sm-block text-truncate"
title={details}>{details}</div>} title={details}>{details}</div>}
@ -117,7 +112,6 @@ DomainCell.propTypes = {
domain: propTypes.string.isRequired, domain: propTypes.string.isRequired,
time: propTypes.string.isRequired, time: propTypes.string.isRequired,
type: propTypes.string.isRequired, type: propTypes.string.isRequired,
service_name: propTypes.string,
tracker: propTypes.object, tracker: propTypes.object,
}; };

View file

@ -3,7 +3,11 @@ import { shallowEqual, useSelector } from 'react-redux';
import classNames from 'classnames'; import classNames from 'classnames';
import React from 'react'; import React from 'react';
import propTypes from 'prop-types'; import propTypes from 'prop-types';
import { formatElapsedMs, getFilterName } from '../../../helpers/helpers'; import {
formatElapsedMs,
getFilterName,
getServiceName,
} from '../../../helpers/helpers';
import { FILTERED_STATUS, FILTERED_STATUS_TO_META_MAP } from '../../../helpers/constants'; import { FILTERED_STATUS, FILTERED_STATUS_TO_META_MAP } from '../../../helpers/constants';
import IconTooltip from './IconTooltip'; import IconTooltip from './IconTooltip';
@ -16,6 +20,7 @@ const ResponseCell = ({
upstream, upstream,
rule, rule,
filterId, filterId,
service_name,
}) => { }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const filters = useSelector((state) => state.filtering.filters, shallowEqual); const filters = useSelector((state) => state.filtering.filters, shallowEqual);
@ -52,7 +57,7 @@ const ResponseCell = ({
install_settings_dns: upstream, install_settings_dns: upstream,
elapsed: formattedElapsedMs, elapsed: formattedElapsedMs,
response_code: status, response_code: status,
filter, ...(service_name ? { service_name: getServiceName(service_name) } : { filter }),
rule_label: rule, rule_label: rule,
response_table_header: renderResponses(response), response_table_header: renderResponses(response),
original_response: renderResponses(originalResponse), original_response: renderResponses(originalResponse),
@ -64,8 +69,22 @@ const ResponseCell = ({
...COMMON_CONTENT, ...COMMON_CONTENT,
filter: '', filter: '',
}); });
const detailedInfo = isBlocked ? filter : formattedElapsedMs;
const getDetailedInfo = (reason) => {
switch (reason) {
case FILTERED_STATUS.FILTERED_BLOCKED_SERVICE:
if (!service_name) {
return formattedElapsedMs;
}
return getServiceName(service_name);
case FILTERED_STATUS.FILTERED_BLACK_LIST:
return filter;
default:
return formattedElapsedMs;
}
};
const detailedInfo = getDetailedInfo(reason);
return <div className="logs__cell logs__cell--response" role="gridcell"> return <div className="logs__cell logs__cell--response" role="gridcell">
<IconTooltip <IconTooltip
@ -96,6 +115,7 @@ ResponseCell.propTypes = {
upstream: propTypes.string.isRequired, upstream: propTypes.string.isRequired,
rule: propTypes.string, rule: propTypes.string,
filterId: propTypes.number, filterId: propTypes.number,
service_name: propTypes.string,
}; };
export default ResponseCell; export default ResponseCell;

View file

@ -11,6 +11,7 @@ import {
formatTime, formatTime,
getBlockingClientName, getBlockingClientName,
getFilterName, getFilterName,
getServiceName,
processContent, processContent,
} from '../../../helpers/helpers'; } from '../../../helpers/helpers';
import { import {
@ -74,6 +75,7 @@ const Row = memo(({
rule, rule,
originalResponse, originalResponse,
status, status,
service_name,
} = rowProps; } = rowProps;
const hasTracker = !!tracker; const hasTracker = !!tracker;
@ -133,6 +135,8 @@ const Row = memo(({
date: formatDateTime(time, DEFAULT_SHORT_DATE_FORMAT_OPTIONS), date: formatDateTime(time, DEFAULT_SHORT_DATE_FORMAT_OPTIONS),
encryption_status: isBlocked encryption_status: isBlocked
? <div className="bg--danger">{requestStatus}</div> : requestStatus, ? <div className="bg--danger">{requestStatus}</div> : requestStatus,
...(FILTERED_STATUS.FILTERED_BLOCKED_SERVICE && service_name
&& { service_name: getServiceName(service_name) }),
domain, domain,
type_table_header: type, type_table_header: type,
protocol, protocol,
@ -219,6 +223,7 @@ Row.propTypes = {
rule: propTypes.string, rule: propTypes.string,
originalResponse: propTypes.array, originalResponse: propTypes.array,
status: propTypes.string.isRequired, status: propTypes.string.isRequired,
service_name: propTypes.string,
}).isRequired, }).isRequired,
isSmallScreen: propTypes.bool.isRequired, isSmallScreen: propTypes.bool.isRequired,
setDetailedDataCurrent: propTypes.func.isRequired, setDetailedDataCurrent: propTypes.func.isRequired,

View file

@ -280,6 +280,11 @@ export const SERVICES = [
}, },
]; ];
export const SERVICES_ID_NAME_MAP = SERVICES.reduce((acc, { id, name }) => {
acc[id] = name;
return acc;
}, {});
export const ENCRYPTION_SOURCE = { export const ENCRYPTION_SOURCE = {
PATH: 'path', PATH: 'path',
CONTENT: 'content', CONTENT: 'content',
@ -351,6 +356,10 @@ export const RESPONSE_FILTER = {
QUERY: 'blocked', QUERY: 'blocked',
LABEL: 'show_blocked_responses', LABEL: 'show_blocked_responses',
}, },
BLOCKED_SERVICES: {
QUERY: 'blocked_services',
LABEL: 'blocked_services',
},
BLOCKED_THREATS: { BLOCKED_THREATS: {
QUERY: 'blocked_safebrowsing', QUERY: 'blocked_safebrowsing',
LABEL: 'blocked_threats', LABEL: 'blocked_threats',
@ -397,7 +406,7 @@ export const FILTERED_STATUS_TO_META_MAP = {
COLOR: QUERY_STATUS_COLORS.WHITE, COLOR: QUERY_STATUS_COLORS.WHITE,
}, },
[FILTERED_STATUS.FILTERED_BLOCKED_SERVICE]: { [FILTERED_STATUS.FILTERED_BLOCKED_SERVICE]: {
LABEL: RESPONSE_FILTER.BLOCKED.LABEL, LABEL: 'blocked_service',
COLOR: QUERY_STATUS_COLORS.RED, COLOR: QUERY_STATUS_COLORS.RED,
}, },
[FILTERED_STATUS.FILTERED_SAFE_SEARCH]: { [FILTERED_STATUS.FILTERED_SAFE_SEARCH]: {

View file

@ -26,6 +26,7 @@ import {
FILTERED, FILTERED,
FILTERED_STATUS, FILTERED_STATUS,
IP_MATCH_LIST_STATUS, IP_MATCH_LIST_STATUS,
SERVICES_ID_NAME_MAP,
STANDARD_DNS_PORT, STANDARD_DNS_PORT,
STANDARD_HTTPS_PORT, STANDARD_HTTPS_PORT,
STANDARD_WEB_PORT, STANDARD_WEB_PORT,
@ -944,3 +945,9 @@ export const getBlockingClientName = (clients, ip) => {
*/ */
export const filterOutComments = (lines) => lines export const filterOutComments = (lines) => lines
.filter((line) => !line.startsWith(COMMENT_LINE_DEFAULT_TOKEN)); .filter((line) => !line.startsWith(COMMENT_LINE_DEFAULT_TOKEN));
/**
* @param {string} serviceId
* @returns {string}
*/
export const getServiceName = (serviceId) => SERVICES_ID_NAME_MAP[serviceId] || serviceId;

View file

@ -38,6 +38,7 @@ const getDevServerConfig = (proxyUrl = BASE_URL) => {
return { return {
hot: true, hot: true,
open: true,
host: devServerHost, host: devServerHost,
port: devServerPort, port: devServerPort,
proxy: { proxy: {
@ -61,5 +62,5 @@ module.exports = merge(common, {
}, },
], ],
}, },
devServer: process.env.WEBPACK_DEV_SERVER ? getDevServerConfig(BASE_URL) : undefined, ...(process.env.WEBPACK_DEV_SERVER ? { devServer: getDevServerConfig(BASE_URL) } : undefined),
}); });

View file

@ -17,7 +17,8 @@ const (
filteringStatusAll = "all" filteringStatusAll = "all"
filteringStatusFiltered = "filtered" // all kinds of filtering filteringStatusFiltered = "filtered" // all kinds of filtering
filteringStatusBlocked = "blocked" // blocked or blocked service filteringStatusBlocked = "blocked" // blocked or blocked services
filteringStatusBlockedService = "blocked_services" // blocked
filteringStatusBlockedSafebrowsing = "blocked_safebrowsing" // blocked by safebrowsing filteringStatusBlockedSafebrowsing = "blocked_safebrowsing" // blocked by safebrowsing
filteringStatusBlockedParental = "blocked_parental" // blocked by parental control filteringStatusBlockedParental = "blocked_parental" // blocked by parental control
filteringStatusWhitelisted = "whitelisted" // whitelisted filteringStatusWhitelisted = "whitelisted" // whitelisted
@ -29,7 +30,7 @@ const (
// filteringStatusValues -- array with all possible filteringStatus values // filteringStatusValues -- array with all possible filteringStatus values
var filteringStatusValues = []string{ var filteringStatusValues = []string{
filteringStatusAll, filteringStatusFiltered, filteringStatusBlocked, filteringStatusAll, filteringStatusFiltered, filteringStatusBlocked,
filteringStatusBlockedSafebrowsing, filteringStatusBlockedParental, filteringStatusBlockedService, filteringStatusBlockedSafebrowsing, filteringStatusBlockedParental,
filteringStatusWhitelisted, filteringStatusRewritten, filteringStatusSafeSearch, filteringStatusWhitelisted, filteringStatusRewritten, filteringStatusSafeSearch,
filteringStatusProcessed, filteringStatusProcessed,
} }
@ -113,6 +114,8 @@ func (c *searchCriteria) match(entry *logEntry) bool {
return res.IsFiltered && return res.IsFiltered &&
(res.Reason == dnsfilter.FilteredBlackList || (res.Reason == dnsfilter.FilteredBlackList ||
res.Reason == dnsfilter.FilteredBlockedService) res.Reason == dnsfilter.FilteredBlockedService)
case filteringStatusBlockedService:
return res.IsFiltered && res.Reason == dnsfilter.FilteredBlockedService
case filteringStatusBlockedParental: case filteringStatusBlockedParental:
return res.IsFiltered && res.Reason == dnsfilter.FilteredParental return res.IsFiltered && res.Reason == dnsfilter.FilteredParental
case filteringStatusBlockedSafebrowsing: case filteringStatusBlockedSafebrowsing:
@ -120,8 +123,8 @@ func (c *searchCriteria) match(entry *logEntry) bool {
case filteringStatusWhitelisted: case filteringStatusWhitelisted:
return res.Reason == dnsfilter.NotFilteredWhiteList return res.Reason == dnsfilter.NotFilteredWhiteList
case filteringStatusRewritten: case filteringStatusRewritten:
return (res.Reason == dnsfilter.ReasonRewrite || return res.Reason == dnsfilter.ReasonRewrite ||
res.Reason == dnsfilter.RewriteEtcHosts) res.Reason == dnsfilter.RewriteEtcHosts
case filteringStatusSafeSearch: case filteringStatusSafeSearch:
return res.IsFiltered && res.Reason == dnsfilter.FilteredSafeSearch return res.IsFiltered && res.Reason == dnsfilter.FilteredSafeSearch