Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] Allow a list of domains #64

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 55 additions & 3 deletions Classes/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,17 +146,69 @@ protected function checkAccess(ServerRequestInterface $request): string
return 'No secret or too small secret defined';
}

if (!isset($settings['allowedIps']) || empty($settings['allowedIps'])) {
return 'No allowed ips defined';
/* Only returns an error when both are empty */
if (empty($settings['allowedIps']) && empty($settings['allowedDomains'])) {
return 'No allowed ips or domains defined';
}

$allowedIps = $this->getAllowedIps($settings['allowedIps'], $settings['allowedDomains']);

$remoteIp = GeneralUtility::getIndpEnv('REMOTE_ADDR');
if (!GeneralUtility::cmpIP($remoteIp, $settings['allowedIps'])) {
if (!GeneralUtility::cmpIP($remoteIp, $allowedIps)) {
return sprintf('IP comparison failed, remote IP: %s!', $remoteIp);
}

return '';
}

/**
* Parses the allowed domains and IPs from the extension settings into a single allowed IPs string
* @return string The allowed ips, comma separated.
*/
public function getAllowedIps(string $allowedIps, string $allowedDomains): string
{
$allowedIps = trim($allowedIps);
$allowedDomains = trim($allowedDomains);

/* Return * when anything is allowed in one field, and the other is empty */
if (($allowedIps === '*' && $allowedDomains === '*') ||
($allowedIps === '*' && empty($allowedDomains)) ||
(empty($allowedIps) && $allowedDomains === '*')) {
return '*';
}

$allowedIpsResult = '';
if($allowedIps !== '*' && !empty($allowedIps)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please apply PSR coding standards to all files. (space after if)

$allowedIpsResult = sprintf('%s, ', $allowedIps);
}

/* Convert the domain names to IP addresses */
if($allowedDomains !== '*' && !empty($allowedDomains)) {
$allowedDomainsArray = explode(',', $allowedDomains);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use GeneralUtility::trimExplode instead

foreach ($allowedDomainsArray as $allowedDomain) {
$resultsIpv4 = @dns_get_record($allowedDomain, DNS_A);
if($resultsIpv4) {
foreach ($resultsIpv4 as $resultIpv4) {
if(isset($resultIpv4['ip'])) {
$allowedIpsResult .= sprintf('%s, ', $resultIpv4['ip']);
}
}
}
$resultsIpv6 = @dns_get_record($allowedDomain, DNS_AAAA);
if($resultsIpv6) {
foreach ($resultsIpv6 as $resultIpv6) {
if(isset($resultIpv6['ipv6'])) {
$allowedIpsResult .= sprintf('%s, ', $resultIpv6['ipv6']);
}
}
}
}
}

/* Return concatenated IPs and domains IPs */
return trim($allowedIpsResult, ' ,');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

collect the resulting IPs in an array first and do the implode here-

}

protected function getSettings(): array
{
$configuration = [];
Expand Down
4 changes: 4 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ allowedIps
""""""""""
Define a comma separated list of IPs which are allowed to fetch the client data.

allowedDomains
""""""""""
Define a comma separated list of domains which are allowed to fetch the client data.

enableDebugForErrors
""""""""""""""""""""
If set, the errors are outputted if you call `http://yourdomain.tld/?eID=t3monitoring&secret=<yoursecret>`. This can help to identify problems.
Expand Down
148 changes: 148 additions & 0 deletions Tests/Unit/ClientTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
<?php

use PHPUnit\Framework\TestCase;
use T3Monitor\T3monitoringClient\Client;
use TYPO3\CMS\Core\Utility\GeneralUtility;

class ClientTest extends TestCase
{

/**
* @var Client
*/
protected $client;

protected function setUp(): void
{
parent::setUp();
/** @var Client $client */
$this->client = GeneralUtility::makeInstance(Client::class);
}

/**
* @test
*/
public function testInputIpsAndDomainsStarsReturnOneStarOnly()
{
$allowedIps = '*';
$allowedDomains = '*';
$this->assertEquals('*', $this->client->getAllowedIps($allowedIps, $allowedDomains));

$allowedIps = '*';
$allowedDomains = '';
$this->assertEquals('*', $this->client->getAllowedIps($allowedIps, $allowedDomains));

$allowedIps = '';
$allowedDomains = '*';
$this->assertEquals('*', $this->client->getAllowedIps($allowedIps, $allowedDomains));
}

/**
* @test
*/
public function testValuesHasPriorityOverStarOverEmpty()
{
$allowedIps = '78.47.171.202, 142.250.184.206';
$allowedDomains = '*';
/* Expect the IPs to be returned */
$this->assertCount(
2,
explode(',', $this->client->getAllowedIps($allowedIps, $allowedDomains))
);

$allowedIps = '78.47.171.202, 142.250.184.206';
$allowedDomains = '';
/* Expect the IPs to be returned */
$this->assertCount(
2,
explode(',', $this->client->getAllowedIps($allowedIps, $allowedDomains))
);

$allowedIps = '*';
$allowedDomains = 'www.google.com, www.test.io';
/* Expect the IPs from the domains to be returned */
$this->assertGreaterThanOrEqual(
2,
explode(',', $this->client->getAllowedIps($allowedIps, $allowedDomains))
);

$allowedIps = '';
$allowedDomains = 'www.google.com, www.test.io';
/* Expect the IPs from the domains to be returned */
$this->assertGreaterThanOrEqual(
2,
explode(',', $this->client->getAllowedIps($allowedIps, $allowedDomains))
);
}

/**
* @test
*/
public function testInputDomainsOnlyReturnsIPv4AndIPv6()
{
$allowedIps = '';
$allowedDomains = 'www.google.com';

/* Expect the IPs to be returned */
$this->assertGreaterThanOrEqual(
1,
explode(',', $this->client->getAllowedIps($allowedIps, $allowedDomains))
);
}

/**
* @test
*/
public function testInputIpsAndDomainsReturnsBothConcatenated()
{
$allowedIps = '78.47.171.202, 142.250.184.206';
$allowedDomains = 'www.google.com, www.test.io';

/* Expect 4 or more IPs (depending on IPv6 implementation and ) to be returned */
$this->assertGreaterThanOrEqual(
4,
explode(',', $this->client->getAllowedIps($allowedIps, $allowedDomains))
);
}

/**
* @test
*/
public function testExpectTypeErrorOnNull()
{
$allowedIps = null;
$allowedDomains = null;

$this->expectException(TypeError::class);
$this->client->getAllowedIps($allowedIps, $allowedDomains);
}

/**
* @test
*/
public function testExpectZeroIpsWithEmptyParameters()
{
$allowedIps = '';
$allowedDomains = '';

$this->assertEquals(
'',
$this->client->getAllowedIps($allowedIps, $allowedDomains)
);
}

/**
* @test
*/
public function testExpectBogusDomainNamesToNotBeProcessed()
{
$allowedIps = '78.47.171.202, 142.250.184.206';
$allowedDomains = 'com.google.www, io.test.www, [email protected], www,test,io, www/test/io, jksdafjsdnidmfhsnbsdfkjnjuhasghdsn.nl';

$this->assertCount(
2,
explode(',', $this->client->getAllowedIps($allowedIps, $allowedDomains))
);
}

}
5 changes: 4 additions & 1 deletion ext_conf_template.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ secret =
allowedIps = *

# cat=features/enable/3; type=boolean; label=Enable debugging: Instead of silently stopping the endpoint call, the error is outputted. Just enable this to debug if a connection is not possible!
enableDebugForErrors = 0
enableDebugForErrors = 0

# cat=features/enable/2; type=string; label=Allowed domains:Restrict the endpoint to specific domains. Comma separated lists are possible
allowedDomains = *