Skip to content

Commit

Permalink
- client: Match client IP strictly
Browse files Browse the repository at this point in the history
  • Loading branch information
ArtemBaskal committed May 25, 2020
1 parent 383507b commit 3f38bdf
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 16 deletions.
14 changes: 10 additions & 4 deletions client/src/components/Dashboard/Clients.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { Trans, withTranslation } from 'react-i18next';
import Card from '../ui/Card';
import Cell from '../ui/Cell';

import { getPercent } from '../../helpers/helpers';
import { STATUS_COLORS } from '../../helpers/constants';
import { getPercent, isClientInIpsOrCidrs } from '../../helpers/helpers';
import { BLOCKED_CLIENT, STATUS_COLORS } from '../../helpers/constants';
import { formatClientCell } from '../../helpers/formatClientCell';

const getClientsPercentColor = (percent) => {
Expand Down Expand Up @@ -56,7 +56,12 @@ const renderBlockingButton = (blocked, ip, handleClick, processing) => {
);
};

const isBlockedClient = (clients, ip) => !!(clients && clients.includes(ip));
const isBlockedClient = (rawClients, client) => {
if (!rawClients || !client) {
return false;
}
return isClientInIpsOrCidrs(rawClients, client);
};

const clientCell = (t, toggleClientStatus, processing, disallowedClients) => function cell(row) {
const { value } = row;
Expand All @@ -67,7 +72,8 @@ const clientCell = (t, toggleClientStatus, processing, disallowedClients) => fun
<div className="logs__row logs__row--overflow logs__row--column">
{formatClientCell(row, t)}
</div>
{renderBlockingButton(blocked, value, toggleClientStatus, processing)}
{blocked !== BLOCKED_CLIENT.CIDR
&& renderBlockingButton(blocked, value, toggleClientStatus, processing)}
</Fragment>
);
};
Expand Down
2 changes: 2 additions & 0 deletions client/src/components/Settings/Dns/Access/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Field, reduxForm } from 'redux-form';
import { Trans, withTranslation } from 'react-i18next';
import flow from 'lodash/flow';
import { renderTextareaField } from '../../../../helpers/form';
import { normalizeMultiline } from '../../../../helpers/helpers';

