Skip to content

Commit

Permalink
Pull request: all: client id support
Browse files Browse the repository at this point in the history
Merge in DNS/adguard-home from 1383-client-id to master

Updates AdguardTeam#1383.

Squashed commit of the following:

commit ebe2678
Author: Ildar Kamalov <ik@adguard.com>
Date:   Wed Jan 27 17:51:59 2021 +0300

    - client: check if IP is valid

commit 0c33058
Author: Ildar Kamalov <ik@adguard.com>
Date:   Wed Jan 27 17:07:50 2021 +0300

    - client: find clients by client_id

commit 71c9593
Merge: 9104f16 3e9edd9
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jan 27 16:09:45 2021 +0300

    Merge branch 'master' into 1383-client-id

commit 9104f16
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jan 27 13:28:50 2021 +0300

    dnsforward: imp tests

commit ed47f26
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Wed Jan 27 12:39:52 2021 +0300

    dnsforward: fix address

commit 98b222b
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jan 26 19:50:31 2021 +0300

    home: imp code

commit 4f39665
Merge: 199fdc0 c215b82
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jan 26 19:45:13 2021 +0300

    Merge branch 'master' into 1383-client-id

commit 199fdc0
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jan 26 19:20:37 2021 +0300

    all: imp tests, logging, etc

commit 35ff14f
Author: Ildar Kamalov <ik@adguard.com>
Date:   Tue Jan 26 18:55:19 2021 +0300

    + client: remove block button from clients with client_id

commit 32991a0
Author: Ildar Kamalov <ik@adguard.com>
Date:   Tue Jan 26 18:54:25 2021 +0300

    + client: add requests count for client_id

commit 2d68df4
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jan 26 15:49:50 2021 +0300

    stats: handle client ids

commit 4e14ab3
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jan 26 13:45:25 2021 +0300

    openapi: fix example

commit ca9cf3f
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jan 26 13:37:10 2021 +0300

    openapi: improve clients find api docs

commit f79876e
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Jan 26 13:18:52 2021 +0300

    home: accept ids in clients find

commit 5b72595
Merge: 607e241 abf8f65
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Jan 25 18:34:56 2021 +0300

    Merge branch 'master' into 1383-client-id

commit 607e241
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Jan 25 18:30:39 2021 +0300

    dnsforward: fix quic

commit f046352
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Jan 25 16:53:09 2021 +0300

    all: remove wildcard requirement

commit 3b67948
Author: Andrey Meshkov <am@adguard.com>
Date:   Mon Jan 25 16:02:28 2021 +0300

    workDir now supports symlinks

commit 0647ab4
Author: Ildar Kamalov <ik@adguard.com>
Date:   Mon Jan 25 14:59:46 2021 +0300

    - client: remove wildcard from domain validation

commit b1aec04
Author: Ildar Kamalov <ik@adguard.com>
Date:   Mon Jan 25 14:55:39 2021 +0300

    + client: add form to download mobileconfig

... and 12 more commits
  • Loading branch information
ainar-g authored and heyxkhoa committed Mar 17, 2023
1 parent 56c36ad commit bb62e63
Show file tree
Hide file tree
Showing 53 changed files with 1,707 additions and 615 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ and this project adheres to
## [Unreleased]

<!--
## [v0.105.0] - 2021-01-18
## [v0.105.0] - 2021-01-27
-->

### Added

