mirror of
https://github.com/shlinkio/shlink.git
synced 2024-11-27 16:26:37 +03:00
Fixed all possible PHPStan errors
This commit is contained in:
parent
4f3995ea80
commit
db956a1f40
21 changed files with 67 additions and 68 deletions
|
@ -71,14 +71,6 @@ class ResolveUrlCommand extends Command
|
|||
|
||||
try {
|
||||
$longUrl = $this->urlShortener->shortCodeToUrl($shortCode);
|
||||
if (! isset($longUrl)) {
|
||||
$output->writeln(sprintf(
|
||||
'<error>' . $this->translator->translate('No URL found for short code "%s"') . '</error>',
|
||||
$shortCode
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
$output->writeln(sprintf('%s <info>%s</info>', $this->translator->translate('Long URL:'), $longUrl));
|
||||
} catch (InvalidShortCodeException $e) {
|
||||
$output->writeln(sprintf('<error>' . $this->translator->translate(
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace Shlinkio\Shlink\Common\Exception;
|
|||
|
||||
class WrongIpException extends RuntimeException
|
||||
{
|
||||
public static function fromIpAddress($ipAddress, \Exception $prev = null)
|
||||
public static function fromIpAddress($ipAddress, \Throwable $prev = null)
|
||||
{
|
||||
return new self(sprintf('Provided IP "%s" is invalid', $ipAddress), 0, $prev);
|
||||
}
|
||||
|
|
|
@ -22,15 +22,17 @@ class IpLocationResolver implements IpLocationResolverInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* @param $ipAddress
|
||||
* @param string $ipAddress
|
||||
* @return array
|
||||
* @throws WrongIpException
|
||||
*/
|
||||
public function resolveIpLocation($ipAddress)
|
||||
public function resolveIpLocation(string $ipAddress): array
|
||||
{
|
||||
try {
|
||||
$response = $this->httpClient->get(sprintf(self::SERVICE_PATTERN, $ipAddress));
|
||||
return json_decode((string) $response->getBody(), true);
|
||||
} catch (GuzzleException $e) {
|
||||
/** @var \Throwable $e */
|
||||
throw WrongIpException::fromIpAddress($ipAddress, $e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,14 @@ declare(strict_types=1);
|
|||
|
||||
namespace Shlinkio\Shlink\Common\Service;
|
||||
|
||||
use Shlinkio\Shlink\Common\Exception\WrongIpException;
|
||||
|
||||
interface IpLocationResolverInterface
|
||||
{
|
||||
/**
|
||||
* @param $ipAddress
|
||||
* @param string $ipAddress
|
||||
* @return array
|
||||
* @throws WrongIpException
|
||||
*/
|
||||
public function resolveIpLocation($ipAddress);
|
||||
public function resolveIpLocation(string $ipAddress): array;
|
||||
}
|
||||
|
|
|
@ -6,11 +6,11 @@ namespace Shlinkio\Shlink\Common\Util;
|
|||
class DateRange
|
||||
{
|
||||
/**
|
||||
* @var \DateTimeInterface
|
||||
* @var \DateTimeInterface|null
|
||||
*/
|
||||
private $startDate;
|
||||
/**
|
||||
* @var \DateTimeInterface
|
||||
* @var \DateTimeInterface|null
|
||||
*/
|
||||
private $endDate;
|
||||
|
||||
|
@ -21,7 +21,7 @@ class DateRange
|
|||
}
|
||||
|
||||
/**
|
||||
* @return \DateTimeInterface
|
||||
* @return \DateTimeInterface|null
|
||||
*/
|
||||
public function getStartDate()
|
||||
{
|
||||
|
@ -29,7 +29,7 @@ class DateRange
|
|||
}
|
||||
|
||||
/**
|
||||
* @return \DateTimeInterface
|
||||
* @return \DateTimeInterface|null
|
||||
*/
|
||||
public function getEndDate()
|
||||
{
|
||||
|
@ -39,8 +39,8 @@ class DateRange
|
|||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty()
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
return is_null($this->startDate) && is_null($this->endDate);
|
||||
return $this->startDate === null && $this->endDate === null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,12 +49,6 @@ class RedirectAction implements MiddlewareInterface
|
|||
try {
|
||||
$longUrl = $this->urlShortener->shortCodeToUrl($shortCode);
|
||||
|
||||
// If provided shortCode does not belong to a valid long URL, dispatch next middleware, which will trigger
|
||||
// a not-found error
|
||||
if ($longUrl === null) {
|
||||
return $delegate->process($request);
|
||||
}
|
||||
|
||||
// Track visit to this short code
|
||||
$this->visitTracker->track($shortCode, $request);
|
||||
|
||||
|
|
|
@ -7,9 +7,9 @@ use Shlinkio\Shlink\Common\Exception\RuntimeException;
|
|||
|
||||
class InvalidUrlException extends RuntimeException
|
||||
{
|
||||
public static function fromUrl($url, \Exception $previous = null)
|
||||
public static function fromUrl($url, \Throwable $previous = null)
|
||||
{
|
||||
$code = isset($previous) ? $previous->getCode() : -1;
|
||||
return new static(sprintf('Provided URL "%s" is not an exisitng and valid URL', $url), $code, $previous);
|
||||
return new static(sprintf('Provided URL "%s" is not an existing and valid URL', $url), $code, $previous);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,9 +49,9 @@ class ShortUrlService implements ShortUrlServiceInterface
|
|||
* @return ShortUrl
|
||||
* @throws InvalidShortCodeException
|
||||
*/
|
||||
public function setTagsByShortCode($shortCode, array $tags = [])
|
||||
public function setTagsByShortCode($shortCode, array $tags = []): ShortUrl
|
||||
{
|
||||
/** @var ShortUrl $shortUrl */
|
||||
/** @var ShortUrl|null $shortUrl */
|
||||
$shortUrl = $this->em->getRepository(ShortUrl::class)->findOneBy([
|
||||
'shortCode' => $shortCode,
|
||||
]);
|
||||
|
|
|
@ -24,5 +24,5 @@ interface ShortUrlServiceInterface
|
|||
* @return ShortUrl
|
||||
* @throws InvalidShortCodeException
|
||||
*/
|
||||
public function setTagsByShortCode($shortCode, array $tags = []);
|
||||
public function setTagsByShortCode($shortCode, array $tags = []): ShortUrl;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||
namespace Shlinkio\Shlink\Core\Service\Tag;
|
||||
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Shlinkio\Shlink\Core\Entity\Tag;
|
||||
use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException;
|
||||
|
@ -15,7 +16,7 @@ class TagService implements TagServiceInterface
|
|||
use TagManagerTrait;
|
||||
|
||||
/**
|
||||
* @var EntityManagerInterface
|
||||
* @var EntityManager|EntityManagerInterface
|
||||
*/
|
||||
private $em;
|
||||
|
||||
|
|
|
@ -90,6 +90,7 @@ class UrlShortener implements UrlShortenerInterface
|
|||
int $maxVisits = null
|
||||
): string {
|
||||
// If the url already exists in the database, just return its short code
|
||||
/** @var ShortUrl|null $shortUrl */
|
||||
$shortUrl = $this->em->getRepository(ShortUrl::class)->findOneBy([
|
||||
'originalUrl' => $url,
|
||||
]);
|
||||
|
@ -148,6 +149,7 @@ class UrlShortener implements UrlShortenerInterface
|
|||
'max' => 15,
|
||||
]]);
|
||||
} catch (GuzzleException $e) {
|
||||
/** @var \Throwable $e */
|
||||
throw InvalidUrlException::fromUrl($url, $e);
|
||||
}
|
||||
}
|
||||
|
@ -155,13 +157,13 @@ class UrlShortener implements UrlShortenerInterface
|
|||
/**
|
||||
* Generates the unique shortcode for an autoincrement ID
|
||||
*
|
||||
* @param int $id
|
||||
* @param float $id
|
||||
* @return string
|
||||
*/
|
||||
private function convertAutoincrementIdToShortCode($id): string
|
||||
private function convertAutoincrementIdToShortCode(float $id): string
|
||||
{
|
||||
$id = ((int) $id) + 200000; // Increment the Id so that the generated shortcode is not too short
|
||||
$length = strlen($this->chars);
|
||||
$id += 200000; // Increment the Id so that the generated shortcode is not too short
|
||||
$length = \strlen($this->chars);
|
||||
$code = '';
|
||||
|
||||
while ($id > 0) {
|
||||
|
|
|
@ -15,7 +15,7 @@ use Shlinkio\Shlink\Core\Repository\VisitRepository;
|
|||
class VisitsTracker implements VisitsTrackerInterface
|
||||
{
|
||||
/**
|
||||
* @var EntityManagerInterface|EntityManager
|
||||
* @var EntityManager|EntityManagerInterface
|
||||
*/
|
||||
private $em;
|
||||
|
||||
|
@ -66,14 +66,14 @@ class VisitsTracker implements VisitsTrackerInterface
|
|||
/**
|
||||
* Returns the visits on certain short code
|
||||
*
|
||||
* @param $shortCode
|
||||
* @param string $shortCode
|
||||
* @param DateRange $dateRange
|
||||
* @return Visit[]
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function info($shortCode, DateRange $dateRange = null): array
|
||||
public function info(string $shortCode, DateRange $dateRange = null): array
|
||||
{
|
||||
/** @var ShortUrl $shortUrl */
|
||||
/** @var ShortUrl|null $shortUrl */
|
||||
$shortUrl = $this->em->getRepository(ShortUrl::class)->findOneBy([
|
||||
'shortCode' => $shortCode,
|
||||
]);
|
||||
|
|
|
@ -21,10 +21,10 @@ interface VisitsTrackerInterface
|
|||
/**
|
||||
* Returns the visits on certain short code
|
||||
*
|
||||
* @param $shortCode
|
||||
* @param string $shortCode
|
||||
* @param DateRange $dateRange
|
||||
* @return Visit[]
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function info($shortCode, DateRange $dateRange = null): array;
|
||||
public function info(string $shortCode, DateRange $dateRange = null): array;
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ class CreateShortcodeAction extends AbstractRestAction
|
|||
*/
|
||||
public function process(Request $request, DelegateInterface $delegate)
|
||||
{
|
||||
$postData = $request->getParsedBody();
|
||||
$postData = (array) $request->getParsedBody();
|
||||
if (! isset($postData['longUrl'])) {
|
||||
return new JsonResponse([
|
||||
'error' => RestUtils::INVALID_ARGUMENT_ERROR,
|
||||
|
|
|
@ -75,10 +75,10 @@ class GetVisitsAction extends AbstractRestAction
|
|||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param $key
|
||||
* @param string $key
|
||||
* @return \DateTime|null
|
||||
*/
|
||||
protected function getDateQueryParam(Request $request, $key)
|
||||
private function getDateQueryParam(Request $request, string $key)
|
||||
{
|
||||
$query = $request->getQueryParams();
|
||||
if (! isset($query[$key]) || empty($query[$key])) {
|
||||
|
|
|
@ -27,7 +27,7 @@ class JWTService implements JWTServiceInterface
|
|||
* @param int $lifetime
|
||||
* @return string
|
||||
*/
|
||||
public function create(ApiKey $apiKey, $lifetime = self::DEFAULT_LIFETIME)
|
||||
public function create(ApiKey $apiKey, $lifetime = self::DEFAULT_LIFETIME): string
|
||||
{
|
||||
$currentTimestamp = time();
|
||||
|
||||
|
@ -48,7 +48,7 @@ class JWTService implements JWTServiceInterface
|
|||
* @return string
|
||||
* @throws AuthenticationException If the token has expired
|
||||
*/
|
||||
public function refresh($jwt, $lifetime = self::DEFAULT_LIFETIME)
|
||||
public function refresh(string $jwt, $lifetime = self::DEFAULT_LIFETIME): string
|
||||
{
|
||||
$payload = $this->getPayload($jwt);
|
||||
$payload['exp'] = time() + $lifetime;
|
||||
|
@ -61,7 +61,7 @@ class JWTService implements JWTServiceInterface
|
|||
* @param string $jwt
|
||||
* @return bool
|
||||
*/
|
||||
public function verify($jwt)
|
||||
public function verify(string $jwt): bool
|
||||
{
|
||||
try {
|
||||
// If no exception is thrown while decoding the token, it is considered valid
|
||||
|
@ -79,7 +79,7 @@ class JWTService implements JWTServiceInterface
|
|||
* @return array
|
||||
* @throws AuthenticationException If the token has expired
|
||||
*/
|
||||
public function getPayload($jwt)
|
||||
public function getPayload(string $jwt): array
|
||||
{
|
||||
try {
|
||||
return $this->decode($jwt);
|
||||
|
@ -92,16 +92,16 @@ class JWTService implements JWTServiceInterface
|
|||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
protected function encode(array $data)
|
||||
protected function encode(array $data): string
|
||||
{
|
||||
return JWT::encode($data, $this->appOptions->getSecretKey(), self::DEFAULT_ENCRYPTION_ALG);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $jwt
|
||||
* @param string $jwt
|
||||
* @return array
|
||||
*/
|
||||
protected function decode($jwt)
|
||||
protected function decode(string $jwt): array
|
||||
{
|
||||
return (array) JWT::decode($jwt, $this->appOptions->getSecretKey(), [self::DEFAULT_ENCRYPTION_ALG]);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ interface JWTServiceInterface
|
|||
* @param int $lifetime
|
||||
* @return string
|
||||
*/
|
||||
public function create(ApiKey $apiKey, $lifetime = self::DEFAULT_LIFETIME);
|
||||
public function create(ApiKey $apiKey, $lifetime = self::DEFAULT_LIFETIME): string;
|
||||
|
||||
/**
|
||||
* Refreshes a token and returns it with the new expiration
|
||||
|
@ -28,7 +28,7 @@ interface JWTServiceInterface
|
|||
* @return string
|
||||
* @throws AuthenticationException If the token has expired
|
||||
*/
|
||||
public function refresh($jwt, $lifetime = self::DEFAULT_LIFETIME);
|
||||
public function refresh(string $jwt, $lifetime = self::DEFAULT_LIFETIME): string;
|
||||
|
||||
/**
|
||||
* Verifies that certain JWT is valid
|
||||
|
@ -36,7 +36,7 @@ interface JWTServiceInterface
|
|||
* @param string $jwt
|
||||
* @return bool
|
||||
*/
|
||||
public function verify($jwt);
|
||||
public function verify(string $jwt): bool;
|
||||
|
||||
/**
|
||||
* Decodes certain token and returns the payload
|
||||
|
@ -45,5 +45,5 @@ interface JWTServiceInterface
|
|||
* @return array
|
||||
* @throws AuthenticationException If the token has expired
|
||||
*/
|
||||
public function getPayload($jwt);
|
||||
public function getPayload(string $jwt): array;
|
||||
}
|
||||
|
|
|
@ -55,13 +55,14 @@ class CheckAuthenticationMiddleware implements MiddlewareInterface, StatusCodeIn
|
|||
*
|
||||
* @return Response
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws \ErrorException
|
||||
*/
|
||||
public function process(Request $request, DelegateInterface $delegate)
|
||||
{
|
||||
// If current route is the authenticate route or an OPTIONS request, continue to the next middleware
|
||||
/** @var RouteResult $routeResult */
|
||||
/** @var RouteResult|null $routeResult */
|
||||
$routeResult = $request->getAttribute(RouteResult::class);
|
||||
if (! isset($routeResult)
|
||||
if ($routeResult === null
|
||||
|| $routeResult->isFailure()
|
||||
|| $routeResult->getMatchedRouteName() === AuthenticateAction::class
|
||||
|| $request->getMethod() === 'OPTIONS'
|
||||
|
|
|
@ -46,13 +46,9 @@ class ApiKeyService implements ApiKeyServiceInterface
|
|||
*/
|
||||
public function check($key)
|
||||
{
|
||||
/** @var ApiKey $apiKey */
|
||||
/** @var ApiKey|null $apiKey */
|
||||
$apiKey = $this->getByKey($key);
|
||||
if (! isset($apiKey)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $apiKey->isValid();
|
||||
return $apiKey !== null && $apiKey->isValid();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -60,12 +56,13 @@ class ApiKeyService implements ApiKeyServiceInterface
|
|||
*
|
||||
* @param string $key
|
||||
* @return ApiKey
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function disable($key)
|
||||
{
|
||||
/** @var ApiKey $apiKey */
|
||||
/** @var ApiKey|null $apiKey */
|
||||
$apiKey = $this->getByKey($key);
|
||||
if (! isset($apiKey)) {
|
||||
if ($apiKey === null) {
|
||||
throw new InvalidArgumentException(sprintf('API key "%s" does not exist and can\'t be disabled', $key));
|
||||
}
|
||||
|
||||
|
@ -75,7 +72,7 @@ class ApiKeyService implements ApiKeyServiceInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* Lists all existing appi keys
|
||||
* Lists all existing api keys
|
||||
*
|
||||
* @param bool $enabledOnly Tells if only enabled keys should be returned
|
||||
* @return ApiKey[]
|
||||
|
@ -94,8 +91,10 @@ class ApiKeyService implements ApiKeyServiceInterface
|
|||
*/
|
||||
public function getByKey($key)
|
||||
{
|
||||
return $this->em->getRepository(ApiKey::class)->findOneBy([
|
||||
/** @var ApiKey|null $apiKey */
|
||||
$apiKey = $this->em->getRepository(ApiKey::class)->findOneBy([
|
||||
'key' => $key,
|
||||
]);
|
||||
return $apiKey;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace Shlinkio\Shlink\Rest\Service;
|
||||
|
||||
use Shlinkio\Shlink\Common\Exception\InvalidArgumentException;
|
||||
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
||||
|
||||
interface ApiKeyServiceInterface
|
||||
|
@ -28,11 +29,12 @@ interface ApiKeyServiceInterface
|
|||
*
|
||||
* @param string $key
|
||||
* @return ApiKey
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function disable($key);
|
||||
|
||||
/**
|
||||
* Lists all existing appi keys
|
||||
* Lists all existing api keys
|
||||
*
|
||||
* @param bool $enabledOnly Tells if only enabled keys should be returned
|
||||
* @return ApiKey[]
|
||||
|
|
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||
namespace ShlinkioTest\Shlink\Rest\Action;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\Argument;
|
||||
use Prophecy\Prophecy\ObjectProphecy;
|
||||
use Shlinkio\Shlink\Rest\Action\AuthenticateAction;
|
||||
use Shlinkio\Shlink\Rest\Authentication\JWTService;
|
||||
|
@ -32,6 +33,8 @@ class AuthenticateActionTest extends TestCase
|
|||
{
|
||||
$this->apiKeyService = $this->prophesize(ApiKeyService::class);
|
||||
$this->jwtService = $this->prophesize(JWTService::class);
|
||||
$this->jwtService->create(Argument::cetera())->willReturn('');
|
||||
|
||||
$this->action = new AuthenticateAction(
|
||||
$this->apiKeyService->reveal(),
|
||||
$this->jwtService->reveal(),
|
||||
|
|
Loading…
Reference in a new issue