const fields = [
{
Expand Down Expand Up @@ -44,6 +45,7 @@ const Form = (props) => {
type="text"
className="form-control form-control--textarea font-monospace"
disabled={disabled}
normalizeOnBlur={normalizeMultiline}
/>
</div>;

Expand Down
5 changes: 5 additions & 0 deletions client/src/helpers/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -379,3 +379,8 @@ export const DNS_REQUEST_OPTIONS = {
PARALLEL_REQUESTS: 'parallel_requests',
FASTEST_ADDR: 'fastest_addr',
};

export const BLOCKED_CLIENT = {
IP: 'IP',
CIDR: 'CIDR',
};
87 changes: 75 additions & 12 deletions client/src/helpers/helpers.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-bitwise */
import 'url-polyfill';
import dateParse from 'date-fns/parse';
import dateFormat from 'date-fns/format';
Expand All @@ -24,6 +25,7 @@ import {
DEFAULT_LANGUAGE,
FILTERED_STATUS,
FILTERED,
BLOCKED_CLIENT,
} from './constants';

/**
Expand Down Expand Up @@ -167,7 +169,10 @@ export const getPercent = (amount, number) => {
return 0;
};

export const captitalizeWords = (text) => text.split(/[ -_]/g).map((str) => str.charAt(0).toUpperCase() + str.substr(1)).join(' ');
export const captitalizeWords = (text) => text.split(/[ -_]/g)
.map((str) => str.charAt(0)
.toUpperCase() + str.substr(1))
.join(' ');

export const getInterfaceIp = (option) => {
const onlyIPv6 = option.ip_addresses.every((ip) => ip.includes(':'));
Expand All @@ -187,9 +192,10 @@ export const getInterfaceIp = (option) => {
export const getIpList = (interfaces) => {
let list = [];

Object.keys(interfaces).forEach((item) => {
list = [...list, ...interfaces[item].ip_addresses];
});
Object.keys(interfaces)
.forEach((item) => {
list = [...list, ...interfaces[item].ip_addresses];
});

return list.sort();
};
Expand Down Expand Up @@ -283,7 +289,9 @@ export const normalizeTextarea = (text) => {
return [];
}

return text.replace(/[;, ]/g, '\n').split('\n').filter((n) => n);
return text.replace(/[;, ]/g, '\n')
.split('\n')
.filter((n) => n);
};

/**
Expand All @@ -307,7 +315,10 @@ export const normalizeTopClients = (topClients) => topClients.reduce(
// eslint-disable-next-line no-param-reassign
nameToCountMap.configured[infoName] = count;
return nameToCountMap;
}, { auto: {}, configured: {} },
}, {
auto: {},
configured: {},
},
);

export const getClientInfo = (clients, ip) => {
Expand All @@ -321,7 +332,10 @@ export const getClientInfo = (clients, ip) => {
const { name, whois_info } = client;
const whois = Object.keys(whois_info).length > 0 ? whois_info : '';

return { name, whois };
return {
name,
whois,
};
};

export const getAutoClientInfo = (clients, ip) => {
Expand All @@ -334,7 +348,10 @@ export const getAutoClientInfo = (clients, ip) => {
const { name, whois_info } = client;
const whois = Object.keys(whois_info).length > 0 ? whois_info : '';

return { name, whois };
return {
name,
whois,
};
};

export const sortClients = (clients) => {
Expand All @@ -344,7 +361,8 @@ export const sortClients = (clients) => {

if (nameA > nameB) {
return 1;
} if (nameA < nameB) {
}
if (nameA < nameB) {
return -1;
}

Expand All @@ -366,7 +384,8 @@ export const secondsToMilliseconds = (seconds) => {
return seconds;
};

export const normalizeRulesTextarea = (text) => text && text.replace(/^\n/g, '').replace(/\n\s*\n/g, '\n');
export const normalizeRulesTextarea = (text) => text && text.replace(/^\n/g, '')
.replace(/\n\s*\n/g, '\n');

export const isVersionGreater = (currentVersion, previousVersion) => (
versionCompare(currentVersion, previousVersion) === -1
Expand Down Expand Up @@ -449,10 +468,17 @@ export const getCurrentFilter = (url, filters) => {

if (filter) {
const { enabled, name, url } = filter;
return { enabled, name, url };
return {
enabled,
name,
url,
};
}

return { name: '', url: '' };
return {
name: '',
url: '',
};
};

/**
Expand All @@ -463,3 +489,40 @@ export const formatNumber = (num) => {
const currentLanguage = i18n.languages[0] || DEFAULT_LANGUAGE;
return num.toLocaleString(currentLanguage);
};

export const normalizeMultiline = (multiline) => `${normalizeTextarea(multiline)
.map((line) => line.trim())
.join('\n')}\n`;
/**
* @param ip {string}
* @returns {number}
*/
export const ipToInt = (ip) => ip.split('.')
.reduce((int, oct) => (int << 8) + parseInt(oct, 10), 0) >>> 0;
/**
* @param cidr {string}
* @param ip {string}
* @returns {boolean}
*/
export const isIpInCidr = (cidr, ip) => {
const [range, bits = 32] = cidr.split('/');
const mask = ~((2 ** (32 - bits)) - 1);
return (ipToInt(ip) & mask) === (ipToInt(range) & mask);
};
/**
* @param rawClients {string}
* @param currentClient {string}
* @returns {boolean | 'CIDR' | 'IP'}
*/
export const isClientInIpsOrCidrs = (rawClients, currentClient) => rawClients.split('\n')
.reduce((acc, curr) => {
if (acc) {
return acc;
}
if (curr.includes('/') && isIpInCidr(curr, currentClient)) {
return BLOCKED_CLIENT.CIDR;
} if (curr === currentClient) {
return BLOCKED_CLIENT.IP;
}
return false;
}, false);

0 comments on commit 3f38bdf

Please sign in to comment.