Skip to content

Commit

Permalink
Allow lcobucci/jwt 5.0 and web-token 3.0 (#9)
Browse files Browse the repository at this point in the history
* Allow lcobucci/jwt 5.0 and web-token 3.0
* PHPStan baseline
* CS fixed
* Mutation fixed
  • Loading branch information
Spomky authored May 12, 2023
1 parent 6cf2815 commit 07fc85a
Show file tree
Hide file tree
Showing 28 changed files with 281 additions and 113 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ coding-standards: vendor ## Check all files using defined PHP-CS-FIXER rules

.PHONY: mutation-tests
mutation-tests: vendor ## Run mutation tests with minimum MSI and covered MSI enabled
vendor/bin/infection --logger-github -s --threads=$(nproc) --min-msi=80 --min-covered-msi=85
vendor/bin/infection --logger-github -s --threads=$$(nproc) --min-msi=80 --min-covered-msi=85

.PHONY: tests
tests: vendor ## Run all tests
Expand Down
14 changes: 9 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
"doctrine/doctrine-fixtures-bundle": "^3.4",
"doctrine/orm": "^2.6",
"ekino/phpstan-banned-code": "^1.0",
"infection/infection": "^0.25",
"lcobucci/jwt": "^4.0",
"infection/infection": "^0.26",
"lcobucci/jwt": "^4.0|^5.0",
"matthiasnoback/symfony-config-test": "^4.2",
"matthiasnoback/symfony-dependency-injection-test": "^4.2",
"nyholm/psr7": "^1.3",
Expand All @@ -45,7 +45,7 @@
"phpstan/phpstan-phpunit": "^1.0",
"phpstan/phpstan-strict-rules": "^1.0",
"phpunit/phpunit": "^9.3",
"rector/rector": "^0.12",
"rector/rector": "^0.15",
"roave/security-advisories": "dev-latest",
"symfony/cache": "^5.3|^6.0",
"symfony/http-client": "^5.3|^6.0",
Expand All @@ -54,7 +54,7 @@
"symfony/var-dumper": "^5.3|^6.0",
"symfony/yaml": "^5.3|^6.0",
"symplify/easy-coding-standard": "^9.4",
"web-token/jwt-signature-algorithm-ecdsa": "^2.0"
"web-token/jwt-signature-algorithm-ecdsa": "^2.0|^3.0"
},
"autoload": {
"psr-4" : {
Expand All @@ -68,7 +68,11 @@
}
},
"config": {
"sort-packages": true
"sort-packages": true,
"allow-plugins": {
"infection/extension-installer": true,
"php-http/discovery": true
}
},
"replace": {
"spomky-labs/web-push-lib": "self.version",
Expand Down
66 changes: 66 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
parameters:
ignoreErrors:
-
message: "#^Method WebPush\\\\Bundle\\\\DependencyInjection\\\\WebPushExtension\\:\\:configurePayloadSection\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#"
count: 1
path: src/bundle/DependencyInjection/WebPushExtension.php

-
message: "#^Method WebPush\\\\Bundle\\\\DependencyInjection\\\\WebPushExtension\\:\\:configureVapidSection\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#"
count: 1
path: src/bundle/DependencyInjection/WebPushExtension.php

-
message: "#^Method WebPush\\\\Bundle\\\\DependencyInjection\\\\WebPushExtension\\:\\:getConfiguration\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#"
count: 1
path: src/bundle/DependencyInjection/WebPushExtension.php

-
message: "#^Method WebPush\\\\Bundle\\\\DependencyInjection\\\\WebPushExtension\\:\\:getDoctrineBundleConfiguration\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: src/bundle/DependencyInjection/WebPushExtension.php

-
message: "#^Property WebPush\\\\Bundle\\\\Service\\\\StatusReport\\:\\:\\$links type has no value type specified in iterable type array\\.$#"
count: 1
path: src/bundle/Service/StatusReport.php

-
message: "#^Method WebPush\\\\StatusReport\\:\\:__construct\\(\\) has parameter \\$links with no value type specified in iterable type array\\.$#"
count: 1
path: src/library/StatusReport.php

-
message: "#^Method WebPush\\\\StatusReport\\:\\:create\\(\\) has parameter \\$links with no value type specified in iterable type array\\.$#"
count: 1
path: src/library/StatusReport.php

-
message: "#^Method WebPush\\\\StatusReportInterface\\:\\:getLinks\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: src/library/StatusReportInterface.php

-
message: "#^Method WebPush\\\\Subscription\\:\\:getKeys\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: src/library/Subscription.php

-
message: "#^Method WebPush\\\\SubscriptionInterface\\:\\:getKeys\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: src/library/SubscriptionInterface.php

-
message: "#^Call to deprecated method create\\(\\) of class Lcobucci\\\\JWT\\\\Signer\\\\Ecdsa\\.$#"
count: 1
path: src/library/VAPID/LcobucciProvider.php

-
message: "#^Call to function method_exists\\(\\) with 'Lcobucci\\\\\\\\JWT\\\\\\\\Signer\\\\\\\\Ecdsa\\\\\\\\Sha256' and 'create' will always evaluate to true\\.$#"
count: 1
path: src/library/VAPID/LcobucciProvider.php

-
message: "#^Parameter \\#1 \\$contents of static method Lcobucci\\\\JWT\\\\Signer\\\\Key\\\\InMemory\\:\\:plainText\\(\\) expects non\\-empty\\-string, string given\\.$#"
count: 1
path: src/library/VAPID/LcobucciProvider.php
1 change: 1 addition & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ includes:
- vendor/phpstan/phpstan-beberlei-assert/extension.neon
- vendor/phpstan/phpstan/conf/bleedingEdge.neon
- vendor/ekino/phpstan-banned-code/extension.neon
- phpstan-baseline.neon
42 changes: 25 additions & 17 deletions rector.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,33 @@

declare(strict_types=1);

use Rector\Core\Configuration\Option;
use Rector\Config\RectorConfig;
use Rector\Core\ValueObject\PhpVersion;
use Rector\Php74\Rector\Property\TypedPropertyRector;
use Rector\Doctrine\Set\DoctrineSetList;
use Rector\PHPUnit\Set\PHPUnitLevelSetList;
use Rector\PHPUnit\Set\PHPUnitSetList;
use Rector\Set\ValueObject\LevelSetList;
use Rector\Set\ValueObject\SetList;
use Rector\Symfony\Set\SymfonyLevelSetList;
use Rector\Symfony\Set\SymfonySetList;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $containerConfigurator): void {
$containerConfigurator->import(SetList::DEAD_CODE);
$containerConfigurator->import(SetList::PHP_80);
$containerConfigurator->import(SymfonySetList::SYMFONY_52);
$containerConfigurator->import(SymfonySetList::SYMFONY_CODE_QUALITY);
$parameters = $containerConfigurator->parameters();
$parameters->set(Option::PATHS, [__DIR__ . '/src', __DIR__ . '/tests']);
$parameters->set(Option::PHP_VERSION_FEATURES, PhpVersion::PHP_80);
$parameters->set(Option::AUTO_IMPORT_NAMES, true);
$parameters->set(Option::IMPORT_SHORT_CLASSES, false);
$parameters->set(Option::IMPORT_DOC_BLOCKS, false);

$services = $containerConfigurator->services();
$services->set(TypedPropertyRector::class);
return static function (RectorConfig $config): void {
$config->import(SetList::DEAD_CODE);
$config->import(LevelSetList::UP_TO_PHP_80);
$config->import(SymfonyLevelSetList::UP_TO_SYMFONY_52);
$config->import(SymfonySetList::SYMFONY_CODE_QUALITY);
$config->import(SymfonySetList::SYMFONY_52_VALIDATOR_ATTRIBUTES);
$config->import(SymfonySetList::SYMFONY_CONSTRUCTOR_INJECTION);
$config->import(SymfonySetList::ANNOTATIONS_TO_ATTRIBUTES);
$config->import(DoctrineSetList::DOCTRINE_CODE_QUALITY);
$config->import(DoctrineSetList::ANNOTATIONS_TO_ATTRIBUTES);
$config->import(PHPUnitSetList::PHPUNIT_EXCEPTION);
$config->import(PHPUnitSetList::PHPUNIT_SPECIFIC_METHOD);
$config->import(PHPUnitLevelSetList::UP_TO_PHPUNIT_90);
$config->import(PHPUnitSetList::PHPUNIT_YIELD_DATA_PROVIDER);
$config->paths([__DIR__ . '/src', __DIR__ . '/tests']);
$config->phpVersion(PhpVersion::PHP_80);
$config->parallel();
$config->importNames();
$config->importShortClasses();
};
14 changes: 5 additions & 9 deletions src/bundle/Doctrine/Type/SubscriptionType.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

final class SubscriptionType extends Type
{
public const NAME = 'webpush_subscription';

/**
* {@inheritdoc}
*/
Expand All @@ -23,13 +25,7 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform): ?str
return null;
}
if (! $value instanceof Subscription) {
throw ConversionException::conversionFailedInvalidType(
$value,
$this->getName(),
['null',
Subscription::class,

]);
throw ConversionException::conversionFailedInvalidType($value, self::NAME, ['null', Subscription::class]);
}