- Client ID support for DNS-over-HTTPS, DNS-over-QUIC, and DNS-over-TLS
([#1383]).
- `$dnsrewrite` modifier for filters ([#2102]).
- The host checking API and the query logs API can now return multiple matched
rules ([#2102]).
Expand All @@ -27,6 +29,7 @@ and this project adheres to
- HTTP API request body size limit ([#2305]).

[#1361]: https://github.com/AdguardTeam/AdGuardHome/issues/1361
[#1383]: https://github.com/AdguardTeam/AdGuardHome/issues/1383
[#2102]: https://github.com/AdguardTeam/AdGuardHome/issues/2102
[#2302]: https://github.com/AdguardTeam/AdGuardHome/issues/2302
[#2304]: https://github.com/AdguardTeam/AdGuardHome/issues/2304
Expand All @@ -35,6 +38,7 @@ and this project adheres to

### Changed

- `workDir` now supports symlinks.
- Stopped mounting together the directories `/opt/adguardhome/conf` and
`/opt/adguardhome/work` in our Docker images ([#2589]).
- When `dns.bogus_nxdomain` option is used, the server will now transform
Expand Down
9 changes: 6 additions & 3 deletions HACKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,12 @@ The rules are mostly sorted in the alphabetical order.
* Don't use underscores in file and package names, unless they're build tags
or for tests. This is to prevent accidental build errors with weird tags.

* Don't write code with more than four (**4**) levels of indentation. Just
like [Linus said], plus an additional level for an occasional error check or
struct initialization.
* Don't write non-test code with more than four (**4**) levels of indentation.
Just like [Linus said], plus an additional level for an occasional error
check or struct initialization.

The exception proving the rule is the table-driven test code, where an
additional level of indentation is allowed.

* Eschew external dependencies, including transitive, unless
absolutely necessary.
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,10 @@ go-lint: ; $(ENV) "$(SHELL)" ./scripts/make/go-lint.sh
go-test: ; $(ENV) "$(SHELL)" ./scripts/make/go-test.sh
go-tools: ; $(ENV) "$(SHELL)" ./scripts/make/go-tools.sh

go-check: go-tools go-lint go-test

openapi-lint: ; cd ./openapi/ && $(YARN) test
openapi-show: ; cd ./openapi/ && $(YARN) start

# TODO(a.garipov): Remove the legacy targets once the build
# infrastructure stops using them.
Expand Down
21 changes: 15 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,21 @@ If you're running **Linux**, there's a secure and easy way to install AdGuard Ho

### Guides

* [FAQ](https://github.com/AdguardTeam/AdGuardHome/wiki/FAQ)
* [Configuration](https://github.com/AdguardTeam/AdGuardHome/wiki/Configuration)
* [AdGuard Home as a DNS-over-HTTPS or DNS-over-TLS server](https://github.com/AdguardTeam/AdGuardHome/wiki/Encryption)
* [How to install and run AdGuard Home on Raspberry Pi](https://github.com/AdguardTeam/AdGuardHome/wiki/Raspberry-Pi)
* [How to install and run AdGuard Home on a Virtual Private Server](https://github.com/AdguardTeam/AdGuardHome/wiki/VPS)
* [How to write your own hosts blocklists properly](https://github.com/AdguardTeam/AdGuardHome/wiki/Hosts-Blocklists)
* [Getting Started](https://github.com/AdguardTeam/AdGuardHome/wiki/Getting-Started)
* [FAQ](https://github.com/AdguardTeam/AdGuardHome/wiki/FAQ)
* [How to Write Hosts Blocklists](https://github.com/AdguardTeam/AdGuardHome/wiki/Hosts-Blocklists)
* [Comparing AdGuard Home to Other Solutions](https://github.com/AdguardTeam/AdGuardHome/wiki/Comparison)
* Configuring AdGuard
* [Configuration](https://github.com/AdguardTeam/AdGuardHome/wiki/Configuration)
* [Configuring AdGuard Home Clients](https://github.com/AdguardTeam/AdGuardHome/wiki/Clients)
* [AdGuard Home as a DoH, DoT, or DoQ Server](https://github.com/AdguardTeam/AdGuardHome/wiki/Encryption)
* [AdGuard Home as a DNSCrypt Server](https://github.com/AdguardTeam/AdGuardHome/wiki/DNSCrypt)
* [AdGuard Home as a DHCP Server](https://github.com/AdguardTeam/AdGuardHome/wiki/DHCP)
* Installing AdGuard Home
* [Docker](https://github.com/AdguardTeam/AdGuardHome/wiki/Docker)
* [How to Install and Run AdGuard Home on a Raspberry Pi](https://github.com/AdguardTeam/AdGuardHome/wiki/Raspberry-Pi)
* [How to Install and Run AdGuard Home on a Virtual Private Server](https://github.com/AdguardTeam/AdGuardHome/wiki/VPS)
* [Verifying Releases](https://github.com/AdguardTeam/AdGuardHome/wiki/Verify-Releases)

### API

Expand Down
9 changes: 7 additions & 2 deletions client/src/__locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"form_error_ip_format": "Invalid IP format",
"form_error_mac_format": "Invalid MAC format",
"form_error_client_id_format": "Invalid client ID format",
"form_error_server_name": "Invalid server name or wildcard certificate",
"form_error_server_name": "Invalid server name",
"form_error_positive": "Must be greater than 0",
"form_error_negative": "Must be equal to 0 or greater",
"range_end_error": "Must be greater than range start",
Expand Down Expand Up @@ -251,8 +251,12 @@
"dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS",
"dns_over_quic": "DNS-over-QUIC",
"client_id": "Client ID",
"client_id_placeholder": "Enter client ID",
"client_id_desc": "Different clients can be identified by a special client ID. <a>Here</a> you can learn more about how to identify clients.",
"download_mobileconfig_doh": "Download .mobileconfig for DNS-over-HTTPS",
"download_mobileconfig_dot": "Download .mobileconfig for DNS-over-TLS",
"download_mobileconfig": "Download configuration file",
"plain_dns": "Plain DNS",
"form_enter_rate_limit": "Enter rate limit",
"rate_limit": "Rate limit",
Expand Down Expand Up @@ -388,7 +392,7 @@
"client_edit": "Edit Client",
"client_identifier": "Identifier",
"ip_address": "IP address",
"client_identifier_desc": "Clients can be identified by the IP address, CIDR, MAC address or domain. Please note that using MAC as identifier is possible only if AdGuard Home is also a <0>DHCP server</0>",
"client_identifier_desc": "Clients can be identified by the IP address, CIDR, MAC address or a special client ID (can be used for DoT/DoH/DoQ). <0>Here</0> you can learn more about how to identify clients.",
"form_enter_ip": "Enter IP",
"form_enter_mac": "Enter MAC",
"form_enter_id": "Enter identifier",
Expand Down Expand Up @@ -432,6 +436,7 @@
"setup_dns_privacy_other_3": "<0>dnscrypt-proxy</0> supports <1>DNS-over-HTTPS</1>.",
"setup_dns_privacy_other_4": "<0>Mozilla Firefox</0> supports <1>DNS-over-HTTPS</1>.",
"setup_dns_privacy_other_5": "You will find more implementations <0>here</0> and <1>here</1>.",
"setup_dns_privacy_ioc_mac": "iOS and macOS configuration",
"setup_dns_notice": "In order to use <1>DNS-over-HTTPS</1> or <1>DNS-over-TLS</1>, you need to <0>configure Encryption</0> in AdGuard Home settings.",
"rewrite_added": "DNS rewrite for \"{{key}}\" successfully added",
"rewrite_deleted": "DNS rewrite for \"{{key}}\" successfully deleted",
Expand Down
2 changes: 1 addition & 1 deletion client/src/actions/queryLogs.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
import { addErrorToast, addSuccessToast } from './toasts';

const enrichWithClientInfo = async (logs) => {
const clientsParams = getParamsForClientsSearch(logs, 'client');
const clientsParams = getParamsForClientsSearch(logs, 'client', 'client_id');

if (Object.keys(clientsParams).length > 0) {
const clients = await apiClient.findClients(clientsParams);
Expand Down
4 changes: 4 additions & 0 deletions client/src/components/App/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,7 @@ body {
.ReactModal__Body--open {
overflow: hidden;
}

a.btn-success.disabled {
color: #fff;
}
34 changes: 21 additions & 13 deletions client/src/components/Dashboard/Clients.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Card from '../ui/Card';
import Cell from '../ui/Cell';

import { getPercent, sortIp } from '../../helpers/helpers';
import { BLOCK_ACTIONS, STATUS_COLORS } from '../../helpers/constants';
import { BLOCK_ACTIONS, R_CLIENT_ID, STATUS_COLORS } from '../../helpers/constants';
import { toggleClientBlock } from '../../actions/access';
import { renderFormattedClientCell } from '../../helpers/renderFormattedClientCell';
import { getStats } from '../../actions/stats';
Expand All @@ -35,6 +35,10 @@ const CountCell = (row) => {
};

const renderBlockingButton = (ip, disallowed, disallowed_rule) => {
if (R_CLIENT_ID.test(ip)) {
return null;
}

const dispatch = useDispatch();
const { t } = useTranslation();
const processingSet = useSelector((state) => state.access.processingSet);
Expand All @@ -59,17 +63,19 @@ const renderBlockingButton = (ip, disallowed, disallowed_rule) => {
const text = disallowed ? BLOCK_ACTIONS.UNBLOCK : BLOCK_ACTIONS.BLOCK;

const isNotInAllowedList = disallowed && disallowed_rule === '';
return <div className="table__action pl-4">
<button
return (
<div className="table__action pl-4">
<button
type="button"
className={buttonClass}
onClick={isNotInAllowedList ? undefined : onClick}
disabled={isNotInAllowedList || processingSet}
title={t(isNotInAllowedList ? 'client_not_in_allowed_clients' : text)}
>
<Trans>{text}</Trans>
</button>
</div>;
>
<Trans>{text}</Trans>
</button>
</div>
);
};

const ClientCell = (row) => {
Expand All @@ -90,13 +96,14 @@ const Clients = ({
const { t } = useTranslation();
const topClients = useSelector((state) => state.stats.topClients, shallowEqual);

return <Card
return (
<Card
title={t('top_clients')}
subtitle={subtitle}
bodyType="card-table"
refresh={refreshButton}
>
<ReactTable
>
<ReactTable
data={topClients.map(({
name: ip, count, info, blocked,
}) => ({
Expand All @@ -107,7 +114,7 @@ const Clients = ({
}))}
columns={[
{
Header: 'IP',
Header: <Trans>client_table_header</Trans>,
accessor: 'ip',
sortMethod: sortIp,
Cell: ClientCell,
Expand All @@ -134,8 +141,9 @@ const Clients = ({

return disallowed ? { className: 'logs__row--red' } : {};
}}
/>
</Card>;
/>
</Card>
);
};

Clients.propTypes = {
Expand Down
107 changes: 71 additions & 36 deletions client/src/components/Logs/Cells/ClientCell.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { updateLogs } from '../../../actions/queryLogs';

const ClientCell = ({
client,
client_id,
domain,
info,
info: {
Expand All @@ -33,12 +34,14 @@ const ClientCell = ({
const autoClient = autoClients.find((autoClient) => autoClient.name === client);
const source = autoClient?.source;
const whoisAvailable = whois_info && Object.keys(whois_info).length > 0;
const clientName = name || client_id;
const clientInfo = { ...info, name: clientName };

const id = nanoid();

const data = {
address: client,
name,
name: clientName,
country: whois_info?.country,
city: whois_info?.city,
network: whois_info?.orgname,
Expand Down Expand Up @@ -99,13 +102,20 @@ const ClientCell = ({
if (options.length === 0) {
return null;
}
return <>{options.map(({ name, onClick, disabled }) => <button
key={name}
className="button-action--arrow-option px-4 py-2"
onClick={onClick}
disabled={disabled}
>{t(name)}
</button>)}</>;
return (
<>
{options.map(({ name, onClick, disabled }) => (
<button
key={name}
className="button-action--arrow-option px-4 py-2"
onClick={onClick}
disabled={disabled}
>
{t(name)}
</button>
))}
</>
);
};

const content = getOptions(BUTTON_OPTIONS);
Expand All @@ -125,45 +135,70 @@ const ClientCell = ({
'button-action__container--detailed': isDetailed,
});

return <div className={containerClass}>
<button type="button"
return (
<div className={containerClass}>
<button
type="button"
className={buttonClass}
onClick={onClick}
disabled={processingRules}
>
{t(buttonType)}
</button>
{content && <button className={buttonArrowClass} disabled={processingRules}>
<IconTooltip
className='h-100'
tooltipClass='button-action--arrow-option-container'
xlinkHref='chevron-down'
triggerClass='button-action--icon'
content={content} placement="bottom-end" trigger="click"
onVisibilityChange={setOptionsOpened}
/>
</button>}
</div>;
>
{t(buttonType)}
</button>
{content && (
<button className={buttonArrowClass} disabled={processingRules}>
<IconTooltip
className="h-100"
tooltipClass="button-action--arrow-option-container"
xlinkHref="chevron-down"
triggerClass="button-action--icon"
content={content}
placement="bottom-end"
trigger="click"
onVisibilityChange={setOptionsOpened}
/>
</button>
)}
</div>
);
};

return <div className="o-hidden h-100 logs__cell logs__cell--client" role="gridcell">
<IconTooltip className={hintClass} columnClass='grid grid--limited' tooltipClass='px-5 pb-5 pt-4 mw-75'
xlinkHref='question' contentItemClass="contentItemClass" title="client_details"
content={processedData} placement="bottom" />
<div className={nameClass}>
<div data-tip={true} data-for={id}>
{renderFormattedClientCell(client, info, isDetailed, true)}
return (
<div
className="o-hidden h-100 logs__cell logs__cell--client"
role="gridcell"
>
<IconTooltip
className={hintClass}
columnClass="grid grid--limited"
tooltipClass="px-5 pb-5 pt-4"
xlinkHref="question"
contentItemClass="text-truncate key-colon o-hidden"
title="client_details"
content={processedData}
placement="bottom"
/>
<div className={nameClass}>
<div data-tip={true} data-for={id}>
{renderFormattedClientCell(client, clientInfo, isDetailed, true)}
</div>
{isDetailed && clientName && !whoisAvailable && (
<div
className="detailed-info d-none d-sm-block logs__text"
title={clientName}
>
{clientName}
</div>
)}
</div>
{isDetailed && name && !whoisAvailable
&& <div className="detailed-info d-none d-sm-block logs__text"
title={name}>{name}</div>}
{renderBlockingButton(isFiltered, domain)}
</div>
{renderBlockingButton(isFiltered, domain)}
</div>;
);
};

ClientCell.propTypes = {
client: propTypes.string.isRequired,
client_id: propTypes.string,
domain: propTypes.string.isRequired,
info: propTypes.oneOfType([
propTypes.string,
Expand Down
Loading

0 comments on commit bb62e63

Please sign in to comment.