Add logic for IP-based dynamic redirects

This commit is contained in:
Alejandro Celaya
2024-07-17 19:51:13 +02:00
parent 1312ea61f4
commit f49d98f2ea
9 changed files with 102 additions and 25 deletions

View File

@@ -5,14 +5,14 @@ namespace Shlinkio\Shlink\Core\RedirectRule\Entity;
use JsonSerializable;
use Psr\Http\Message\ServerRequestInterface;
use Shlinkio\Shlink\Common\Entity\AbstractEntity;
use Shlinkio\Shlink\Common\Middleware\IpAddressMiddlewareFactory;
use Shlinkio\Shlink\Core\Model\DeviceType;
use Shlinkio\Shlink\Core\RedirectRule\Model\RedirectConditionType;
use Shlinkio\Shlink\Core\RedirectRule\Model\Validation\RedirectRulesInputFilter;
use Shlinkio\Shlink\Core\Util\IpAddressUtils;
use function Shlinkio\Shlink\Core\acceptLanguageToLocales;
use function Shlinkio\Shlink\Core\ArrayUtils\some;
use function Shlinkio\Shlink\Core\ipAddressFromRequest;
use function Shlinkio\Shlink\Core\normalizeLocale;
use function Shlinkio\Shlink\Core\splitLocale;
use function sprintf;
@@ -114,7 +114,7 @@ class RedirectCondition extends AbstractEntity implements JsonSerializable
private function matchesRemoteIpAddress(ServerRequestInterface $request): bool
{
$remoteAddress = $request->getAttribute(IpAddressMiddlewareFactory::REQUEST_ATTR);
$remoteAddress = ipAddressFromRequest($request);
return $remoteAddress !== null && IpAddressUtils::ipAddressMatchesGroups($remoteAddress, [$this->matchValue]);
}

View File

@@ -14,8 +14,9 @@ use function array_map;
use function explode;
use function implode;
use function Shlinkio\Shlink\Core\ArrayUtils\some;
use function str_contains;
class IpAddressUtils
final class IpAddressUtils
{
/**
* Checks if an IP address matches any of provided groups.

View File

@@ -5,9 +5,9 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Visit\Model;
use Psr\Http\Message\ServerRequestInterface;
use Shlinkio\Shlink\Common\Middleware\IpAddressMiddlewareFactory;
use Shlinkio\Shlink\Core\Options\TrackingOptions;
use function Shlinkio\Shlink\Core\ipAddressFromRequest;
use function Shlinkio\Shlink\Core\isCrawler;
use function substr;
@@ -46,7 +46,7 @@ final class Visitor
return new self(
$request->getHeaderLine('User-Agent'),
$request->getHeaderLine('Referer'),
$request->getAttribute(IpAddressMiddlewareFactory::REQUEST_ATTR),
ipAddressFromRequest($request),
$request->getUri()->__toString(),
);
}

View File

@@ -7,7 +7,6 @@ namespace Shlinkio\Shlink\Core\Visit;
use Fig\Http\Message\RequestMethodInterface;
use Mezzio\Router\Middleware\ImplicitHeadMiddleware;
use Psr\Http\Message\ServerRequestInterface;
use Shlinkio\Shlink\Common\Middleware\IpAddressMiddlewareFactory;
use Shlinkio\Shlink\Core\ErrorHandler\Model\NotFoundType;
use Shlinkio\Shlink\Core\Exception\InvalidIpFormatException;
use Shlinkio\Shlink\Core\Options\TrackingOptions;
@@ -15,6 +14,8 @@ use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Util\IpAddressUtils;
use Shlinkio\Shlink\Core\Visit\Model\Visitor;
use function Shlinkio\Shlink\Core\ipAddressFromRequest;
readonly class RequestTracker implements RequestTrackerInterface, RequestMethodInterface
{
public function __construct(private VisitsTrackerInterface $visitsTracker, private TrackingOptions $trackingOptions)
@@ -53,7 +54,7 @@ readonly class RequestTracker implements RequestTrackerInterface, RequestMethodI
return false;
}
$remoteAddr = $request->getAttribute(IpAddressMiddlewareFactory::REQUEST_ATTR);
$remoteAddr = ipAddressFromRequest($request);
if ($this->shouldDisableTrackingFromAddress($remoteAddr)) {
return false;
}