return json_encode($value, JSON_THROW_ON_ERROR);
Expand All @@ -46,7 +42,7 @@ public function convertToPHPValue($value, AbstractPlatform $platform): ?Subscrip
try {
return Subscription::createFromString($value);
} catch (Throwable $e) {
throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', 'string'], $e);
throw ConversionException::conversionFailedInvalidType($value, self::NAME, ['null', 'string'], $e);
}
}

Expand All @@ -63,7 +59,7 @@ public function getSQLDeclaration(array $column, AbstractPlatform $platform): st
*/
public function getName(): string
{
return 'webpush_subscription';
return self::NAME;
}

/**
Expand Down
21 changes: 14 additions & 7 deletions src/bundle/WebPushBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DoctrineOrmMappingsPass;
use function realpath;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
use Symfony\Component\HttpKernel\Bundle\Bundle;
Expand Down Expand Up @@ -34,12 +35,16 @@ public function getContainerExtension(): ExtensionInterface
public function build(ContainerBuilder $container): void
{
parent::build($container);
$container->addCompilerPass(new ExtensionCompilerPass());
$container->addCompilerPass(new LoggerSetterCompilerPass());
$container->addCompilerPass(new PayloadContentEncodingCompilerPass());
$container->addCompilerPass(new PayloadCacheCompilerPass());
$container->addCompilerPass(new PayloadPaddingCompilerPass());
$container->addCompilerPass(new SymfonyServiceCompilerPass());
$container->addCompilerPass(new ExtensionCompilerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 0);
$container->addCompilerPass(new LoggerSetterCompilerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 0);
$container->addCompilerPass(
new PayloadContentEncodingCompilerPass(),
PassConfig::TYPE_BEFORE_OPTIMIZATION,
0
);
$container->addCompilerPass(new PayloadCacheCompilerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 0);
$container->addCompilerPass(new PayloadPaddingCompilerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 0);
$container->addCompilerPass(new SymfonyServiceCompilerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 0);

$this->registerMappings($container);
}
Expand All @@ -58,7 +63,9 @@ private function registerMappings(ContainerBuilder $container): void
$realPath => 'WebPush',
];
$container->addCompilerPass(
DoctrineOrmMappingsPass::createXmlMappingDriver($mappings, [], 'webpush.doctrine_mapping')
DoctrineOrmMappingsPass::createXmlMappingDriver($mappings, [], 'webpush.doctrine_mapping'),
PassConfig::TYPE_BEFORE_OPTIMIZATION,
0
);
}
}
4 changes: 1 addition & 3 deletions src/library/Action.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ public function getIcon(): ?string
*/
public function jsonSerialize(): array
{
return array_filter(get_object_vars($this), static function ($v): bool {
return $v !== null;
});
return array_filter(get_object_vars($this), static fn ($v): bool => $v !== null);
}
}
3 changes: 1 addition & 2 deletions src/library/Payload/AbstractAESGCM.php
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,8 @@ private function createInfo(string $type, string $context): string
$info = 'Content-Encoding: ';
$info .= $type;
$info .= "\0";
$info .= $context;

