diff --git a/.php_cs.dist b/.php_cs.dist index 6b90209..917b4d1 100644 --- a/.php_cs.dist +++ b/.php_cs.dist @@ -21,6 +21,7 @@ return PhpCsFixer\Config::create() '@PSR1' => true, '@PSR2' => true, '@Symfony' => true, + '@PhpCsFixer' => true, '@DoctrineAnnotation' => true, '@PHP70Migration' => true, '@PHP71Migration' => true, @@ -34,8 +35,10 @@ return PhpCsFixer\Config::create() 'native_function_invocation' => [ 'include' => ['@compiler_optimized'], 'scope' => 'namespaced', + 'strict' => true, ], 'mb_str_functions' => true, + 'method_chaining_indentation' => true, 'linebreak_after_opening_tag' => true, 'combine_consecutive_issets' => true, 'combine_consecutive_unsets' => true, @@ -56,6 +59,8 @@ return PhpCsFixer\Config::create() 'style' => 'annotation', ], 'php_unit_test_case_static_method_calls' => true, + 'php_unit_expectation' => true, + 'php_unit_test_class_requires_covers' => false, 'global_namespace_import' => [ 'import_classes' => true, 'import_constants' => true, diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 1651460..a71afc2 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -32,62 +32,63 @@ public function getConfigTreeBuilder(): TreeBuilder } $rootNode ->validate() - ->ifTrue(static function(array $config): bool { + ->ifTrue(static function (array $config): bool { return !isset($config['key_set']) && !isset($config['key_set_remote']); }) - ->thenInvalid('You must either configure a "key_set" or a "key_set_remote".') + ->thenInvalid('You must either configure a "key_set" or a "key_set_remote".') ->end() ->addDefaultsIfNotSet() ->children() - ->scalarNode('server_name') - ->info('The name of the server. The recommended value is the server URL. This value will be used to check the issuer of the token.') - ->isRequired() - ->end() - ->scalarNode('audience') - ->info('The audience of the token. If not set `server_name` will be used.') - ->end() - ->integerNode('ttl') - ->info('The lifetime of a token (in second). For security reasons, a value below 1 hour (3600 sec) is recommended.') - ->min(0) - ->defaultValue(1800) - ->end() - ->scalarNode('key_set') - ->info('Private/Shared keys used by this server to validate signed tokens. Must be a JWKSet object.') - ->end() - ->arrayNode('key_set_remote') - ->children() - ->scalarNode('type') - ->info('The type of the remote key set, either `jku` or `x5u`.') - ->end() - ->scalarNode('url') - ->info('The URL from where the key set should be downloaded.') - ->end() - ->end() - ->end() - ->scalarNode('key_index') - ->info('Index of the key in the key set used to sign the tokens. Could be an integer or the key ID.') - ->isRequired() - ->end() - ->scalarNode('signature_algorithm') - ->info('Signature algorithm used to sign the tokens.') - ->isRequired() - ->end() - ->arrayNode('claim_checked') - ->info('List of aliases to claim checkers.') - ->useAttributeAsKey('name') - ->prototype('scalar')->end() - ->treatNullLike([]) - ->treatFalseLike([]) - ->end() - ->arrayNode('mandatory_claims') - ->info('List of claims that must be present.') - ->useAttributeAsKey('name') - ->prototype('scalar')->end() - ->defaultValue([]) - ->treatNullLike([]) - ->treatFalseLike([]) - ->end() - ->end(); + ->scalarNode('server_name') + ->info('The name of the server. The recommended value is the server URL. This value will be used to check the issuer of the token.') + ->isRequired() + ->end() + ->scalarNode('audience') + ->info('The audience of the token. If not set `server_name` will be used.') + ->end() + ->integerNode('ttl') + ->info('The lifetime of a token (in second). For security reasons, a value below 1 hour (3600 sec) is recommended.') + ->min(0) + ->defaultValue(1800) + ->end() + ->scalarNode('key_set') + ->info('Private/Shared keys used by this server to validate signed tokens. Must be a JWKSet object.') + ->end() + ->arrayNode('key_set_remote') + ->children() + ->scalarNode('type') + ->info('The type of the remote key set, either `jku` or `x5u`.') + ->end() + ->scalarNode('url') + ->info('The URL from where the key set should be downloaded.') + ->end() + ->end() + ->end() + ->scalarNode('key_index') + ->info('Index of the key in the key set used to sign the tokens. Could be an integer or the key ID.') + ->isRequired() + ->end() + ->scalarNode('signature_algorithm') + ->info('Signature algorithm used to sign the tokens.') + ->isRequired() + ->end() + ->arrayNode('claim_checked') + ->info('List of aliases to claim checkers.') + ->useAttributeAsKey('name') + ->prototype('scalar')->end() + ->treatNullLike([]) + ->treatFalseLike([]) + ->end() + ->arrayNode('mandatory_claims') + ->info('List of claims that must be present.') + ->useAttributeAsKey('name') + ->prototype('scalar')->end() + ->defaultValue([]) + ->treatNullLike([]) + ->treatFalseLike([]) + ->end() + ->end() + ; $this->addEncryptionSection($rootNode); @@ -99,28 +100,29 @@ private function addEncryptionSection(ArrayNodeDefinition $node): void $node ->addDefaultsIfNotSet() ->children() - ->arrayNode('encryption') - ->addDefaultsIfNotSet() - ->canBeEnabled() - ->children() - ->scalarNode('key_set') - ->info('Private/ Shared keys used by this server to decrypt the tokens. Must be a JWKSet object.') - ->isRequired() - ->end() - ->scalarNode('key_index') - ->isRequired() - ->info('Index of the key in the key set used to encrypt the tokens. Could be an integer or the key ID.') - ->end() - ->scalarNode('key_encryption_algorithm') - ->isRequired() - ->info('Key encryption algorithm used to encrypt the tokens.') - ->end() - ->scalarNode('content_encryption_algorithm') - ->info('Content encryption algorithm used to encrypt the tokens.') - ->isRequired() - ->end() - ->end() - ->end() - ->end(); + ->arrayNode('encryption') + ->addDefaultsIfNotSet() + ->canBeEnabled() + ->children() + ->scalarNode('key_set') + ->info('Private/ Shared keys used by this server to decrypt the tokens. Must be a JWKSet object.') + ->isRequired() + ->end() + ->scalarNode('key_index') + ->isRequired() + ->info('Index of the key in the key set used to encrypt the tokens. Could be an integer or the key ID.') + ->end() + ->scalarNode('key_encryption_algorithm') + ->isRequired() + ->info('Key encryption algorithm used to encrypt the tokens.') + ->end() + ->scalarNode('content_encryption_algorithm') + ->info('Content encryption algorithm used to encrypt the tokens.') + ->isRequired() + ->end() + ->end() + ->end() + ->end() + ; } } diff --git a/DependencyInjection/SpomkyLabsLexikJoseExtension.php b/DependencyInjection/SpomkyLabsLexikJoseExtension.php index 1bbc8b7..10b2ab7 100644 --- a/DependencyInjection/SpomkyLabsLexikJoseExtension.php +++ b/DependencyInjection/SpomkyLabsLexikJoseExtension.php @@ -13,7 +13,6 @@ namespace SpomkyLabs\LexikJoseBundle\DependencyInjection; -use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; use function array_key_exists; use Jose\Bundle\JoseFramework\Helper\ConfigurationHelper; use SpomkyLabs\LexikJoseBundle\Encoder\LexikJoseEncoder; @@ -91,7 +90,7 @@ public function prepend(ContainerBuilder $container): void if (isset($bridgeConfig['key_set_remote'])) { ConfigurationHelper::addKeyset($container, 'lexik_jose_bridge.signature', $bridgeConfig['key_set_remote']['type'], ['url' => $bridgeConfig['key_set_remote']['url'], 'is_public' => $isDebug]); - } else if (isset($bridgeConfig['key_set'])) { + } elseif (isset($bridgeConfig['key_set'])) { ConfigurationHelper::addKeyset($container, 'lexik_jose_bridge.signature', 'jwkset', ['value' => $bridgeConfig['key_set'], 'is_public' => $isDebug]); } diff --git a/Encoder/LexikJoseEncoder.php b/Encoder/LexikJoseEncoder.php index 3310ce0..b4a1fa6 100644 --- a/Encoder/LexikJoseEncoder.php +++ b/Encoder/LexikJoseEncoder.php @@ -113,12 +113,12 @@ final class LexikJoseEncoder implements JWTEncoderInterface private $encryptionKeyIndex; /** - * @var string|null + * @var null|string */ private $keyEncryptionAlgorithm; /** - * @var string|null + * @var null|string */ private $contentEncryptionAlgorithm; @@ -137,17 +137,18 @@ final class LexikJoseEncoder implements JWTEncoderInterface * * @param int|string $signatureKeyIndex */ - public function __construct(JWSBuilder $jwsBuilder, - JWSVerifier $jwsLoader, - ClaimCheckerManager $claimCheckerManager, - HeaderCheckerManager $signatureHeaderCheckerManager, - JWKSet $signatureKeyset, - $signatureKeyIndex, - string $signatureAlgorithm, - string $issuer, - string $audience, - int $ttl, - array $mandatoryClaims = [] + public function __construct( + JWSBuilder $jwsBuilder, + JWSVerifier $jwsLoader, + ClaimCheckerManager $claimCheckerManager, + HeaderCheckerManager $signatureHeaderCheckerManager, + JWKSet $signatureKeyset, + $signatureKeyIndex, + string $signatureAlgorithm, + string $issuer, + string $audience, + int $ttl, + array $mandatoryClaims = [] ) { $this->jwsBuilder = $jwsBuilder; $this->jwsLoader = $jwsLoader; @@ -194,26 +195,6 @@ public function encode(array $payload): string } } - private function sign(array $payload): string - { - $payload += $this->getAdditionalPayload(); - $headers = $this->getSignatureHeader(); - $signatureKey = $this->signatureKeyset->get($this->signatureKeyIndex); - if ($signatureKey->has('kid')) { - $headers['kid'] = $signatureKey->get('kid'); - } - - $jws = $this->jwsBuilder - ->create() - ->withPayload(JsonConverter::encode($payload)) - ->addSignature($signatureKey, $headers) - ->build(); - - $serializer = new JWSCompactSerializer(); - - return $serializer->serialize($jws, 0); - } - public function encrypt(string $jws): string { $headers = $this->getEncryptionHeader(); @@ -228,13 +209,64 @@ public function encrypt(string $jws): string ->withPayload($jws) ->withSharedProtectedHeader($headers) ->addRecipient($encryptionKey) - ->build(); + ->build() + ; $serializer = new JWECompactSerializer(); return $serializer->serialize($jwe, 0); } + /** + * {@inheritdoc} + */ + public function decode($token): array + { + try { + if (null !== $this->jweBuilder) { + $token = $this->decrypt($token); + } + + return $this->verify($token); + } catch (InvalidClaimException $e) { + switch ($e->getClaim()) { + case 'exp': + $reason = JWTDecodeFailureException::EXPIRED_TOKEN; + + break; + default: + $reason = JWTDecodeFailureException::INVALID_TOKEN; + } + + throw new JWTDecodeFailureException($reason, sprintf('Invalid JWT Token. The following claim was not verified: %s.', $e->getClaim())); + } catch (InvalidHeaderException $e) { + throw new JWTDecodeFailureException(JWTDecodeFailureException::INVALID_TOKEN, sprintf('Invalid JWT Token. The following header was not verified: %s.', $e->getHeader())); + } catch (Exception $e) { + throw new JWTDecodeFailureException(JWTDecodeFailureException::INVALID_TOKEN, sprintf('Invalid JWT Token: %s', $e->getMessage()), $e); + } + } + + private function sign(array $payload): string + { + $payload += $this->getAdditionalPayload(); + $headers = $this->getSignatureHeader(); + $signatureKey = $this->signatureKeyset->get($this->signatureKeyIndex); + if ($signatureKey->has('kid')) { + $headers['kid'] = $signatureKey->get('kid'); + } + + $jws = $this->jwsBuilder + ->create() + ->withPayload(JsonConverter::encode($payload)) + ->addSignature($signatureKey, $headers) + ->build() + ; + + $serializer = new JWSCompactSerializer(); + + return $serializer->serialize($jws, 0); + } + /** * @throws JWTDecodeFailureException */ @@ -276,34 +308,6 @@ private function verify(string $token): array return $payload; } - /** - * {@inheritdoc} - */ - public function decode($token): array - { - try { - if (null !== $this->jweBuilder) { - $token = $this->decrypt($token); - } - - return $this->verify($token); - } catch (InvalidClaimException $e) { - switch ($e->getClaim()) { - case 'exp': - $reason = JWTDecodeFailureException::EXPIRED_TOKEN; - break; - default: - $reason = JWTDecodeFailureException::INVALID_TOKEN; - } - - throw new JWTDecodeFailureException($reason, sprintf('Invalid JWT Token. The following claim was not verified: %s.', $e->getClaim())); - } catch (InvalidHeaderException $e) { - throw new JWTDecodeFailureException(JWTDecodeFailureException::INVALID_TOKEN, sprintf('Invalid JWT Token. The following header was not verified: %s.', $e->getHeader())); - } catch (Exception $e) { - throw new JWTDecodeFailureException(JWTDecodeFailureException::INVALID_TOKEN, sprintf('Invalid JWT Token: %s', $e->getMessage()), $e); - } - } - private function getAdditionalPayload(): array { return [ diff --git a/Resources/config/encryption_services.php b/Resources/config/encryption_services.php index 0b93419..48180c1 100644 --- a/Resources/config/encryption_services.php +++ b/Resources/config/encryption_services.php @@ -19,7 +19,8 @@ $container = $container->services()->defaults() ->private() ->autoconfigure() - ->autowire(); + ->autowire() + ; $container->set('spomkylabs_lexik_jose_checker_key_encryption_algorithm') ->class(AlgHeaderChecker::class) diff --git a/Resources/config/services.php b/Resources/config/services.php index eb4ad69..bb574a3 100644 --- a/Resources/config/services.php +++ b/Resources/config/services.php @@ -22,7 +22,8 @@ $container = $container->services()->defaults() ->private() ->autoconfigure() - ->autowire(); + ->autowire() + ; $container->set(LexikJoseEncoder::class) ->args([ diff --git a/Tests/Context/LoginContext.php b/Tests/Context/LoginContext.php index 22bfd74..f08a3cb 100644 --- a/Tests/Context/LoginContext.php +++ b/Tests/Context/LoginContext.php @@ -30,12 +30,12 @@ trait LoginContext { /** - * @var string|null + * @var null|string */ - private $token = null; + private $token; /** - * @param string|null $name name of the session OR active session will be used + * @param null|string $name name of the session OR active session will be used * * @return \Behat\Mink\Session */ @@ -47,7 +47,7 @@ abstract public function getSession($name = null); abstract public function getContainer(); /** - * @return string|null + * @return null|string */ public function getToken() { @@ -67,13 +67,17 @@ public function iHaveAValidSignedToken() ->create() ->withPayload(JsonConverter::encode($payload)) ->addSignature($signatureKey, $this->getSignatureHeader()) - ->build(); + ->build() + ; $serialzer = new JWSCompactSerializer(); $this->token = $serialzer->serialize($jwt, 0); } /** * @Given the token must contain the claim :claim with value :value + * + * @param mixed $claim + * @param mixed $value */ public function theTokenMustContainTheClaimWithValue($claim, $value) { @@ -89,6 +93,8 @@ public function theTokenMustContainTheClaimWithValue($claim, $value) /** * @Given the token must contain the claim :claim + * + * @param mixed $claim */ public function theTokenMustContainTheClaim($claim) { @@ -114,7 +120,8 @@ public function iHaveAValidSignedAndEncryptedToken() ->create() ->withPayload(JsonConverter::encode($payload)) ->addSignature($signatureKey, $this->getSignatureHeader()) - ->build(); + ->build() + ; $serialzer = new JWSCompactSerializer(); $jws = $serialzer->serialize($jwt); @@ -126,7 +133,8 @@ public function iHaveAValidSignedAndEncryptedToken() ->withPayload($jws) ->withSharedProtectedHeader($this->getEncryptionHeader()) ->addRecipient($encryptionKey) - ->build(); + ->build() + ; $serialzer = new JWECompactSerializer(); @@ -135,6 +143,8 @@ public function iHaveAValidSignedAndEncryptedToken() /** * @Given I have a signed and encrypted token but without the :claim claim + * + * @param mixed $claim */ public function iHaveASignedAndEncryptedTokenButWithoutTheClaim($claim) { @@ -147,7 +157,8 @@ public function iHaveASignedAndEncryptedTokenButWithoutTheClaim($claim) ->create() ->withPayload(JsonConverter::encode($payload)) ->addSignature($signatureKey, $this->getSignatureHeader()) - ->build(); + ->build() + ; $serialzer = new JWSCompactSerializer(); $jws = $serialzer->serialize($jwt); @@ -159,7 +170,8 @@ public function iHaveASignedAndEncryptedTokenButWithoutTheClaim($claim) ->withPayload($jws) ->withSharedProtectedHeader($this->getEncryptionHeader()) ->addRecipient($encryptionKey) - ->build(); + ->build() + ; $serialzer = new JWECompactSerializer(); @@ -186,7 +198,8 @@ public function iHaveAnExpiredSignedAndEncryptedToken() ->create() ->withPayload(JsonConverter::encode($payload)) ->addSignature($signatureKey, $this->getSignatureHeader()) - ->build(); + ->build() + ; $serialzer = new JWSCompactSerializer(); $jws = $serialzer->serialize($jwt); @@ -198,7 +211,8 @@ public function iHaveAnExpiredSignedAndEncryptedToken() ->withPayload($jws) ->withSharedProtectedHeader($this->getEncryptionHeader()) ->addRecipient($encryptionKey) - ->build(); + ->build() + ; $serialzer = new JWECompactSerializer(); @@ -223,7 +237,8 @@ public function iHaveASignedAndEncryptedTokenButWithWrongIssuer() ->create() ->withPayload(JsonConverter::encode($payload)) ->addSignature($signatureKey, $this->getSignatureHeader()) - ->build(); + ->build() + ; $serialzer = new JWSCompactSerializer(); $jws = $serialzer->serialize($jwt); @@ -235,7 +250,8 @@ public function iHaveASignedAndEncryptedTokenButWithWrongIssuer() ->withPayload($jws) ->withSharedProtectedHeader($this->getEncryptionHeader()) ->addRecipient($encryptionKey) - ->build(); + ->build() + ; $serialzer = new JWECompactSerializer(); @@ -260,7 +276,8 @@ public function iHaveASignedAndEncryptedTokenButWithWrongAudience() ->create() ->withPayload(JsonConverter::encode($payload)) ->addSignature($signatureKey, $this->getSignatureHeader()) - ->build(); + ->build() + ; $serialzer = new JWSCompactSerializer(); $jws = $serialzer->serialize($jwt); @@ -272,13 +289,24 @@ public function iHaveASignedAndEncryptedTokenButWithWrongAudience() ->withPayload($jws) ->withSharedProtectedHeader($this->getEncryptionHeader()) ->addRecipient($encryptionKey) - ->build(); + ->build() + ; $serialzer = new JWECompactSerializer(); $this->token = $serialzer->serialize($jwe, 0); } + /** + * @Then I store the token + */ + public function iStoreTheToken() + { + $content = json_decode($this->getSession()->getPage()->getContent(), true); + + $this->token = $content['token']; + } + /** * @return array */ @@ -333,16 +361,6 @@ private function getEncryptionHeader() return $header; } - /** - * @Then I store the token - */ - public function iStoreTheToken() - { - $content = json_decode($this->getSession()->getPage()->getContent(), true); - - $this->token = $content['token']; - } - private function getSignatureKey(): JWK { $keyIndex = $this->getContainer()->getParameter('lexik_jose_bridge.encoder.key_index'); diff --git a/Tests/Context/RequestBuilder.php b/Tests/Context/RequestBuilder.php index bc7e012..342d12b 100644 --- a/Tests/Context/RequestBuilder.php +++ b/Tests/Context/RequestBuilder.php @@ -44,9 +44,9 @@ final class RequestBuilder private $request_parameter = []; /** - * @var string|null + * @var null|string */ - private $content = null; + private $content; /** * @var string @@ -296,7 +296,7 @@ public function getServer() } /** - * @return string|null + * @return null|string */ public function getContent() { diff --git a/Tests/Context/RequestContext.php b/Tests/Context/RequestContext.php index 8f5df61..851afea 100644 --- a/Tests/Context/RequestContext.php +++ b/Tests/Context/RequestContext.php @@ -19,18 +19,18 @@ trait RequestContext { - private $request_builder = null; - private $exception = null; + private $request_builder; + private $exception; /** - * @return string|null + * @return null|string */ abstract public function getToken(); /** * Returns Mink session. * - * @param string|null $name name of the session OR active session will be used + * @param null|string $name name of the session OR active session will be used * * @return \Behat\Mink\Session */ @@ -44,19 +44,7 @@ abstract public function getSession($name = null); abstract public function locatePath($uri); /** - * @return \SpomkyLabs\LexikJoseBundle\Features\Context\RequestBuilder - */ - protected function getRequestBuilder() - { - if (null === $this->request_builder) { - $this->request_builder = new RequestBuilder(); - } - - return $this->request_builder; - } - - /** - * @return Exception|null + * @return null|Exception */ public function getException() { @@ -65,6 +53,9 @@ public function getException() /** * @Given I add key :key with value :value in the header + * + * @param mixed $key + * @param mixed $value */ public function iAddKeyWithValueInTheHeader($key, $value) { @@ -73,6 +64,9 @@ public function iAddKeyWithValueInTheHeader($key, $value) /** * @Given I add key :key with value :value in the query parameter + * + * @param mixed $key + * @param mixed $value */ public function iAddKeyWithValueInTheQueryParameter($key, $value) { @@ -81,14 +75,20 @@ public function iAddKeyWithValueInTheQueryParameter($key, $value) /** * @Given I add user :user and password :secret in the authorization header + * + * @param mixed $user + * @param mixed $secret */ public function iAddUserAndPasswordInTheAuthorizationHeader($user, $secret) { - $this->getRequestBuilder()->addHeader('Authorization', 'Basic '.base64_encode("$user:$secret")); + $this->getRequestBuilder()->addHeader('Authorization', 'Basic '.base64_encode("{$user}:{$secret}")); } /** * @Given I add key :key with value :value in the body request + * + * @param mixed $key + * @param mixed $value */ public function iAddKeyWithValueInTheBodyRequest($key, $value) { @@ -110,6 +110,8 @@ public function iAddTheTokenInTheAuthorizationHeader() /** * @Given the request content type is :content_type + * + * @param mixed $content_type */ public function theContentTypeIs($content_type) { @@ -136,6 +138,7 @@ public function theRequestIsSecured() * @When I :method the request to :uri * * @param string $method + * @param mixed $uri */ public function iTheRequestTo($method, $uri) { @@ -165,6 +168,8 @@ public function iTheRequestTo($method, $uri) /** * @Given I am on the page :url + * + * @param mixed $url */ public function iAmOnThePage($url) { @@ -183,6 +188,8 @@ public function iShouldNotReceiveAnException() /** * @Then I should receive an exception :message + * + * @param mixed $message */ public function iShouldReceiveAnException($message) { @@ -218,6 +225,8 @@ public function theErrorListenerShouldReceiveAnInvalidTokenEvent() /** * @Then the error listener should receive an invalid token event containing an exception with message :message + * + * @param mixed $message */ public function theErrorListenerShouldReceiveAnInvalidTokenEventContainingAnExceptionWithMessage($message) { @@ -234,4 +243,16 @@ public function theErrorListenerShouldReceiveAnInvalidTokenEventContainingAnExce throw new Exception(); } + + /** + * @return \SpomkyLabs\LexikJoseBundle\Features\Context\RequestBuilder + */ + protected function getRequestBuilder() + { + if (null === $this->request_builder) { + $this->request_builder = new RequestBuilder(); + } + + return $this->request_builder; + } } diff --git a/Tests/Context/ResponseContext.php b/Tests/Context/ResponseContext.php index ed7a3fc..cdc9f40 100644 --- a/Tests/Context/ResponseContext.php +++ b/Tests/Context/ResponseContext.php @@ -24,7 +24,7 @@ trait ResponseContext { /** - * @param string|null $name name of the session OR active session will be used + * @param null|string $name name of the session OR active session will be used * * @return \Behat\Mink\Session */ @@ -32,6 +32,8 @@ abstract public function getSession($name = null); /** * @Then the response content-type should be :content_type + * + * @param mixed $content_type */ public function theResponseContentTypeShouldBe($content_type) { diff --git a/Tests/app/AppKernel.php b/Tests/app/AppKernel.php index 7083a6f..13940c3 100644 --- a/Tests/app/AppKernel.php +++ b/Tests/app/AppKernel.php @@ -21,7 +21,7 @@ final class AppKernel extends Kernel */ public function registerBundles(): array { - $bundles = [ + return [ new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(), new Symfony\Bundle\FrameworkBundle\FrameworkBundle(), new Symfony\Bundle\SecurityBundle\SecurityBundle(), @@ -33,8 +33,6 @@ public function registerBundles(): array new SpomkyLabs\TestBundle\SpomkyLabsTestBundle(), new SpomkyLabs\LexikJoseBundle\SpomkyLabsLexikJoseBundle(), ]; - - return $bundles; } /** diff --git a/Tests/app/autoload.php b/Tests/app/autoload.php index 365a4f7..785707f 100644 --- a/Tests/app/autoload.php +++ b/Tests/app/autoload.php @@ -14,9 +14,7 @@ use Composer\Autoload\ClassLoader; use Doctrine\Common\Annotations\AnnotationRegistry; -/* - * @var ClassLoader - */ +// @var ClassLoader $loader = require __DIR__.'/../../vendor/autoload.php'; //AnnotationRegistry::registerLoader([$loader, 'loadClass']); diff --git a/phpstan.neon b/phpstan.neon index 27b59d6..d6ff8a5 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -9,8 +9,10 @@ parameters: checkMissingIterableValueType: false ignoreErrors: - '#Call to an undefined method Symfony\\Component\\Config\\Definition\\Builder\\NodeParentInterface\:\:scalarNode\(\)\.#' + - '#Call to an undefined method Symfony\\Component\\Config\\Definition\\Builder\\NodeDefinition\:\:addDefaultsIfNotSet\(\)\.#' includes: - vendor/phpstan/phpstan-strict-rules/rules.neon - vendor/phpstan/phpstan-deprecation-rules/rules.neon - vendor/thecodingmachine/phpstan-safe-rule/phpstan-safe-rule.neon - vendor/phpstan/phpstan-beberlei-assert/extension.neon + - vendor/phpstan/phpstan/conf/bleedingEdge.neon