mirror of
https://github.com/shlinkio/shlink.git
synced 2025-02-25 18:45:27 -06:00
Replaced references to obfuscate by anonymize
This commit is contained in:
@@ -12,7 +12,7 @@ return [
|
|||||||
'hostname' => '',
|
'hostname' => '',
|
||||||
],
|
],
|
||||||
'validate_url' => false,
|
'validate_url' => false,
|
||||||
'obfuscate_remote_addr' => true,
|
'anonymize_remote_addr' => true,
|
||||||
'visits_webhooks' => [],
|
'visits_webhooks' => [],
|
||||||
'default_short_codes_length' => DEFAULT_SHORT_CODES_LENGTH,
|
'default_short_codes_length' => DEFAULT_SHORT_CODES_LENGTH,
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ This is the complete list of supported env vars:
|
|||||||
* `MERCURE_PUBLIC_HUB_URL`: The public URL of a mercure hub server to which Shlink will sent updates. This URL will also be served to consumers that want to subscribe to those updates.
|
* `MERCURE_PUBLIC_HUB_URL`: The public URL of a mercure hub server to which Shlink will sent updates. This URL will also be served to consumers that want to subscribe to those updates.
|
||||||
* `MERCURE_INTERNAL_HUB_URL`: An internal URL for a mercure hub. Will be used only when publishing updates to mercure, and does not need to be public. If this is not provided but `MERCURE_PUBLIC_HUB_URL` was, the former one will be used to publish updates.
|
* `MERCURE_INTERNAL_HUB_URL`: An internal URL for a mercure hub. Will be used only when publishing updates to mercure, and does not need to be public. If this is not provided but `MERCURE_PUBLIC_HUB_URL` was, the former one will be used to publish updates.
|
||||||
* `MERCURE_JWT_SECRET`: The secret key that was provided to the mercure hub server, in order to be able to generate valid JWTs for publishing/subscribing to that server.
|
* `MERCURE_JWT_SECRET`: The secret key that was provided to the mercure hub server, in order to be able to generate valid JWTs for publishing/subscribing to that server.
|
||||||
* `OBFUSCATE_REMOTE_ADDR`: Tells if IP addresses from visitors should be obfuscated before storing them in the database. Default value is `true`. **Careful!** Setting this to `false` will make your Shlink instance no longer be in compliance with the GDPR and other similar laws.
|
* `ANONYMIZE_REMOTE_ADDR`: Tells if IP addresses from visitors should be obfuscated before storing them in the database. Default value is `true`. **Careful!** Setting this to `false` will make your Shlink instance no longer be in compliance with the GDPR and other similar data protection regulations.
|
||||||
|
|
||||||
An example using all env vars could look like this:
|
An example using all env vars could look like this:
|
||||||
|
|
||||||
@@ -205,7 +205,7 @@ docker run \
|
|||||||
-e "MERCURE_PUBLIC_HUB_URL=https://example.com" \
|
-e "MERCURE_PUBLIC_HUB_URL=https://example.com" \
|
||||||
-e "MERCURE_INTERNAL_HUB_URL=http://my-mercure-hub.prod.svc.cluster.local" \
|
-e "MERCURE_INTERNAL_HUB_URL=http://my-mercure-hub.prod.svc.cluster.local" \
|
||||||
-e MERCURE_JWT_SECRET=super_secret_key \
|
-e MERCURE_JWT_SECRET=super_secret_key \
|
||||||
-e OBFUSCATE_REMOTE_ADDR=false \
|
-e ANONYMIZE_REMOTE_ADDR=false \
|
||||||
shlinkio/shlink:stable
|
shlinkio/shlink:stable
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -251,7 +251,7 @@ The whole configuration should have this format, but it can be split into multip
|
|||||||
"mercure_public_hub_url": "https://example.com",
|
"mercure_public_hub_url": "https://example.com",
|
||||||
"mercure_internal_hub_url": "http://my-mercure-hub.prod.svc.cluster.local",
|
"mercure_internal_hub_url": "http://my-mercure-hub.prod.svc.cluster.local",
|
||||||
"mercure_jwt_secret": "super_secret_key",
|
"mercure_jwt_secret": "super_secret_key",
|
||||||
"obfuscate_remote_addr": false
|
"anonymize_remote_addr": false
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ return [
|
|||||||
'hostname' => env('SHORT_DOMAIN_HOST', ''),
|
'hostname' => env('SHORT_DOMAIN_HOST', ''),
|
||||||
],
|
],
|
||||||
'validate_url' => (bool) env('VALIDATE_URLS', false),
|
'validate_url' => (bool) env('VALIDATE_URLS', false),
|
||||||
'obfuscate_remote_addr' => (bool) env('OBFUSCATE_REMOTE_ADDR', true),
|
'anonymize_remote_addr' => (bool) env('ANONYMIZE_REMOTE_ADDR', true),
|
||||||
'visits_webhooks' => $helper->getVisitsWebhooks(),
|
'visits_webhooks' => $helper->getVisitsWebhooks(),
|
||||||
'default_short_codes_length' => $helper->getDefaultShortCodesLength(),
|
'default_short_codes_length' => $helper->getDefaultShortCodesLength(),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ return [
|
|||||||
Service\VisitsTracker::class => [
|
Service\VisitsTracker::class => [
|
||||||
'em',
|
'em',
|
||||||
EventDispatcherInterface::class,
|
EventDispatcherInterface::class,
|
||||||
'config.url_shortener.obfuscate_remote_addr',
|
'config.url_shortener.anonymize_remote_addr',
|
||||||
],
|
],
|
||||||
Service\ShortUrlService::class => ['em', Service\ShortUrl\ShortUrlResolver::class, Util\UrlValidator::class],
|
Service\ShortUrlService::class => ['em', Service\ShortUrl\ShortUrlResolver::class, Util\UrlValidator::class],
|
||||||
Visit\VisitLocator::class => ['em'],
|
Visit\VisitLocator::class => ['em'],
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class SimplifiedConfigParser
|
|||||||
'mercure_public_hub_url' => ['mercure', 'public_hub_url'],
|
'mercure_public_hub_url' => ['mercure', 'public_hub_url'],
|
||||||
'mercure_internal_hub_url' => ['mercure', 'internal_hub_url'],
|
'mercure_internal_hub_url' => ['mercure', 'internal_hub_url'],
|
||||||
'mercure_jwt_secret' => ['mercure', 'jwt_secret'],
|
'mercure_jwt_secret' => ['mercure', 'jwt_secret'],
|
||||||
'obfuscate_remote_addr' => ['url_shortener', 'obfuscate_remote_addr'],
|
'anonymize_remote_addr' => ['url_shortener', 'anonymize_remote_addr'],
|
||||||
];
|
];
|
||||||
private const SIMPLIFIED_CONFIG_SIDE_EFFECTS = [
|
private const SIMPLIFIED_CONFIG_SIDE_EFFECTS = [
|
||||||
'delete_short_url_threshold' => [
|
'delete_short_url_threshold' => [
|
||||||
|
|||||||
@@ -21,19 +21,19 @@ class Visit extends AbstractEntity implements JsonSerializable
|
|||||||
private ShortUrl $shortUrl;
|
private ShortUrl $shortUrl;
|
||||||
private ?VisitLocation $visitLocation = null;
|
private ?VisitLocation $visitLocation = null;
|
||||||
|
|
||||||
public function __construct(ShortUrl $shortUrl, Visitor $visitor, bool $obfuscate = true, ?Chronos $date = null)
|
public function __construct(ShortUrl $shortUrl, Visitor $visitor, bool $anonymize = true, ?Chronos $date = null)
|
||||||
{
|
{
|
||||||
$this->shortUrl = $shortUrl;
|
$this->shortUrl = $shortUrl;
|
||||||
$this->date = $date ?? Chronos::now();
|
$this->date = $date ?? Chronos::now();
|
||||||
$this->userAgent = $visitor->getUserAgent();
|
$this->userAgent = $visitor->getUserAgent();
|
||||||
$this->referer = $visitor->getReferer();
|
$this->referer = $visitor->getReferer();
|
||||||
$this->remoteAddr = $this->processAddress($obfuscate, $visitor->getRemoteAddress());
|
$this->remoteAddr = $this->processAddress($anonymize, $visitor->getRemoteAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
private function processAddress(bool $obfuscate, ?string $address): ?string
|
private function processAddress(bool $anonymize, ?string $address): ?string
|
||||||
{
|
{
|
||||||
// Localhost addresses do not need to be obfuscated
|
// Localhost addresses do not need to be anonymized
|
||||||
if (! $obfuscate || $address === null || $address === IpAddress::LOCALHOST) {
|
if (! $anonymize || $address === null || $address === IpAddress::LOCALHOST) {
|
||||||
return $address;
|
return $address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,16 +22,16 @@ class VisitsTracker implements VisitsTrackerInterface
|
|||||||
{
|
{
|
||||||
private ORM\EntityManagerInterface $em;
|
private ORM\EntityManagerInterface $em;
|
||||||
private EventDispatcherInterface $eventDispatcher;
|
private EventDispatcherInterface $eventDispatcher;
|
||||||
private bool $obfuscateRemoteAddr;
|
private bool $anonymizeRemoteAddr;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
ORM\EntityManagerInterface $em,
|
ORM\EntityManagerInterface $em,
|
||||||
EventDispatcherInterface $eventDispatcher,
|
EventDispatcherInterface $eventDispatcher,
|
||||||
bool $obfuscateRemoteAddr
|
bool $anonymizeRemoteAddr
|
||||||
) {
|
) {
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->eventDispatcher = $eventDispatcher;
|
$this->eventDispatcher = $eventDispatcher;
|
||||||
$this->obfuscateRemoteAddr = $obfuscateRemoteAddr;
|
$this->anonymizeRemoteAddr = $anonymizeRemoteAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,7 +39,7 @@ class VisitsTracker implements VisitsTrackerInterface
|
|||||||
*/
|
*/
|
||||||
public function track(ShortUrl $shortUrl, Visitor $visitor): void
|
public function track(ShortUrl $shortUrl, Visitor $visitor): void
|
||||||
{
|
{
|
||||||
$visit = new Visit($shortUrl, $visitor, $this->obfuscateRemoteAddr);
|
$visit = new Visit($shortUrl, $visitor, $this->anonymizeRemoteAddr);
|
||||||
|
|
||||||
$this->em->persist($visit);
|
$this->em->persist($visit);
|
||||||
$this->em->flush();
|
$this->em->flush();
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ class SimplifiedConfigParserTest extends TestCase
|
|||||||
'mercure_public_hub_url' => 'public_url',
|
'mercure_public_hub_url' => 'public_url',
|
||||||
'mercure_internal_hub_url' => 'internal_url',
|
'mercure_internal_hub_url' => 'internal_url',
|
||||||
'mercure_jwt_secret' => 'super_secret_value',
|
'mercure_jwt_secret' => 'super_secret_value',
|
||||||
'obfuscate_remote_addr' => false,
|
'anonymize_remote_addr' => false,
|
||||||
];
|
];
|
||||||
$expected = [
|
$expected = [
|
||||||
'app_options' => [
|
'app_options' => [
|
||||||
@@ -93,7 +93,7 @@ class SimplifiedConfigParserTest extends TestCase
|
|||||||
'https://third-party.io/foo',
|
'https://third-party.io/foo',
|
||||||
],
|
],
|
||||||
'default_short_codes_length' => 8,
|
'default_short_codes_length' => 8,
|
||||||
'obfuscate_remote_addr' => false,
|
'anonymize_remote_addr' => false,
|
||||||
],
|
],
|
||||||
|
|
||||||
'delete_short_urls' => [
|
'delete_short_urls' => [
|
||||||
|
|||||||
@@ -39,20 +39,20 @@ class VisitTest extends TestCase
|
|||||||
* @test
|
* @test
|
||||||
* @dataProvider provideAddresses
|
* @dataProvider provideAddresses
|
||||||
*/
|
*/
|
||||||
public function addressIsObfuscatedWhenRequested(bool $obfuscate, ?string $address, ?string $expectedAddress): void
|
public function addressIsAnonymizedWhenRequested(bool $anonymize, ?string $address, ?string $expectedAddress): void
|
||||||
{
|
{
|
||||||
$visit = new Visit(new ShortUrl(''), new Visitor('Chrome', 'some site', $address), $obfuscate);
|
$visit = new Visit(new ShortUrl(''), new Visitor('Chrome', 'some site', $address), $anonymize);
|
||||||
|
|
||||||
$this->assertEquals($expectedAddress, $visit->getRemoteAddr());
|
$this->assertEquals($expectedAddress, $visit->getRemoteAddr());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideAddresses(): iterable
|
public function provideAddresses(): iterable
|
||||||
{
|
{
|
||||||
yield 'obfuscated null address' => [true, null, null];
|
yield 'anonymized null address' => [true, null, null];
|
||||||
yield 'non-obfuscated null address' => [false, null, null];
|
yield 'non-anonymized null address' => [false, null, null];
|
||||||
yield 'obfuscated localhost' => [true, IpAddress::LOCALHOST, IpAddress::LOCALHOST];
|
yield 'anonymized localhost' => [true, IpAddress::LOCALHOST, IpAddress::LOCALHOST];
|
||||||
yield 'non-obfuscated localhost' => [false, IpAddress::LOCALHOST, IpAddress::LOCALHOST];
|
yield 'non-anonymized localhost' => [false, IpAddress::LOCALHOST, IpAddress::LOCALHOST];
|
||||||
yield 'obfuscated regular address' => [true, '1.2.3.4', '1.2.3.0'];
|
yield 'anonymized regular address' => [true, '1.2.3.4', '1.2.3.0'];
|
||||||
yield 'non-obfuscated regular address' => [false, '1.2.3.4', '1.2.3.4'];
|
yield 'non-anonymized regular address' => [false, '1.2.3.4', '1.2.3.4'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ namespace ShlinkioTest\Shlink\Core\Service;
|
|||||||
|
|
||||||
use Doctrine\ORM\EntityManager;
|
use Doctrine\ORM\EntityManager;
|
||||||
use Laminas\Stdlib\ArrayUtils;
|
use Laminas\Stdlib\ArrayUtils;
|
||||||
use PHPUnit\Framework\Assert;
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Prophecy\Argument;
|
use Prophecy\Argument;
|
||||||
use Prophecy\Prophecy\ObjectProphecy;
|
use Prophecy\Prophecy\ObjectProphecy;
|
||||||
@@ -53,25 +52,6 @@ class VisitsTrackerTest extends TestCase
|
|||||||
$this->eventDispatcher->dispatch(Argument::type(ShortUrlVisited::class))->shouldHaveBeenCalled();
|
$this->eventDispatcher->dispatch(Argument::type(ShortUrlVisited::class))->shouldHaveBeenCalled();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @test */
|
|
||||||
public function trackedIpAddressGetsObfuscated(): void
|
|
||||||
{
|
|
||||||
$shortCode = '123ABC';
|
|
||||||
|
|
||||||
$this->em->persist(Argument::any())->will(function ($args) {
|
|
||||||
/** @var Visit $visit */
|
|
||||||
$visit = $args[0];
|
|
||||||
Assert::assertEquals('4.3.2.0', $visit->getRemoteAddr());
|
|
||||||
$visit->setId('1');
|
|
||||||
return $visit;
|
|
||||||
})->shouldBeCalledOnce();
|
|
||||||
$this->em->flush()->shouldBeCalledOnce();
|
|
||||||
|
|
||||||
$this->visitsTracker->track(new ShortUrl($shortCode), new Visitor('', '', '4.3.2.1'));
|
|
||||||
|
|
||||||
$this->eventDispatcher->dispatch(Argument::type(ShortUrlVisited::class))->shouldHaveBeenCalled();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @test */
|
/** @test */
|
||||||
public function infoReturnsVisitsForCertainShortCode(): void
|
public function infoReturnsVisitsForCertainShortCode(): void
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user