return $info;
return $info . $context;
}

private function getServerKey(): ServerKey
Expand Down
5 changes: 1 addition & 4 deletions src/library/StatusReport.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,13 @@

class StatusReport implements StatusReportInterface
{
private array $links;

public function __construct(
private SubscriptionInterface $subscription,
private NotificationInterface $notification,
private int $code,
private string $location,
array $links
private array $links
) {
$this->links = $links;
}

public static function create(
Expand Down
6 changes: 2 additions & 4 deletions src/library/Utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,8 @@ public static function privateKeyToPEM(string $privateKey, string $publicKey): s

$pem = '-----BEGIN EC PRIVATE KEY-----' . PHP_EOL;
$pem .= chunk_split(base64_encode($der), 64, PHP_EOL);
$pem .= '-----END EC PRIVATE KEY-----' . PHP_EOL;

return $pem;
return $pem . ('-----END EC PRIVATE KEY-----' . PHP_EOL);
}

public static function publicKeyToPEM(string $publicKey): string
Expand All @@ -64,9 +63,8 @@ public static function publicKeyToPEM(string $publicKey): string

$pem = '-----BEGIN PUBLIC KEY-----' . PHP_EOL;
$pem .= chunk_split(base64_encode($der), 64, PHP_EOL);
$pem .= '-----END PUBLIC KEY-----' . PHP_EOL;

return $pem;
return $pem . ('-----END PUBLIC KEY-----' . PHP_EOL);
}

public static function computeIKM(
Expand Down
6 changes: 5 additions & 1 deletion src/library/VAPID/LcobucciProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,11 @@ public function setLogger(LoggerInterface $logger): self
public function computeHeader(array $claims): Header
{
$this->logger->debug('Computing the JWS');
$signer = Sha256::create();
if (method_exists(Sha256::class, 'create')) {
$signer = Sha256::create();
} else {
$signer = new Sha256();
}
$header = json_encode([
'typ' => 'JWT',
'alg' => 'ES256',
Expand Down
4 changes: 1 addition & 3 deletions src/library/VAPID/WebTokenProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,13 @@ public function __construct(string $publicKey, string $privateKey)
$x = mb_substr($publicKeyBin, 1, self::PRIVATE_KEY_LENGTH, '8bit');
$y = mb_substr($publicKeyBin, -self::PRIVATE_KEY_LENGTH, null, '8bit');

$jwk = new JWK([
$this->signatureKey = new JWK([
'kty' => 'EC',
'crv' => 'P-256',
'd' => $privateKey,
'x' => Base64Url::encode($x),
'y' => Base64Url::encode($y),
]);

$this->signatureKey = $jwk;
$algorithmManager = new AlgorithmManager([new ES256()]);
$this->serializer = new CompactSerializer();
$this->jwsBuilder = new JWSBuilder($algorithmManager);
Expand Down
16 changes: 7 additions & 9 deletions tests/Bundle/FakeApp/Entity/Subscription.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,18 @@

namespace WebPush\Tests\Bundle\FakeApp\Entity;

use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use WebPush\Subscription as BaseSubscription;
use WebPush\Tests\Bundle\FakeApp\Repository\SubscriptionRepository;

/**
* @ORM\Table(name="subscriptions")
* @ORM\Entity(repositoryClass="WebPush\Tests\Bundle\FakeApp\Repository\SubscriptionRepository")
*/
#[ORM\Entity(repositoryClass: SubscriptionRepository::class)]
#[ORM\Table(name: 'subscriptions')]
class Subscription extends BaseSubscription
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
#[ORM\Id]
#[ORM\Column(type: Types::INTEGER)]
#[ORM\GeneratedValue]
private ?int $id = null;

public function getId(): ?int
Expand Down
Loading

0 comments on commit 07fc85a

Please sign in to comment.