diff --git a/.gitignore b/.gitignore index c3f54875..e1123f0c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,10 @@ +phpstan.neon phpunit.xml Tests/autoload.php +var/ vendor/ Propel/om/ Propel/map/ composer.lock .php_cs.cache +.phpunit.result.cache diff --git a/.travis.yml b/.travis.yml index bad59d75..88efa7de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,6 @@ language: php sudo: true php: - - 7.1 - 7.2 service: @@ -12,12 +11,18 @@ service: matrix: fast_finish: true include: - - php: 7.1 - env: SYMFONY_VERSION=3.4.* - php: 7.2 - env: SYMFONY_VERSION=4.0.* + env: SYMFONY_VERSION=4.4.* - php: 7.2 - env: SYMFONY_VERSION=4.0.* DEPENDENCIES=beta + env: SYMFONY_VERSION=5.0.* + - php: 7.3 + env: SYMFONY_VERSION=4.4.* + - php: 7.3 + env: SYMFONY_VERSION=5.0.* + - php: 7.4 + env: SYMFONY_VERSION=4.4.* + - php: 7.4 + env: SYMFONY_VERSION=5.0.* cache: directories: diff --git a/Command/CleanCommand.php b/Command/CleanCommand.php index e24590f4..bad03350 100644 --- a/Command/CleanCommand.php +++ b/Command/CleanCommand.php @@ -21,15 +21,20 @@ class CleanCommand extends Command { + /** @var TokenManagerInterface */ private $accessTokenManager; + + /** @var TokenManagerInterface */ private $refreshTokenManager; + + /** @var AuthCodeManagerInterface */ private $authCodeManager; public function __construct( TokenManagerInterface $accessTokenManager, TokenManagerInterface $refreshTokenManager, - AuthCodeManagerInterface $authCodeManager) - { + AuthCodeManagerInterface $authCodeManager + ) { parent::__construct(); $this->accessTokenManager = $accessTokenManager; @@ -40,7 +45,7 @@ public function __construct( /** * {@inheritdoc} */ - protected function configure() + protected function configure(): void { parent::configure(); @@ -63,7 +68,15 @@ protected function execute(InputInterface $input, OutputInterface $output) { foreach ([$this->accessTokenManager, $this->refreshTokenManager, $this->authCodeManager] as $service) { $result = $service->deleteExpired(); - $output->writeln(sprintf('Removed %d items from %s storage.', $result, get_class($service))); + $output->writeln( + sprintf( + 'Removed %d items from %s storage.', + $result, + get_class($service) + ) + ); } + + return 0; } } diff --git a/Command/CreateClientCommand.php b/Command/CreateClientCommand.php index 6b881b2b..3790ef0f 100644 --- a/Command/CreateClientCommand.php +++ b/Command/CreateClientCommand.php @@ -22,6 +22,7 @@ class CreateClientCommand extends Command { + /** @var ClientManagerInterface */ private $clientManager; public function __construct(ClientManagerInterface $clientManager) @@ -34,7 +35,7 @@ public function __construct(ClientManagerInterface $clientManager) /** * {@inheritdoc} */ - protected function configure() + protected function configure(): void { parent::configure(); diff --git a/Controller/AuthorizeController.php b/Controller/AuthorizeController.php index 46c75fca..f973597e 100644 --- a/Controller/AuthorizeController.php +++ b/Controller/AuthorizeController.php @@ -19,7 +19,7 @@ use FOS\OAuthServerBundle\Model\ClientManagerInterface; use OAuth2\OAuth2; use OAuth2\OAuth2ServerException; -use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface; +use RuntimeException; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\Form\Form; use Symfony\Component\HttpFoundation\Request; @@ -31,6 +31,7 @@ use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Exception\AccessDeniedException; use Symfony\Component\Security\Core\User\UserInterface; +use Twig\Environment; /** * Controller handling basic authorization. @@ -65,9 +66,9 @@ class AuthorizeController private $oAuth2Server; /** - * @var EngineInterface + * @var Environment */ - private $templating; + private $twig; /** * @var RequestStack @@ -89,11 +90,6 @@ class AuthorizeController */ private $clientManager; - /** - * @var string - */ - private $templateEngineType; - /** * @var EventDispatcherInterface */ @@ -105,47 +101,32 @@ class AuthorizeController * * @todo This controller could be refactored to not rely on so many dependencies * - * @param RequestStack $requestStack - * @param Form $authorizeForm - * @param AuthorizeFormHandler $authorizeFormHandler - * @param OAuth2 $oAuth2Server - * @param EngineInterface $templating - * @param TokenStorageInterface $tokenStorage - * @param UrlGeneratorInterface $router - * @param ClientManagerInterface $clientManager - * @param EventDispatcherInterface $eventDispatcher - * @param SessionInterface $session - * @param string $templateEngineType + * @param SessionInterface $session */ public function __construct( RequestStack $requestStack, Form $authorizeForm, AuthorizeFormHandler $authorizeFormHandler, OAuth2 $oAuth2Server, - EngineInterface $templating, + Environment $twig, TokenStorageInterface $tokenStorage, UrlGeneratorInterface $router, ClientManagerInterface $clientManager, EventDispatcherInterface $eventDispatcher, - SessionInterface $session = null, - $templateEngineType = 'twig' + SessionInterface $session = null ) { $this->requestStack = $requestStack; $this->session = $session; $this->authorizeForm = $authorizeForm; $this->authorizeFormHandler = $authorizeFormHandler; $this->oAuth2Server = $oAuth2Server; - $this->templating = $templating; + $this->twig = $twig; $this->tokenStorage = $tokenStorage; $this->router = $router; $this->clientManager = $clientManager; - $this->templateEngineType = $templateEngineType; $this->eventDispatcher = $eventDispatcher; } - /** - * Authorize. - */ public function authorizeAction(Request $request) { $user = $this->tokenStorage->getToken()->getUser(); @@ -164,8 +145,11 @@ public function authorizeAction(Request $request) /** @var OAuthEvent $event */ $event = $this->eventDispatcher->dispatch( - OAuthEvent::PRE_AUTHORIZATION_PROCESS, - new OAuthEvent($user, $this->getClient()) + new OAuthEvent( + $user, + $this->getClient() + ), + OAuthEvent::PRE_AUTHORIZATION_PROCESS ); if ($event->isAuthorizedClient()) { @@ -183,26 +167,25 @@ public function authorizeAction(Request $request) 'client' => $this->getClient(), ]; - return $this->renderAuthorize($data, $this->templating, $this->templateEngineType); + return new Response( + $this->twig->render('@FOSOAuthServer/Authorize/authorize.html.twig', $data), + Response::HTTP_OK + ); } - /** - * @param UserInterface $user - * @param AuthorizeFormHandler $formHandler - * @param Request $request - * - * @return Response - */ - protected function processSuccess(UserInterface $user, AuthorizeFormHandler $formHandler, Request $request) - { + protected function processSuccess( + UserInterface $user, + AuthorizeFormHandler $formHandler, + Request $request + ): ?Response { if ($this->session && true === $this->session->get('_fos_oauth_server.ensure_logout')) { $this->tokenStorage->setToken(null); $this->session->invalidate(); } $this->eventDispatcher->dispatch( - OAuthEvent::POST_AUTHORIZATION_PROCESS, - new OAuthEvent($user, $this->getClient(), $formHandler->isAccepted()) + new OAuthEvent($user, $this->getClient(), $formHandler->isAccepted()), + OAuthEvent::POST_AUTHORIZATION_PROCESS ); $formName = $this->authorizeForm->getName(); @@ -221,20 +204,13 @@ protected function processSuccess(UserInterface $user, AuthorizeFormHandler $for /** * Generate the redirection url when the authorize is completed. - * - * @param UserInterface $user - * - * @return string */ - protected function getRedirectionUrl(UserInterface $user) + protected function getRedirectionUrl(UserInterface $user): string { return $this->router->generate('fos_oauth_server_profile_show'); } - /** - * @return ClientInterface - */ - protected function getClient() + protected function getClient(): ClientInterface { if (null !== $this->client) { return $this->client; @@ -246,7 +222,7 @@ protected function getClient() if (null === $clientId = $request->get('client_id')) { $formData = $request->get($this->authorizeForm->getName(), []); - $clientId = isset($formData['client_id']) ? $formData['client_id'] : null; + $clientId = $formData['client_id'] ?? null; } $this->client = $this->clientManager->findClientByPublicId($clientId); @@ -258,25 +234,11 @@ protected function getClient() return $this->client; } - /** - * @throws \RuntimeException - */ - protected function renderAuthorize(array $data, EngineInterface $engine, string $engineType): Response - { - return $engine->renderResponse( - '@FOSOAuthServer/Authorize/authorize.html.'.$engineType, - $data - ); - } - - /** - * @return null|Request - */ - private function getCurrentRequest() + private function getCurrentRequest(): ?Request { $request = $this->requestStack->getCurrentRequest(); if (null === $request) { - throw new \RuntimeException('No current request.'); + throw new RuntimeException('No current request.'); } return $request; diff --git a/Controller/TokenController.php b/Controller/TokenController.php index 09b0a07a..d5840276 100644 --- a/Controller/TokenController.php +++ b/Controller/TokenController.php @@ -25,17 +25,12 @@ class TokenController */ protected $server; - /** - * @param OAuth2 $server - */ public function __construct(OAuth2 $server) { $this->server = $server; } /** - * @param Request $request - * * @return Response */ public function tokenAction(Request $request) diff --git a/DependencyInjection/Compiler/GrantExtensionsCompilerPass.php b/DependencyInjection/Compiler/GrantExtensionsCompilerPass.php index 31cdaca7..a433b61c 100644 --- a/DependencyInjection/Compiler/GrantExtensionsCompilerPass.php +++ b/DependencyInjection/Compiler/GrantExtensionsCompilerPass.php @@ -13,6 +13,8 @@ namespace FOS\OAuthServerBundle\DependencyInjection\Compiler; +use FOS\OAuthServerBundle\Storage\GrantExtensionDispatcherInterface; +use ReflectionClass; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; @@ -23,12 +25,12 @@ */ class GrantExtensionsCompilerPass implements CompilerPassInterface { - public function process(ContainerBuilder $container) + public function process(ContainerBuilder $container): void { $storageDefinition = $container->findDefinition('fos_oauth_server.storage'); $className = $container->getParameterBag()->resolveValue($storageDefinition->getClass()); - $storageClass = new \ReflectionClass($className); - if (!$storageClass->implementsInterface('FOS\OAuthServerBundle\Storage\GrantExtensionDispatcherInterface')) { + $storageClass = new ReflectionClass($className); + if (!$storageClass->implementsInterface(GrantExtensionDispatcherInterface::class)) { return; } diff --git a/DependencyInjection/Compiler/RequestStackCompilerPass.php b/DependencyInjection/Compiler/RequestStackCompilerPass.php index a45f5ca3..1eeeb389 100644 --- a/DependencyInjection/Compiler/RequestStackCompilerPass.php +++ b/DependencyInjection/Compiler/RequestStackCompilerPass.php @@ -27,7 +27,7 @@ final class RequestStackCompilerPass implements CompilerPassInterface /** * {@inheritdoc} */ - public function process(ContainerBuilder $container) + public function process(ContainerBuilder $container): void { if ($container->has('request_stack')) { return; diff --git a/DependencyInjection/Compiler/TokenStorageCompilerPass.php b/DependencyInjection/Compiler/TokenStorageCompilerPass.php deleted file mode 100644 index 2c55ebc0..00000000 --- a/DependencyInjection/Compiler/TokenStorageCompilerPass.php +++ /dev/null @@ -1,36 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace FOS\OAuthServerBundle\DependencyInjection\Compiler; - -use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Reference; - -/** - * @author Andras Ratz - */ -class TokenStorageCompilerPass implements CompilerPassInterface -{ - /** - * {@inheritdoc} - */ - public function process(ContainerBuilder $container) - { - $definition = $container->getDefinition('fos_oauth_server.security.authentication.listener'); - - if ($container->hasDefinition('security.token_storage') === false) { - $definition->replaceArgument(0, new Reference('security.context')); - } - } -} diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 571fcafd..2bb09a69 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -13,6 +13,7 @@ namespace FOS\OAuthServerBundle\DependencyInjection; +use InvalidArgumentException; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; @@ -20,19 +21,20 @@ /** * This is the class that validates and merges configuration from your app/config files. * - * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class} + * To learn more see + * {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class} */ class Configuration implements ConfigurationInterface { /** * {@inheritdoc} */ - public function getConfigTreeBuilder() + public function getConfigTreeBuilder(): TreeBuilder { - $treeBuilder = new TreeBuilder(); + $treeBuilder = new TreeBuilder('fos_oauth_server'); /** @var ArrayNodeDefinition $rootNode */ - $rootNode = $treeBuilder->root('fos_oauth_server'); + $rootNode = $treeBuilder->getRootNode(); $supportedDrivers = ['orm', 'mongodb', 'propel', 'custom']; @@ -43,20 +45,31 @@ public function getConfigTreeBuilder() return $v; } - if (empty($v['service']['client_manager']) || $v['service']['client_manager'] === 'fos_oauth_server.client_manager.default') { - throw new \InvalidArgumentException('The service client_manager must be set explicitly for custom db_driver.'); + if (empty($v['service']['client_manager']) + || + $v['service']['client_manager'] === 'fos_oauth_server.client_manager.default' + ) { + throw new InvalidArgumentException('The service client_manager must be set explicitly for custom db_driver.'); } - if (empty($v['service']['access_token_manager']) || $v['service']['access_token_manager'] === 'fos_oauth_server.access_token_manager.default') { - throw new \InvalidArgumentException('The service access_token_manager must be set explicitly for custom db_driver.'); + if (empty($v['service']['access_token_manager']) + || + $v['service']['access_token_manager'] === 'fos_oauth_server.access_token_manager.default') { + throw new InvalidArgumentException('The service access_token_manager must be set explicitly for custom db_driver.'); } - if (empty($v['service']['refresh_token_manager']) || $v['service']['refresh_token_manager'] === 'fos_oauth_server.refresh_token_manager.default') { - throw new \InvalidArgumentException('The service refresh_token_manager must be set explicitly for custom db_driver.'); + if (empty($v['service']['refresh_token_manager']) + || + $v['service']['refresh_token_manager'] === 'fos_oauth_server.refresh_token_manager.default' + ) { + throw new InvalidArgumentException('The service refresh_token_manager must be set explicitly for custom db_driver.'); } - if (empty($v['service']['auth_code_manager']) || $v['service']['auth_code_manager'] === 'fos_oauth_server.auth_code_manager.default') { - throw new \InvalidArgumentException('The service auth_code_manager must be set explicitly for custom db_driver.'); + if (empty($v['service']['auth_code_manager']) + || + $v['service']['auth_code_manager'] === 'fos_oauth_server.auth_code_manager.default' + ) { + throw new InvalidArgumentException('The service auth_code_manager must be set explicitly for custom db_driver.'); } return $v; @@ -66,7 +79,10 @@ public function getConfigTreeBuilder() ->scalarNode('db_driver') ->validate() ->ifNotInArray($supportedDrivers) - ->thenInvalid('The driver %s is not supported. Please choose one of '.json_encode($supportedDrivers)) + ->thenInvalid( + 'The driver %s is not supported. Please choose one of ' + .json_encode($supportedDrivers) + ) ->end() ->isRequired() ->cannotBeEmpty() @@ -81,12 +97,11 @@ public function getConfigTreeBuilder() $this->addAuthorizeSection($rootNode); $this->addServiceSection($rootNode); - $this->addTemplateSection($rootNode); return $treeBuilder; } - private function addAuthorizeSection(ArrayNodeDefinition $node) + private function addAuthorizeSection(ArrayNodeDefinition $node): void { $node ->children() @@ -97,9 +112,12 @@ private function addAuthorizeSection(ArrayNodeDefinition $node) ->arrayNode('form') ->addDefaultsIfNotSet() ->children() - ->scalarNode('type')->defaultValue('fos_oauth_server_authorize')->end() - ->scalarNode('handler')->defaultValue('fos_oauth_server.authorize.form.handler.default')->end() - ->scalarNode('name')->defaultValue('fos_oauth_server_authorize_form')->cannotBeEmpty()->end() + ->scalarNode('type') + ->defaultValue('fos_oauth_server_authorize')->end() + ->scalarNode('handler') + ->defaultValue('fos_oauth_server.authorize.form.handler.default')->end() + ->scalarNode('name') + ->defaultValue('fos_oauth_server_authorize_form')->cannotBeEmpty()->end() ->arrayNode('validation_groups') ->prototype('scalar')->end() ->defaultValue(['Authorize', 'Default']) @@ -112,7 +130,7 @@ private function addAuthorizeSection(ArrayNodeDefinition $node) ; } - private function addServiceSection(ArrayNodeDefinition $node) + private function addServiceSection(ArrayNodeDefinition $node): void { $node ->addDefaultsIfNotSet() @@ -120,12 +138,18 @@ private function addServiceSection(ArrayNodeDefinition $node) ->arrayNode('service') ->addDefaultsIfNotSet() ->children() - ->scalarNode('storage')->defaultValue('fos_oauth_server.storage.default')->cannotBeEmpty()->end() - ->scalarNode('user_provider')->defaultNull()->end() - ->scalarNode('client_manager')->defaultValue('fos_oauth_server.client_manager.default')->end() - ->scalarNode('access_token_manager')->defaultValue('fos_oauth_server.access_token_manager.default')->end() - ->scalarNode('refresh_token_manager')->defaultValue('fos_oauth_server.refresh_token_manager.default')->end() - ->scalarNode('auth_code_manager')->defaultValue('fos_oauth_server.auth_code_manager.default')->end() + ->scalarNode('storage') + ->defaultValue('fos_oauth_server.storage.default')->cannotBeEmpty()->end() + ->scalarNode('user_provider') + ->defaultNull()->end() + ->scalarNode('client_manager') + ->defaultValue('fos_oauth_server.client_manager.default')->end() + ->scalarNode('access_token_manager') + ->defaultValue('fos_oauth_server.access_token_manager.default')->end() + ->scalarNode('refresh_token_manager') + ->defaultValue('fos_oauth_server.refresh_token_manager.default')->end() + ->scalarNode('auth_code_manager') + ->defaultValue('fos_oauth_server.auth_code_manager.default')->end() ->arrayNode('options') ->useAttributeAsKey('key') ->treatNullLike([]) @@ -137,18 +161,4 @@ private function addServiceSection(ArrayNodeDefinition $node) ->end() ; } - - private function addTemplateSection(ArrayNodeDefinition $node) - { - $node - ->children() - ->arrayNode('template') - ->addDefaultsIfNotSet() - ->children() - ->scalarNode('engine')->defaultValue('twig')->end() - ->end() - ->end() - ->end() - ; - } } diff --git a/DependencyInjection/FOSOAuthServerExtension.php b/DependencyInjection/FOSOAuthServerExtension.php index 256bff31..1a153df9 100644 --- a/DependencyInjection/FOSOAuthServerExtension.php +++ b/DependencyInjection/FOSOAuthServerExtension.php @@ -163,7 +163,7 @@ private function computeArraySupportedScopes(array $supportedScopes) { foreach ($supportedScopes as $scope) { if (false !== mb_strpos($scope, ' ')) { - throw new InvalidConfigurationException('The array notation for supported_scopes should not contain spaces in array items. Either use full array notation or use the string notation for supported_scopes. See https://git.io/vx1X0 for more informations.'); + throw new InvalidConfigurationException('The array notation for supported_scopes should not contain spaces in array items. Either use full array notation or use the string notation for supported_scopes. See https://git.io/vx1X0 for more information.'); } } diff --git a/DependencyInjection/Security/Factory/OAuthFactory.php b/DependencyInjection/Security/Factory/OAuthFactory.php index 62146aa8..4710832b 100644 --- a/DependencyInjection/Security/Factory/OAuthFactory.php +++ b/DependencyInjection/Security/Factory/OAuthFactory.php @@ -15,6 +15,7 @@ use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\SecurityFactoryInterface; use Symfony\Component\Config\Definition\Builder\NodeDefinition; +use Symfony\Component\DependencyInjection\ChildDefinition; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; @@ -28,11 +29,11 @@ class OAuthFactory implements SecurityFactoryInterface /** * {@inheritdoc} */ - public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint) + public function create(ContainerBuilder $container, $id, $config, $userProvider, $defaultEntryPoint): array { // NOTE: done like this to avoid PHPStan complaining about a missing class for both Symfony v3 and Symfony v4 $definitionDecorator = 'Symfony\\Component\\DependencyInjection\\DefinitionDecorator'; - $childDefinition = 'Symfony\\Component\\DependencyInjection\\ChildDefinition'; + $childDefinition = ChildDefinition::class; $definitionClass = $childDefinition; if (class_exists($definitionDecorator)) { $definitionClass = $definitionDecorator; @@ -45,7 +46,10 @@ public function create(ContainerBuilder $container, $id, $config, $userProvider, ; $listenerId = 'security.authentication.listener.fos_oauth_server.'.$id; - $container->setDefinition($listenerId, new $definitionClass('fos_oauth_server.security.authentication.listener')); + $container->setDefinition( + $listenerId, + new $definitionClass('fos_oauth_server.security.authentication.listener') + ); return [$providerId, $listenerId, 'fos_oauth_server.security.entry_point']; } @@ -53,7 +57,7 @@ public function create(ContainerBuilder $container, $id, $config, $userProvider, /** * {@inheritdoc} */ - public function getPosition() + public function getPosition(): string { return 'pre_auth'; } @@ -61,7 +65,7 @@ public function getPosition() /** * {@inheritdoc} */ - public function getKey() + public function getKey(): string { return 'fos_oauth'; } @@ -69,7 +73,7 @@ public function getKey() /** * {@inheritdoc} */ - public function addConfiguration(NodeDefinition $node) + public function addConfiguration(NodeDefinition $node): void { } } diff --git a/Document/AuthCodeManager.php b/Document/AuthCodeManager.php index bdcc2ad1..fe45b735 100644 --- a/Document/AuthCodeManager.php +++ b/Document/AuthCodeManager.php @@ -14,7 +14,7 @@ namespace FOS\OAuthServerBundle\Document; use Doctrine\ODM\MongoDB\DocumentManager; -use Doctrine\ODM\MongoDB\DocumentRepository; +use Doctrine\ODM\MongoDB\Repository\DocumentRepository; use FOS\OAuthServerBundle\Model\AuthCodeInterface; use FOS\OAuthServerBundle\Model\AuthCodeManager as BaseAuthCodeManager; @@ -49,7 +49,7 @@ public function __construct(DocumentManager $dm, $class) /** * {@inheritdoc} */ - public function getClass() + public function getClass(): string { return $this->class; } @@ -65,7 +65,7 @@ public function findAuthCodeBy(array $criteria) /** * {@inheritdoc} */ - public function updateAuthCode(AuthCodeInterface $authCode) + public function updateAuthCode(AuthCodeInterface $authCode): void { $this->dm->persist($authCode); $this->dm->flush(); @@ -74,7 +74,7 @@ public function updateAuthCode(AuthCodeInterface $authCode) /** * {@inheritdoc} */ - public function deleteAuthCode(AuthCodeInterface $authCode) + public function deleteAuthCode(AuthCodeInterface $authCode): void { $this->dm->remove($authCode); $this->dm->flush(); @@ -83,8 +83,9 @@ public function deleteAuthCode(AuthCodeInterface $authCode) /** * {@inheritdoc} */ - public function deleteExpired() + public function deleteExpired(): int { + /** @var \MongoDB\Driver\WriteResult */ $result = $this ->repository ->createQueryBuilder() @@ -94,6 +95,6 @@ public function deleteExpired() ->execute() ; - return $result['n']; + return $result->getDeletedCount(); } } diff --git a/Document/ClientManager.php b/Document/ClientManager.php index 73a95d63..5fde9b3d 100644 --- a/Document/ClientManager.php +++ b/Document/ClientManager.php @@ -14,7 +14,7 @@ namespace FOS\OAuthServerBundle\Document; use Doctrine\ODM\MongoDB\DocumentManager; -use Doctrine\ODM\MongoDB\DocumentRepository; +use Doctrine\ODM\MongoDB\Repository\DocumentRepository; use FOS\OAuthServerBundle\Model\ClientInterface; use FOS\OAuthServerBundle\Model\ClientManager as BaseClientManager; @@ -49,7 +49,7 @@ public function __construct(DocumentManager $dm, $class) /** * {@inheritdoc} */ - public function getClass() + public function getClass(): string { return $this->class; } @@ -65,7 +65,7 @@ public function findClientBy(array $criteria) /** * {@inheritdoc} */ - public function updateClient(ClientInterface $client) + public function updateClient(ClientInterface $client): void { $this->dm->persist($client); $this->dm->flush(); @@ -74,7 +74,7 @@ public function updateClient(ClientInterface $client) /** * {@inheritdoc} */ - public function deleteClient(ClientInterface $client) + public function deleteClient(ClientInterface $client): void { $this->dm->remove($client); $this->dm->flush(); diff --git a/Document/TokenManager.php b/Document/TokenManager.php index 9050924d..5f5fab7a 100644 --- a/Document/TokenManager.php +++ b/Document/TokenManager.php @@ -83,8 +83,9 @@ public function deleteToken(TokenInterface $token) /** * {@inheritdoc} */ - public function deleteExpired() + public function deleteExpired(): int { + /** @var \MongoDB\Driver\WriteResult */ $result = $this ->repository ->createQueryBuilder() @@ -94,6 +95,6 @@ public function deleteExpired() ->execute() ; - return $result['n']; + return $result->getDeletedCount(); } } diff --git a/Entity/AuthCodeManager.php b/Entity/AuthCodeManager.php index 048a9cee..355f2bd2 100644 --- a/Entity/AuthCodeManager.php +++ b/Entity/AuthCodeManager.php @@ -30,8 +30,7 @@ class AuthCodeManager extends BaseAuthCodeManager protected $class; /** - * @param EntityManagerInterface $em - * @param string $class + * @param string $class */ public function __construct(EntityManagerInterface $em, $class) { diff --git a/Event/OAuthEvent.php b/Event/OAuthEvent.php index f686e4df..c0834d11 100644 --- a/Event/OAuthEvent.php +++ b/Event/OAuthEvent.php @@ -14,14 +14,13 @@ namespace FOS\OAuthServerBundle\Event; use FOS\OAuthServerBundle\Model\ClientInterface; -use Symfony\Component\EventDispatcher\Event; use Symfony\Component\Security\Core\User\UserInterface; +use Symfony\Contracts\EventDispatcher\Event; class OAuthEvent extends Event { - const PRE_AUTHORIZATION_PROCESS = 'fos_oauth_server.pre_authorization_process'; - - const POST_AUTHORIZATION_PROCESS = 'fos_oauth_server.post_authorization_process'; + public const PRE_AUTHORIZATION_PROCESS = 'fos_oauth_server.pre_authorization_process'; + public const POST_AUTHORIZATION_PROCESS = 'fos_oauth_server.post_authorization_process'; /** * @var UserInterface @@ -39,9 +38,7 @@ class OAuthEvent extends Event private $isAuthorizedClient; /** - * @param UserInterface $user - * @param ClientInterface $client - * @param bool $isAuthorizedClient + * @param bool $isAuthorizedClient */ public function __construct(UserInterface $user, ClientInterface $client, $isAuthorizedClient = false) { @@ -50,10 +47,7 @@ public function __construct(UserInterface $user, ClientInterface $client, $isAut $this->isAuthorizedClient = $isAuthorizedClient; } - /** - * @return UserInterface - */ - public function getUser() + public function getUser(): UserInterface { return $this->user; } @@ -61,23 +55,17 @@ public function getUser() /** * @param bool $isAuthorizedClient */ - public function setAuthorizedClient($isAuthorizedClient) + public function setAuthorizedClient($isAuthorizedClient): void { $this->isAuthorizedClient = $isAuthorizedClient; } - /** - * @return bool - */ - public function isAuthorizedClient() + public function isAuthorizedClient(): bool { return $this->isAuthorizedClient; } - /** - * @return ClientInterface - */ - public function getClient() + public function getClient(): ClientInterface { return $this->client; } diff --git a/FOSOAuthServerBundle.php b/FOSOAuthServerBundle.php index c6ba0f9f..1505745d 100644 --- a/FOSOAuthServerBundle.php +++ b/FOSOAuthServerBundle.php @@ -15,7 +15,6 @@ use FOS\OAuthServerBundle\DependencyInjection\Compiler\GrantExtensionsCompilerPass; use FOS\OAuthServerBundle\DependencyInjection\Compiler\RequestStackCompilerPass; -use FOS\OAuthServerBundle\DependencyInjection\Compiler\TokenStorageCompilerPass; use FOS\OAuthServerBundle\DependencyInjection\FOSOAuthServerExtension; use FOS\OAuthServerBundle\DependencyInjection\Security\Factory\OAuthFactory; use Symfony\Bundle\SecurityBundle\DependencyInjection\SecurityExtension; @@ -38,7 +37,6 @@ public function build(ContainerBuilder $container) $extension->addSecurityListenerFactory(new OAuthFactory()); $container->addCompilerPass(new GrantExtensionsCompilerPass()); - $container->addCompilerPass(new TokenStorageCompilerPass()); $container->addCompilerPass(new RequestStackCompilerPass()); } } diff --git a/Form/Handler/AuthorizeFormHandler.php b/Form/Handler/AuthorizeFormHandler.php index df219c04..4f29097d 100644 --- a/Form/Handler/AuthorizeFormHandler.php +++ b/Form/Handler/AuthorizeFormHandler.php @@ -40,7 +40,6 @@ class AuthorizeFormHandler private $requestStack; /** - * @param FormInterface $form * @param Request|RequestStack $requestStack */ public function __construct(FormInterface $form, $requestStack = null) @@ -94,7 +93,7 @@ public function process() } $this->form->handleRequest($request); - if (!$this->form->isValid()) { + if ($this->form->isSubmitted() && $this->form->isValid() === false) { return false; } diff --git a/Form/Model/Authorize.php b/Form/Model/Authorize.php index fa639ea5..0811c81e 100644 --- a/Form/Model/Authorize.php +++ b/Form/Model/Authorize.php @@ -48,10 +48,6 @@ class Authorize */ public $scope; - /** - * @param bool $accepted - * @param array $query - */ public function __construct(bool $accepted, array $query = []) { foreach ($query as $key => $value) { diff --git a/Form/Type/AuthorizeFormType.php b/Form/Type/AuthorizeFormType.php index 08aec45f..cfecf2a1 100644 --- a/Form/Type/AuthorizeFormType.php +++ b/Form/Type/AuthorizeFormType.php @@ -41,6 +41,7 @@ public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => 'FOS\OAuthServerBundle\Form\Model\Authorize', + 'validation_groups' => [], ]); } diff --git a/Model/AuthCodeManagerInterface.php b/Model/AuthCodeManagerInterface.php index 2239a849..23811b0d 100644 --- a/Model/AuthCodeManagerInterface.php +++ b/Model/AuthCodeManagerInterface.php @@ -35,8 +35,6 @@ public function getClass(); /** * Retrieve an auth code using a set of criteria. * - * @param array $criteria - * * @return AuthCodeInterface|null */ public function findAuthCodeBy(array $criteria); @@ -52,15 +50,11 @@ public function findAuthCodeByToken($token); /** * Update a given auth code. - * - * @param AuthCodeInterface $authCode */ public function updateAuthCode(AuthCodeInterface $authCode); /** * Delete a given auth code. - * - * @param AuthCodeInterface $authCode */ public function deleteAuthCode(AuthCodeInterface $authCode); diff --git a/Model/ClientInterface.php b/Model/ClientInterface.php index 1a179bee..c985d847 100644 --- a/Model/ClientInterface.php +++ b/Model/ClientInterface.php @@ -44,14 +44,8 @@ public function checkSecret($secret); */ public function getSecret(); - /** - * @param array $redirectUris - */ public function setRedirectUris(array $redirectUris); - /** - * @param array $grantTypes - */ public function setAllowedGrantTypes(array $grantTypes); /** diff --git a/Model/ClientManagerInterface.php b/Model/ClientManagerInterface.php index c62b542d..31b3ed38 100644 --- a/Model/ClientManagerInterface.php +++ b/Model/ClientManagerInterface.php @@ -26,24 +26,18 @@ public function createClient(); public function getClass(); /** - * @return null|ClientInterface + * @return ClientInterface|null */ public function findClientBy(array $criteria); /** * @param mixed $publicId * - * @return null|ClientInterface + * @return ClientInterface|null */ public function findClientByPublicId($publicId); - /** - * @param ClientInterface $client - */ public function updateClient(ClientInterface $client); - /** - * @param ClientInterface $client - */ public function deleteClient(ClientInterface $client); } diff --git a/Model/TokenInterface.php b/Model/TokenInterface.php index f6dcf3aa..3d32ef23 100644 --- a/Model/TokenInterface.php +++ b/Model/TokenInterface.php @@ -38,9 +38,6 @@ public function setToken($token); */ public function setScope($scope); - /** - * @param UserInterface $user - */ public function setUser(UserInterface $user); /** @@ -48,8 +45,5 @@ public function setUser(UserInterface $user); */ public function getUser(); - /** - * @param ClientInterface $client - */ public function setClient(ClientInterface $client); } diff --git a/Model/TokenManagerInterface.php b/Model/TokenManagerInterface.php index e6688dd8..efbd9377 100644 --- a/Model/TokenManagerInterface.php +++ b/Model/TokenManagerInterface.php @@ -32,8 +32,6 @@ public function getClass(); /** * Retrieve a token using a set of criteria. * - * @param array $criteria - * * @return TokenInterface|null */ public function findTokenBy(array $criteria); diff --git a/Resources/config/authorize.xml b/Resources/config/authorize.xml index add0e780..540ac0e5 100644 --- a/Resources/config/authorize.xml +++ b/Resources/config/authorize.xml @@ -28,13 +28,12 @@ - + - %fos_oauth_server.template.engine% diff --git a/Resources/doc/configuration_reference.md b/Resources/doc/configuration_reference.md index 9529fa32..deade0e9 100644 --- a/Resources/doc/configuration_reference.md +++ b/Resources/doc/configuration_reference.md @@ -50,8 +50,6 @@ fos_oauth_server: # Enforce state to be passed in authorization (see RFC 6749, section 10.12) #enforce_state: true or false - template: - engine: twig ``` [Back to index](index.md) diff --git a/Security/Authentication/Provider/OAuthProvider.php b/Security/Authentication/Provider/OAuthProvider.php index bb11eae6..33089ecb 100644 --- a/Security/Authentication/Provider/OAuthProvider.php +++ b/Security/Authentication/Provider/OAuthProvider.php @@ -60,7 +60,7 @@ public function __construct(UserProviderInterface $userProvider, OAuth2 $serverS /** * @param OAuthToken&TokenInterface $token * - * @return null|OAuthToken + * @return OAuthToken|null */ public function authenticate(TokenInterface $token) { @@ -85,12 +85,7 @@ public function authenticate(TokenInterface $token) try { $this->userChecker->checkPreAuth($user); } catch (AccountStatusException $e) { - throw new OAuth2AuthenticateException(Response::HTTP_UNAUTHORIZED, - OAuth2::TOKEN_TYPE_BEARER, - $this->serverService->getVariable(OAuth2::CONFIG_WWW_REALM), - 'access_denied', - $e->getMessage() - ); + throw new OAuth2AuthenticateException(Response::HTTP_UNAUTHORIZED, OAuth2::TOKEN_TYPE_BEARER, $this->serverService->getVariable(OAuth2::CONFIG_WWW_REALM), 'access_denied', $e->getMessage()); } $token->setUser($user); @@ -114,12 +109,7 @@ public function authenticate(TokenInterface $token) try { $this->userChecker->checkPostAuth($user); } catch (AccountStatusException $e) { - throw new OAuth2AuthenticateException(Response::HTTP_UNAUTHORIZED, - OAuth2::TOKEN_TYPE_BEARER, - $this->serverService->getVariable(OAuth2::CONFIG_WWW_REALM), - 'access_denied', - $e->getMessage() - ); + throw new OAuth2AuthenticateException(Response::HTTP_UNAUTHORIZED, OAuth2::TOKEN_TYPE_BEARER, $this->serverService->getVariable(OAuth2::CONFIG_WWW_REALM), 'access_denied', $e->getMessage()); } $token->setUser($user); diff --git a/Security/Firewall/OAuthListener.php b/Security/Firewall/OAuthListener.php index 914fcb9e..7546b2e4 100644 --- a/Security/Firewall/OAuthListener.php +++ b/Security/Firewall/OAuthListener.php @@ -16,19 +16,18 @@ use FOS\OAuthServerBundle\Security\Authentication\Token\OAuthToken; use OAuth2\OAuth2; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Exception\AuthenticationException; -use Symfony\Component\Security\Http\Firewall\ListenerInterface; /** * OAuthListener class. * * @author Arnaud Le Blanc */ -class OAuthListener implements ListenerInterface +class OAuthListener { /** * @var TokenStorageInterface @@ -48,19 +47,23 @@ class OAuthListener implements ListenerInterface /** * @param TokenStorageInterface $tokenStorage the token storage * @param AuthenticationManagerInterface $authenticationManager the authentication manager - * @param OAuth2 $serverService */ - public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, OAuth2 $serverService) - { + public function __construct( + TokenStorageInterface $tokenStorage, + AuthenticationManagerInterface $authenticationManager, + OAuth2 $serverService + ) { $this->tokenStorage = $tokenStorage; $this->authenticationManager = $authenticationManager; $this->serverService = $serverService; } - /** - * @param GetResponseEvent $event the event - */ - public function handle(GetResponseEvent $event) + public function __invoke(RequestEvent $event) + { + $this->handle($event); + } + + public function handle(RequestEvent $event): void { if (null === $oauthToken = $this->serverService->getBearerToken($event->getRequest(), true)) { return; @@ -70,14 +73,12 @@ public function handle(GetResponseEvent $event) $token->setToken($oauthToken); try { - $returnValue = $this->authenticationManager->authenticate($token); - - if ($returnValue instanceof TokenInterface) { - return $this->tokenStorage->setToken($returnValue); - } + $authenticateResult = $this->authenticationManager->authenticate($token); - if ($returnValue instanceof Response) { - return $event->setResponse($returnValue); + if ($authenticateResult instanceof TokenInterface) { + $this->tokenStorage->setToken($authenticateResult); + } elseif ($authenticateResult instanceof Response) { + $event->setResponse($authenticateResult); } } catch (AuthenticationException $e) { if (null !== $p = $e->getPrevious()) { diff --git a/Storage/OAuthStorage.php b/Storage/OAuthStorage.php index a56dd25a..9b6d1f02 100644 --- a/Storage/OAuthStorage.php +++ b/Storage/OAuthStorage.php @@ -14,10 +14,13 @@ namespace FOS\OAuthServerBundle\Storage; use FOS\OAuthServerBundle\Model\AccessTokenManagerInterface; +use FOS\OAuthServerBundle\Model\AuthCodeInterface; use FOS\OAuthServerBundle\Model\AuthCodeManagerInterface; use FOS\OAuthServerBundle\Model\ClientInterface; use FOS\OAuthServerBundle\Model\ClientManagerInterface; use FOS\OAuthServerBundle\Model\RefreshTokenManagerInterface; +use FOS\OAuthServerBundle\Model\TokenInterface; +use InvalidArgumentException; use OAuth2\IOAuth2GrantClient; use OAuth2\IOAuth2GrantCode; use OAuth2\IOAuth2GrantExtension; @@ -69,18 +72,14 @@ class OAuthStorage implements IOAuth2RefreshTokens, IOAuth2GrantUser, IOAuth2Gra */ protected $grantExtensions; - /** - * @param ClientManagerInterface $clientManager - * @param AccessTokenManagerInterface $accessTokenManager - * @param RefreshTokenManagerInterface $refreshTokenManager - * @param AuthCodeManagerInterface $authCodeManager - * @param null|UserProviderInterface $userProvider - * @param null|EncoderFactoryInterface $encoderFactory - */ - public function __construct(ClientManagerInterface $clientManager, AccessTokenManagerInterface $accessTokenManager, - RefreshTokenManagerInterface $refreshTokenManager, AuthCodeManagerInterface $authCodeManager, - UserProviderInterface $userProvider = null, EncoderFactoryInterface $encoderFactory = null) - { + public function __construct( + ClientManagerInterface $clientManager, + AccessTokenManagerInterface $accessTokenManager, + RefreshTokenManagerInterface $refreshTokenManager, + AuthCodeManagerInterface $authCodeManager, + UserProviderInterface $userProvider = null, + EncoderFactoryInterface $encoderFactory = null + ) { $this->clientManager = $clientManager; $this->accessTokenManager = $accessTokenManager; $this->refreshTokenManager = $refreshTokenManager; @@ -107,7 +106,7 @@ public function getClient($clientId) public function checkClientCredentials(IOAuth2Client $client, $client_secret = null) { if (!$client instanceof ClientInterface) { - throw new \InvalidArgumentException('Client has to implement the ClientInterface'); + throw new InvalidArgumentException('Client has to implement the ClientInterface'); } return $client->checkSecret($client_secret); @@ -123,10 +122,15 @@ public function getAccessToken($token) return $this->accessTokenManager->findTokenByToken($token); } - public function createAccessToken($tokenString, IOAuth2Client $client, $data, $expires, $scope = null) - { + public function createAccessToken( + $tokenString, + IOAuth2Client $client, + $data, + $expires, + $scope = null + ): TokenInterface { if (!$client instanceof ClientInterface) { - throw new \InvalidArgumentException('Client has to implement the ClientInterface'); + throw new InvalidArgumentException('Client has to implement the ClientInterface'); } $token = $this->accessTokenManager->createToken(); @@ -147,7 +151,7 @@ public function createAccessToken($tokenString, IOAuth2Client $client, $data, $e public function checkRestrictedGrantType(IOAuth2Client $client, $grant_type) { if (!$client instanceof ClientInterface) { - throw new \InvalidArgumentException('Client has to implement the ClientInterface'); + throw new InvalidArgumentException('Client has to implement the ClientInterface'); } return in_array($grant_type, $client->getAllowedGrantTypes(), true); @@ -156,7 +160,7 @@ public function checkRestrictedGrantType(IOAuth2Client $client, $grant_type) public function checkUserCredentials(IOAuth2Client $client, $username, $password) { if (!$client instanceof ClientInterface) { - throw new \InvalidArgumentException('Client has to implement the ClientInterface'); + throw new InvalidArgumentException('Client has to implement the ClientInterface'); } try { @@ -186,10 +190,16 @@ public function getAuthCode($code) /** * {@inheritdoc} */ - public function createAuthCode($code, IOAuth2Client $client, $data, $redirect_uri, $expires, $scope = null) - { + public function createAuthCode( + $code, + IOAuth2Client $client, + $data, + $redirect_uri, + $expires, + $scope = null + ): AuthCodeInterface { if (!$client instanceof ClientInterface) { - throw new \InvalidArgumentException('Client has to implement the ClientInterface'); + throw new InvalidArgumentException('Client has to implement the ClientInterface'); } $authCode = $this->authCodeManager->createAuthCode(); @@ -218,7 +228,7 @@ public function getRefreshToken($tokenString) public function createRefreshToken($tokenString, IOAuth2Client $client, $data, $expires, $scope = null) { if (!$client instanceof ClientInterface) { - throw new \InvalidArgumentException('Client has to implement the ClientInterface'); + throw new InvalidArgumentException('Client has to implement the ClientInterface'); } $token = $this->refreshTokenManager->createToken(); diff --git a/Tests/Command/CleanCommandTest.php b/Tests/Command/CleanCommandTest.php index 92dbb9a9..99aa0d26 100644 --- a/Tests/Command/CleanCommandTest.php +++ b/Tests/Command/CleanCommandTest.php @@ -16,10 +16,12 @@ use FOS\OAuthServerBundle\Command\CleanCommand; use FOS\OAuthServerBundle\Model\AuthCodeManagerInterface; use FOS\OAuthServerBundle\Model\TokenManagerInterface; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Application; use Symfony\Component\Console\Tester\CommandTester; -class CleanCommandTest extends \PHPUnit\Framework\TestCase +class CleanCommandTest extends TestCase { /** * @var CleanCommand @@ -27,24 +29,24 @@ class CleanCommandTest extends \PHPUnit\Framework\TestCase private $command; /** - * @var \PHPUnit_Framework_MockObject_MockObject|TokenManagerInterface + * @var MockObject|TokenManagerInterface */ private $accessTokenManager; /** - * @var \PHPUnit_Framework_MockObject_MockObject|TokenManagerInterface + * @var MockObject|TokenManagerInterface */ private $refreshTokenManager; /** - * @var \PHPUnit_Framework_MockObject_MockObject|AuthCodeManagerInterface + * @var MockObject|AuthCodeManagerInterface */ private $authCodeManager; /** * {@inheritdoc} */ - protected function setUp() + protected function setUp(): void { $this->accessTokenManager = $this->getMockBuilder(TokenManagerInterface::class)->disableOriginalConstructor()->getMock(); $this->refreshTokenManager = $this->getMockBuilder(TokenManagerInterface::class)->disableOriginalConstructor()->getMock(); @@ -64,27 +66,27 @@ protected function setUp() /** * Delete expired tokens for provided classes. */ - public function testItShouldRemoveExpiredToken() + public function testItShouldRemoveExpiredToken(): void { $expiredAccessTokens = 5; $this->accessTokenManager ->expects($this->once()) ->method('deleteExpired') - ->will($this->returnValue($expiredAccessTokens)) + ->willReturn($expiredAccessTokens) ; $expiredRefreshTokens = 183; $this->refreshTokenManager ->expects($this->once()) ->method('deleteExpired') - ->will($this->returnValue($expiredRefreshTokens)) + ->willReturn($expiredRefreshTokens) ; $expiredAuthCodes = 0; $this->authCodeManager ->expects($this->once()) ->method('deleteExpired') - ->will($this->returnValue($expiredAuthCodes)) + ->willReturn($expiredAuthCodes) ; $tester = new CommandTester($this->command); @@ -92,15 +94,15 @@ public function testItShouldRemoveExpiredToken() $display = $tester->getDisplay(); - $this->assertContains(sprintf('Removed %d items from %s storage.', $expiredAccessTokens, get_class($this->accessTokenManager)), $display); - $this->assertContains(sprintf('Removed %d items from %s storage.', $expiredRefreshTokens, get_class($this->refreshTokenManager)), $display); - $this->assertContains(sprintf('Removed %d items from %s storage.', $expiredAuthCodes, get_class($this->authCodeManager)), $display); + self::assertStringContainsString(sprintf('Removed %d items from %s storage.', $expiredAccessTokens, get_class($this->accessTokenManager)), $display); + self::assertStringContainsString(sprintf('Removed %d items from %s storage.', $expiredRefreshTokens, get_class($this->refreshTokenManager)), $display); + self::assertStringContainsString(sprintf('Removed %d items from %s storage.', $expiredAuthCodes, get_class($this->authCodeManager)), $display); } /** * Skip classes for deleting expired tokens that do not implement AuthCodeManagerInterface or TokenManagerInterface. */ - public function testItShouldNotRemoveExpiredTokensForOtherClasses() + public function testItShouldNotRemoveExpiredTokensForOtherClasses(): void { $this->markTestIncomplete('Needs a better way of testing this'); @@ -109,8 +111,8 @@ public function testItShouldNotRemoveExpiredTokensForOtherClasses() $display = $tester->getDisplay(); - $this->assertNotRegExp(sprintf('\'Removed (\d)+ items from %s storage.\'', get_class($this->accessTokenManager)), $display); - $this->assertNotRegExp(sprintf('\'Removed (\d)+ items from %s storage.\'', get_class($this->refreshTokenManager)), $display); - $this->assertNotRegExp(sprintf('\'Removed (\d)+ items from %s storage.\'', get_class($this->authCodeManager)), $display); + self::assertNotRegExp(sprintf('\'Removed (\d)+ items from %s storage.\'', get_class($this->accessTokenManager)), $display); + self::assertNotRegExp(sprintf('\'Removed (\d)+ items from %s storage.\'', get_class($this->refreshTokenManager)), $display); + self::assertNotRegExp(sprintf('\'Removed (\d)+ items from %s storage.\'', get_class($this->authCodeManager)), $display); } } diff --git a/Tests/Command/CreateClientCommandTest.php b/Tests/Command/CreateClientCommandTest.php index 4a50b206..fd088bc8 100644 --- a/Tests/Command/CreateClientCommandTest.php +++ b/Tests/Command/CreateClientCommandTest.php @@ -14,8 +14,10 @@ namespace FOS\OAuthServerBundle\Tests\Command; use FOS\OAuthServerBundle\Command\CreateClientCommand; +use FOS\OAuthServerBundle\Document\Client; use FOS\OAuthServerBundle\Model\ClientManagerInterface; use FOS\OAuthServerBundle\Tests\TestCase; +use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\Console\Application; use Symfony\Component\Console\Tester\CommandTester; @@ -27,16 +29,20 @@ class CreateClientCommandTest extends TestCase private $command; /** - * @var \PHPUnit_Framework_MockObject_MockObject|ClientManagerInterface + * @var MockObject|ClientManagerInterface */ private $clientManager; /** * {@inheritdoc} */ - protected function setUp() + protected function setUp(): void { - $this->clientManager = $this->getMockBuilder(ClientManagerInterface::class)->disableOriginalConstructor()->getMock(); + $this->clientManager = + $this->getMockBuilder(ClientManagerInterface::class) + ->disableOriginalConstructor() + ->getMock() + ; $command = new CreateClientCommand($this->clientManager); $application = new Application(); @@ -53,13 +59,12 @@ protected function setUp() * * @param string $client a fully qualified class name */ - public function testItShouldCreateClient($client) + public function testItShouldCreateClient($client): void { $this ->clientManager - ->expects($this->any()) ->method('createClient') - ->will($this->returnValue(new $client())) + ->willReturn(new $client()) ; $commandTester = new CommandTester($this->command); @@ -76,24 +81,21 @@ public function testItShouldCreateClient($client) ], ]); - $this->assertSame(0, $commandTester->getStatusCode()); + self::assertSame(0, $commandTester->getStatusCode()); $output = $commandTester->getDisplay(); - $this->assertContains('Client ID', $output); - $this->assertContains('Client Secret', $output); + self::assertStringContainsString('Client ID', $output); + self::assertStringContainsString('Client Secret', $output); } - /** - * @return array - */ - public function clientProvider() + public function clientProvider(): array { return [ - ['FOS\OAuthServerBundle\Document\Client'], - ['FOS\OAuthServerBundle\Entity\Client'], - ['FOS\OAuthServerBundle\Model\Client'], - ['FOS\OAuthServerBundle\Propel\Client'], + [Client::class], + [\FOS\OAuthServerBundle\Entity\Client::class], + [\FOS\OAuthServerBundle\Model\Client::class], + [\FOS\OAuthServerBundle\Propel\Client::class], ]; } } diff --git a/Tests/Controller/AuthorizeControllerFunctionalTest.php b/Tests/Controller/AuthorizeControllerFunctionalTest.php new file mode 100644 index 00000000..40c76c31 --- /dev/null +++ b/Tests/Controller/AuthorizeControllerFunctionalTest.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\OAuthServerBundle\Tests\Controller; + +use FOS\OAuthServerBundle\Tests\Functional\TestCase; +use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; +use Symfony\Component\Security\Core\Exception\AccessDeniedException; +use Symfony\Component\Security\Core\User\UserInterface; +use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken; + +class AuthorizeControllerFunctionalTest extends TestCase +{ + public function setUp(): void + { + parent::setUp(); + + $this->client = $this->createClient(); + } + + public function tearDown(): void + { + unset($this->client); + + parent::tearDown(); + } + + public function testAuthorizeActionWillThrowAccessDeniedException(): void + { + self::$kernel->getContainer()->get('security.token_storage')->setToken(new AnonymousToken('test-secret', 'anon')); + + $this->expectException(AccessDeniedException::class); + $this->expectExceptionMessage('This user does not have access to this section.'); + + $this->client->catchExceptions(false); + $this->client->request('GET', '/oauth/v2/auth'); + } + + public function testAuthorizeActionWillRenderTemplate(): void + { + $user = $this->getMockBuilder(UserInterface::class) + ->disableOriginalConstructor() + ->getMock() + ; + + self::$kernel->getContainer()->get('security.token_storage')->setToken( + new PostAuthenticationGuardToken($user, 'member_area', ['ROLE_USER']) + ); + + $this->client->catchExceptions(false); + $this->client->request('GET', '/oauth/v2/auth', [ + 'client_id' => '123_test-client-id', + ]); + + $this->assertResponse(200, '
'); + } + + public function testAuthorizeActionWillFinishClientAuthorization(): void + { + // TODO: refactor unit AuthorizeControllerTest as functional test here + $this->assertTrue(true); + } + + public function testAuthorizeActionWillEnsureLogout(): void + { + // TODO: refactor unit AuthorizeControllerTest as functional test here + $this->assertTrue(true); + } + + public function testAuthorizeActionWillProcessAuthorizationForm(): void + { + // TODO: refactor unit AuthorizeControllerTest as functional test here + $this->assertTrue(true); + } +} diff --git a/Tests/Controller/AuthorizeControllerTest.php b/Tests/Controller/AuthorizeControllerTest.php index 5aeaf585..2b11c788 100644 --- a/Tests/Controller/AuthorizeControllerTest.php +++ b/Tests/Controller/AuthorizeControllerTest.php @@ -19,7 +19,9 @@ use FOS\OAuthServerBundle\Model\ClientInterface; use FOS\OAuthServerBundle\Model\ClientManagerInterface; use OAuth2\OAuth2; -use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; +use ReflectionProperty; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\Form\Form; use Symfony\Component\Form\FormView; @@ -31,107 +33,102 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AccessDeniedException; use Symfony\Component\Security\Core\User\UserInterface; +use Twig\Environment; -class AuthorizeControllerTest extends \PHPUnit\Framework\TestCase +class AuthorizeControllerTest extends TestCase { /** - * @var \PHPUnit_Framework_MockObject_MockObject|RequestStack + * @var MockObject|RequestStack */ protected $requestStack; /** - * @var \PHPUnit_Framework_MockObject_MockObject|SessionInterface + * @var MockObject|SessionInterface */ protected $session; /** - * @var \PHPUnit_Framework_MockObject_MockObject|Form + * @var MockObject|Form */ protected $form; /** - * @var \PHPUnit_Framework_MockObject_MockObject|AuthorizeFormHandler + * @var MockObject|AuthorizeFormHandler */ protected $authorizeFormHandler; /** - * @var \PHPUnit_Framework_MockObject_MockObject|OAuth2 + * @var MockObject|OAuth2 */ protected $oAuth2Server; /** - * @var \PHPUnit_Framework_MockObject_MockObject|EngineInterface + * @var MockObject|Environment */ - protected $templateEngine; + protected $twig; /** - * @var \PHPUnit_Framework_MockObject_MockObject|TokenStorageInterface + * @var MockObject|TokenStorageInterface */ protected $tokenStorage; /** - * @var \PHPUnit_Framework_MockObject_MockObject|UrlGeneratorInterface + * @var MockObject|UrlGeneratorInterface */ protected $router; /** - * @var \PHPUnit_Framework_MockObject_MockObject|ClientManagerInterface + * @var MockObject|ClientManagerInterface */ protected $clientManager; /** - * @var \PHPUnit_Framework_MockObject_MockObject|EventDispatcherInterface + * @var MockObject|EventDispatcherInterface */ protected $eventDispatcher; - /** - * @var string - */ - protected $templateEngineType; - /** * @var AuthorizeController */ protected $instance; /** - * @var \PHPUnit_Framework_MockObject_MockObject|Request + * @var MockObject|Request */ protected $request; /** - * @var \PHPUnit_Framework_MockObject_MockObject|ParameterBag + * @var MockObject|ParameterBag */ protected $requestQuery; /** - * @var \PHPUnit_Framework_MockObject_MockObject|ParameterBag + * @var MockObject|ParameterBag */ protected $requestRequest; /** - * @var \PHPUnit_Framework_MockObject_MockObject|UserInterface + * @var MockObject|UserInterface */ protected $user; /** - * @var \PHPUnit_Framework_MockObject_MockObject|ClientInterface + * @var MockObject|ClientInterface */ protected $client; /** - * @var \PHPUnit_Framework_MockObject_MockObject|OAuthEvent + * @var MockObject|OAuthEvent */ protected $event; /** - * @var \PHPUnit_Framework_MockObject_MockObject|FormView + * @var MockObject|FormView */ protected $formView; - public function setUp() + public function setUp(): void { $this->requestStack = $this->getMockBuilder(RequestStack::class) ->disableOriginalConstructor() @@ -149,7 +146,7 @@ public function setUp() ->disableOriginalConstructor() ->getMock() ; - $this->templateEngine = $this->getMockBuilder(EngineInterface::class) + $this->twig = $this->getMockBuilder(Environment::class) ->disableOriginalConstructor() ->getMock() ; @@ -173,23 +170,21 @@ public function setUp() ->disableOriginalConstructor() ->getMock() ; - $this->templateEngineType = 'twig'; $this->instance = new AuthorizeController( $this->requestStack, $this->form, $this->authorizeFormHandler, $this->oAuth2Server, - $this->templateEngine, + $this->twig, $this->tokenStorage, $this->router, $this->clientManager, $this->eventDispatcher, - $this->session, - $this->templateEngineType + $this->session ); - /** @var \PHPUnit_Framework_MockObject_MockObject&Request $request */ + /** @var MockObject&Request $request */ $request = $this->getMockBuilder(Request::class) ->disableOriginalConstructor() ->getMock() @@ -225,107 +220,7 @@ public function setUp() parent::setUp(); } - public function testAuthorizeActionWillThrowAccessDeniedException() - { - $token = $this->getMockBuilder(TokenInterface::class) - ->disableOriginalConstructor() - ->getMock() - ; - - $this->tokenStorage - ->expects($this->at(0)) - ->method('getToken') - ->willReturn($token) - ; - - $token - ->expects($this->at(0)) - ->method('getUser') - ->willReturn(null) - ; - - $this->expectException(AccessDeniedException::class); - $this->expectExceptionMessage('This user does not have access to this section.'); - - $this->instance->authorizeAction($this->request); - } - - public function testAuthorizeActionWillRenderTemplate() - { - $token = $this->getMockBuilder(TokenInterface::class) - ->disableOriginalConstructor() - ->getMock() - ; - - $this->tokenStorage - ->expects($this->at(0)) - ->method('getToken') - ->willReturn($token) - ; - - $token - ->expects($this->at(0)) - ->method('getUser') - ->willReturn($this->user) - ; - - $this->session - ->expects($this->at(0)) - ->method('get') - ->with('_fos_oauth_server.ensure_logout') - ->willReturn(false) - ; - - $propertyReflection = new \ReflectionProperty(AuthorizeController::class, 'client'); - $propertyReflection->setAccessible(true); - $propertyReflection->setValue($this->instance, $this->client); - - $this->eventDispatcher - ->expects($this->at(0)) - ->method('dispatch') - ->with(OAuthEvent::PRE_AUTHORIZATION_PROCESS, new OAuthEvent($this->user, $this->client)) - ->willReturn($this->event) - ; - - $this->event - ->expects($this->at(0)) - ->method('isAuthorizedClient') - ->with() - ->willReturn(false) - ; - - $this->authorizeFormHandler - ->expects($this->at(0)) - ->method('process') - ->with() - ->willReturn(false) - ; - - $this->form - ->expects($this->at(0)) - ->method('createView') - ->willReturn($this->formView) - ; - - $response = new Response(); - - $this->templateEngine - ->expects($this->at(0)) - ->method('renderResponse') - ->with( - '@FOSOAuthServer/Authorize/authorize.html.twig', - [ - 'form' => $this->formView, - 'client' => $this->client, - ] - ) - ->willReturn($response) - ; - - $this->assertSame($response, $this->instance->authorizeAction($this->request)); - } - - public function testAuthorizeActionWillFinishClientAuthorization() + public function testAuthorizeActionWillFinishClientAuthorization(): void { $token = $this->getMockBuilder(TokenInterface::class) ->disableOriginalConstructor() @@ -351,14 +246,14 @@ public function testAuthorizeActionWillFinishClientAuthorization() ->willReturn(false) ; - $propertyReflection = new \ReflectionProperty(AuthorizeController::class, 'client'); + $propertyReflection = new ReflectionProperty(AuthorizeController::class, 'client'); $propertyReflection->setAccessible(true); $propertyReflection->setValue($this->instance, $this->client); $this->eventDispatcher ->expects($this->at(0)) ->method('dispatch') - ->with(OAuthEvent::PRE_AUTHORIZATION_PROCESS, new OAuthEvent($this->user, $this->client)) + ->with(new OAuthEvent($this->user, $this->client), OAuthEvent::PRE_AUTHORIZATION_PROCESS) ->willReturn($this->event) ; @@ -392,10 +287,10 @@ public function testAuthorizeActionWillFinishClientAuthorization() ->willReturn($response) ; - $this->assertSame($response, $this->instance->authorizeAction($this->request)); + self::assertSame($response, $this->instance->authorizeAction($this->request)); } - public function testAuthorizeActionWillEnsureLogout() + public function testAuthorizeActionWillEnsureLogout(): void { $token = $this->getMockBuilder(TokenInterface::class) ->disableOriginalConstructor() @@ -435,14 +330,14 @@ public function testAuthorizeActionWillEnsureLogout() ->willReturn(null) ; - $propertyReflection = new \ReflectionProperty(AuthorizeController::class, 'client'); + $propertyReflection = new ReflectionProperty(AuthorizeController::class, 'client'); $propertyReflection->setAccessible(true); $propertyReflection->setValue($this->instance, $this->client); $this->eventDispatcher ->expects($this->at(0)) ->method('dispatch') - ->with(OAuthEvent::PRE_AUTHORIZATION_PROCESS, new OAuthEvent($this->user, $this->client)) + ->with(new OAuthEvent($this->user, $this->client), OAuthEvent::PRE_AUTHORIZATION_PROCESS) ->willReturn($this->event) ; @@ -466,11 +361,9 @@ public function testAuthorizeActionWillEnsureLogout() ->willReturn($this->formView) ; - $response = new Response(); - - $this->templateEngine + $this->twig ->expects($this->at(0)) - ->method('renderResponse') + ->method('render') ->with( '@FOSOAuthServer/Authorize/authorize.html.twig', [ @@ -478,13 +371,15 @@ public function testAuthorizeActionWillEnsureLogout() 'client' => $this->client, ] ) - ->willReturn($response) + ->willReturn('') ; - $this->assertSame($response, $this->instance->authorizeAction($this->request)); + $response = $this->instance->authorizeAction($this->request); + self::assertInstanceOf(Response::class, $response); + self::assertSame('', $response->getContent()); } - public function testAuthorizeActionWillProcessAuthorizationForm() + public function testAuthorizeActionWillProcessAuthorizationForm(): void { $token = $this->getMockBuilder(TokenInterface::class) ->disableOriginalConstructor() @@ -510,14 +405,14 @@ public function testAuthorizeActionWillProcessAuthorizationForm() ->willReturn(false) ; - $propertyReflection = new \ReflectionProperty(AuthorizeController::class, 'client'); + $propertyReflection = new ReflectionProperty(AuthorizeController::class, 'client'); $propertyReflection->setAccessible(true); $propertyReflection->setValue($this->instance, $this->client); $this->eventDispatcher ->expects($this->at(0)) ->method('dispatch') - ->with(OAuthEvent::PRE_AUTHORIZATION_PROCESS, new OAuthEvent($this->user, $this->client)) + ->with(new OAuthEvent($this->user, $this->client), OAuthEvent::PRE_AUTHORIZATION_PROCESS) ->willReturn($this->event) ; @@ -543,8 +438,8 @@ public function testAuthorizeActionWillProcessAuthorizationForm() ->expects($this->at(1)) ->method('dispatch') ->with( - OAuthEvent::POST_AUTHORIZATION_PROCESS, - new OAuthEvent($this->user, $this->client, true) + new OAuthEvent($this->user, $this->client, true), + OAuthEvent::POST_AUTHORIZATION_PROCESS ) ; @@ -591,6 +486,6 @@ public function testAuthorizeActionWillProcessAuthorizationForm() ->willReturn($response) ; - $this->assertSame($response, $this->instance->authorizeAction($this->request)); + self::assertSame($response, $this->instance->authorizeAction($this->request)); } } diff --git a/Tests/DependencyInjection/Compiler/GrantExtensionsCompilerPassTest.php b/Tests/DependencyInjection/Compiler/GrantExtensionsCompilerPassTest.php index fee8584b..253e334f 100644 --- a/Tests/DependencyInjection/Compiler/GrantExtensionsCompilerPassTest.php +++ b/Tests/DependencyInjection/Compiler/GrantExtensionsCompilerPassTest.php @@ -15,6 +15,7 @@ use FOS\OAuthServerBundle\DependencyInjection\Compiler\GrantExtensionsCompilerPass; use FOS\OAuthServerBundle\Storage\GrantExtensionDispatcherInterface; +use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; @@ -26,21 +27,21 @@ * * @author Nikola Petkanski */ -class GrantExtensionsCompilerPassTest extends \PHPUnit\Framework\TestCase +class GrantExtensionsCompilerPassTest extends TestCase { /** * @var GrantExtensionsCompilerPass */ protected $instance; - public function setUp() + public function setUp(): void { $this->instance = new GrantExtensionsCompilerPass(); parent::setUp(); } - public function testProcessWillNotDoAnythingIfTheStorageDoesNotImplementOurInterface() + public function testProcessWillNotDoAnythingIfTheStorageDoesNotImplementOurInterface(): void { $container = $this->getMockBuilder(ContainerBuilder::class) ->disableOriginalConstructor() @@ -90,10 +91,10 @@ public function testProcessWillNotDoAnythingIfTheStorageDoesNotImplementOurInter ->willReturn($resolvedClassName) ; - $this->assertNull($this->instance->process($container)); + self::assertNull($this->instance->process($container)); } - public function testProcessWillFailIfUriIsEmpty() + public function testProcessWillFailIfUriIsEmpty(): void { $container = $this->getMockBuilder(ContainerBuilder::class) ->disableOriginalConstructor() @@ -194,10 +195,10 @@ public function testProcessWillFailIfUriIsEmpty() $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage($exceptionMessage); - $this->assertNull($this->instance->process($container)); + self::assertNull($this->instance->process($container)); } - public function testProcess() + public function testProcess(): void { $container = $this->getMockBuilder(ContainerBuilder::class) ->disableOriginalConstructor() @@ -296,6 +297,6 @@ public function testProcess() } } - $this->assertNull($this->instance->process($container)); + self::assertNull($this->instance->process($container)); } } diff --git a/Tests/DependencyInjection/Compiler/RequestStackCompilerPassTest.php b/Tests/DependencyInjection/Compiler/RequestStackCompilerPassTest.php index b471fcc7..8f985438 100644 --- a/Tests/DependencyInjection/Compiler/RequestStackCompilerPassTest.php +++ b/Tests/DependencyInjection/Compiler/RequestStackCompilerPassTest.php @@ -14,6 +14,8 @@ namespace FOS\OAuthServerBundle\Tests\DependencyInjection\Compiler; use FOS\OAuthServerBundle\DependencyInjection\Compiler\RequestStackCompilerPass; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; @@ -23,7 +25,7 @@ * * @author Nikola Petkanski */ -class RequestStackCompilerPassTest extends \PHPUnit\Framework\TestCase +class RequestStackCompilerPassTest extends TestCase { /** * @var RequestStackCompilerPass @@ -31,11 +33,11 @@ class RequestStackCompilerPassTest extends \PHPUnit\Framework\TestCase protected $instance; /** - * @var \PHPUnit_Framework_MockObject_MockObject|ContainerBuilder + * @var MockObject|ContainerBuilder */ protected $container; - public function setUp() + public function setUp(): void { $this->container = $this->getMockBuilder(ContainerBuilder::class) ->disableOriginalConstructor() @@ -51,7 +53,7 @@ public function setUp() parent::setUp(); } - public function testProcessWithoutRequestStackDoesNothing() + public function testProcessWithoutRequestStackDoesNothing(): void { $this->container ->expects($this->once()) @@ -60,10 +62,10 @@ public function testProcessWithoutRequestStackDoesNothing() ->willReturn(true) ; - $this->assertNull($this->instance->process($this->container)); + self::assertNull($this->instance->process($this->container)); } - public function testProcess() + public function testProcess(): void { $this->container ->expects($this->once()) @@ -96,6 +98,6 @@ public function testProcess() ->willReturn(null) ; - $this->assertNull($this->instance->process($this->container)); + self::assertNull($this->instance->process($this->container)); } } diff --git a/Tests/DependencyInjection/Compiler/TokenStorageCompilerPassTest.php b/Tests/DependencyInjection/Compiler/TokenStorageCompilerPassTest.php deleted file mode 100644 index c9b3bfdd..00000000 --- a/Tests/DependencyInjection/Compiler/TokenStorageCompilerPassTest.php +++ /dev/null @@ -1,110 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace FOS\OAuthServerBundle\Tests\DependencyInjection\Compiler; - -use FOS\OAuthServerBundle\DependencyInjection\Compiler\TokenStorageCompilerPass; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Definition; -use Symfony\Component\DependencyInjection\Reference; - -/** - * Class TokenStorageCompilerPassTest. - * - * @author Nikola Petkanski - */ -class TokenStorageCompilerPassTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var TokenStorageCompilerPass - */ - protected $instance; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject|ContainerBuilder - */ - protected $container; - - public function setUp() - { - $this->container = $this->getMockBuilder(ContainerBuilder::class) - ->disableOriginalConstructor() - ->setMethods([ - 'getDefinition', - 'hasDefinition', - ]) - ->getMock() - ; - $this->instance = new TokenStorageCompilerPass(); - - parent::setUp(); - } - - public function testProcessWithExistingTokenStorage() - { - $authenticationListenerDefinition = $this->getMockBuilder(Definition::class) - ->disableOriginalConstructor() - ->getMock() - ; - - $this->container - ->expects($this->once()) - ->method('getDefinition') - ->with('fos_oauth_server.security.authentication.listener') - ->willReturn($authenticationListenerDefinition) - ; - - $this->container - ->expects($this->once()) - ->method('hasDefinition') - ->with('security.token_storage') - ->willReturn(true) - ; - - $this->assertNull($this->instance->process($this->container)); - } - - public function testProcessWithoutExistingTokenStorage() - { - $authenticationListenerDefinition = $this->getMockBuilder(Definition::class) - ->disableOriginalConstructor() - ->getMock() - ; - - $this->container - ->expects($this->once()) - ->method('getDefinition') - ->with('fos_oauth_server.security.authentication.listener') - ->willReturn($authenticationListenerDefinition) - ; - - $this->container - ->expects($this->once()) - ->method('hasDefinition') - ->with('security.token_storage') - ->willReturn(false) - ; - - $authenticationListenerDefinition - ->expects($this->once()) - ->method('replaceArgument') - ->with( - 0, - new Reference('security.context') - ) - ->willReturn(null) - ; - - $this->assertNull($this->instance->process($this->container)); - } -} diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php index 0c072192..ef5fd9a0 100644 --- a/Tests/DependencyInjection/ConfigurationTest.php +++ b/Tests/DependencyInjection/ConfigurationTest.php @@ -13,33 +13,42 @@ namespace FOS\OAuthServerBundle\Tests\DependencyInjection; +use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts; +use Exception; use FOS\OAuthServerBundle\DependencyInjection\Configuration; +use PHPUnit\Framework\TestCase; +use ReflectionClass; use Symfony\Component\Config\Definition\ConfigurationInterface; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; use Symfony\Component\Config\Definition\Processor; -class ConfigurationTest extends \PHPUnit\Framework\TestCase +class ConfigurationTest extends TestCase { - public function testShouldImplementConfigurationInterface() + use ArraySubsetAsserts; + + public function testShouldImplementConfigurationInterface(): void { - $rc = new \ReflectionClass(Configuration::class); + $rc = new ReflectionClass(Configuration::class); - $this->assertTrue($rc->implementsInterface(ConfigurationInterface::class)); + self::assertTrue($rc->implementsInterface(ConfigurationInterface::class)); } - public function testCouldBeConstructedWithoutAnyArguments() + public function testCouldBeConstructedWithoutAnyArguments(): void { try { new Configuration(); // no exceptions were thrown self::assertTrue(true); - } catch (\Exception $exception) { + } catch (Exception $exception) { $this->fail($exception->getMessage()); } } - public function testShouldNotMandatoryServiceIfNotCustomDriverIsUsed() + /** + * @throws Exception + */ + public function testShouldNotMandatoryServiceIfNotCustomDriverIsUsed(): void { $configuration = new Configuration(); $processor = new Processor(); @@ -52,7 +61,7 @@ public function testShouldNotMandatoryServiceIfNotCustomDriverIsUsed() 'auth_code_class' => 'anAuthCodeClass', ]]); - $this->assertArraySubset([ + self::assertArraySubset([ 'db_driver' => 'orm', 'client_class' => 'aClientClass', 'access_token_class' => 'anAccessTokenClass', @@ -69,7 +78,7 @@ public function testShouldNotMandatoryServiceIfNotCustomDriverIsUsed() ], $config); } - public function testShouldMakeClientManagerServiceMandatoryIfCustomDriverIsUsed() + public function testShouldMakeClientManagerServiceMandatoryIfCustomDriverIsUsed(): void { $configuration = new Configuration(); $processor = new Processor(); @@ -86,7 +95,7 @@ public function testShouldMakeClientManagerServiceMandatoryIfCustomDriverIsUsed( ]]); } - public function testShouldMakeAccessTokenManagerServiceMandatoryIfCustomDriverIsUsed() + public function testShouldMakeAccessTokenManagerServiceMandatoryIfCustomDriverIsUsed(): void { $configuration = new Configuration(); $processor = new Processor(); @@ -106,7 +115,7 @@ public function testShouldMakeAccessTokenManagerServiceMandatoryIfCustomDriverIs ]]); } - public function testShouldMakeRefreshTokenManagerServiceMandatoryIfCustomDriverIsUsed() + public function testShouldMakeRefreshTokenManagerServiceMandatoryIfCustomDriverIsUsed(): void { $configuration = new Configuration(); $processor = new Processor(); @@ -127,7 +136,7 @@ public function testShouldMakeRefreshTokenManagerServiceMandatoryIfCustomDriverI ]]); } - public function testShouldMakeAuthCodeManagerServiceMandatoryIfCustomDriverIsUsed() + public function testShouldMakeAuthCodeManagerServiceMandatoryIfCustomDriverIsUsed(): void { $configuration = new Configuration(); $processor = new Processor(); @@ -149,7 +158,10 @@ public function testShouldMakeAuthCodeManagerServiceMandatoryIfCustomDriverIsUse ]]); } - public function testShouldLoadCustomDriverConfig() + /** + * @throws Exception + */ + public function testShouldLoadCustomDriverConfig(): void { $configuration = new Configuration(); $processor = new Processor(); @@ -168,7 +180,7 @@ public function testShouldLoadCustomDriverConfig() ], ]]); - $this->assertArraySubset([ + self::assertArraySubset([ 'db_driver' => 'custom', 'client_class' => 'aClientClass', 'access_token_class' => 'anAccessTokenClass', diff --git a/Tests/DependencyInjection/FOSOAuthServerExtensionTest.php b/Tests/DependencyInjection/FOSOAuthServerExtensionTest.php index 4ffc09f7..6d5f824b 100644 --- a/Tests/DependencyInjection/FOSOAuthServerExtensionTest.php +++ b/Tests/DependencyInjection/FOSOAuthServerExtensionTest.php @@ -13,7 +13,10 @@ namespace FOS\OAuthServerBundle\Tests\DependencyInjection; +use Exception; use FOS\OAuthServerBundle\DependencyInjection\FOSOAuthServerExtension; +use PHPUnit\Framework\TestCase; +use ReflectionClass; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -21,11 +24,12 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; use Symfony\Component\Routing\Loader\XmlFileLoader; -class FOSOAuthServerExtensionTest extends \PHPUnit\Framework\TestCase +class FOSOAuthServerExtensionTest extends TestCase { + /** @var ContainerBuilder */ private $container; - public function setUp() + public function setUp(): void { $parameterBag = new ParameterBag(); $this->container = new ContainerBuilder($parameterBag); @@ -33,26 +37,26 @@ public function setUp() parent::setUp(); } - public function testShouldImplementConfigurationInterface() + public function testShouldImplementConfigurationInterface(): void { - $rc = new \ReflectionClass(FOSOAuthServerExtension::class); + $rc = new ReflectionClass(FOSOAuthServerExtension::class); - $this->assertTrue($rc->isSubclassOf(Extension::class)); + self::assertTrue($rc->isSubclassOf(Extension::class)); } - public function testCouldBeConstructedWithoutAnyArguments() + public function testCouldBeConstructedWithoutAnyArguments(): void { try { new FOSOAuthServerExtension(); // no exceptions were thrown self::assertTrue(true); - } catch (\Exception $exception) { + } catch (Exception $exception) { $this->fail($exception->getMessage()); } } - public function testShouldLoadAuthorizeRelatedServicesIfAuthorizationIsEnabled() + public function testShouldLoadAuthorizeRelatedServicesIfAuthorizationIsEnabled(): void { $container = new ContainerBuilder(); @@ -66,13 +70,13 @@ public function testShouldLoadAuthorizeRelatedServicesIfAuthorizationIsEnabled() 'authorize' => true, ]], $container); - $this->assertTrue($container->hasDefinition('fos_oauth_server.authorize.form')); - $this->assertTrue($container->hasDefinition('fos_oauth_server.authorize.form.type')); - $this->assertTrue($container->hasDefinition('fos_oauth_server.authorize.form.handler.default')); - $this->assertTrue($container->hasDefinition('fos_oauth_server.controller.authorize')); + self::assertTrue($container->hasDefinition('fos_oauth_server.authorize.form')); + self::assertTrue($container->hasDefinition('fos_oauth_server.authorize.form.type')); + self::assertTrue($container->hasDefinition('fos_oauth_server.authorize.form.handler.default')); + self::assertTrue($container->hasDefinition('fos_oauth_server.controller.authorize')); } - public function testShouldNotLoadAuthorizeRelatedServicesIfAuthorizationIsDisabled() + public function testShouldNotLoadAuthorizeRelatedServicesIfAuthorizationIsDisabled(): void { $container = new ContainerBuilder(); @@ -86,35 +90,35 @@ public function testShouldNotLoadAuthorizeRelatedServicesIfAuthorizationIsDisabl 'authorize' => false, ]], $container); - $this->assertFalse($container->hasDefinition('fos_oauth_server.authorize.form')); - $this->assertFalse($container->hasDefinition('fos_oauth_server.authorize.form.type')); - $this->assertFalse($container->hasDefinition('fos_oauth_server.authorize.form.handler.default')); - $this->assertFalse($container->hasDefinition('fos_oauth_server.controller.authorize')); + self::assertFalse($container->hasDefinition('fos_oauth_server.authorize.form')); + self::assertFalse($container->hasDefinition('fos_oauth_server.authorize.form.type')); + self::assertFalse($container->hasDefinition('fos_oauth_server.authorize.form.handler.default')); + self::assertFalse($container->hasDefinition('fos_oauth_server.controller.authorize')); } - public function testLoadAuthorizeRouting() + public function testLoadAuthorizeRouting(): void { $locator = new FileLocator(); $loader = new XmlFileLoader($locator); $collection = $loader->load(__DIR__.'/../../Resources/config/routing/authorize.xml'); $authorizeRoute = $collection->get('fos_oauth_server_authorize'); - $this->assertSame('/oauth/v2/auth', $authorizeRoute->getPath()); - $this->assertSame(['GET', 'POST'], $authorizeRoute->getMethods()); + self::assertSame('/oauth/v2/auth', $authorizeRoute->getPath()); + self::assertSame(['GET', 'POST'], $authorizeRoute->getMethods()); } - public function testLoadTokenRouting() + public function testLoadTokenRouting(): void { $locator = new FileLocator(); $loader = new XmlFileLoader($locator); $collection = $loader->load(__DIR__.'/../../Resources/config/routing/token.xml'); $tokenRoute = $collection->get('fos_oauth_server_token'); - $this->assertSame('/oauth/v2/token', $tokenRoute->getPath()); - $this->assertSame(['GET', 'POST'], $tokenRoute->getMethods()); + self::assertSame('/oauth/v2/token', $tokenRoute->getPath()); + self::assertSame(['GET', 'POST'], $tokenRoute->getMethods()); } - public function testWithoutService() + public function testWithoutService(): void { $config = [ 'db_driver' => 'orm', @@ -126,13 +130,13 @@ public function testWithoutService() $instance = new FOSOAuthServerExtension(); $instance->load([$config], $this->container); - $this->assertSame( + self::assertSame( $this->container->getParameter('fos_oauth_server.server.options'), [] ); } - public function testStringSupportedScopes() + public function testStringSupportedScopes(): void { $scopes = 'scope1 scope2 scope3 scope4'; @@ -152,7 +156,7 @@ public function testStringSupportedScopes() $instance = new FOSOAuthServerExtension(); $instance->load([$config], $this->container); - $this->assertSame( + self::assertSame( $this->container->getParameter('fos_oauth_server.server.options'), [ 'supported_scopes' => 'scope1 scope2 scope3 scope4', @@ -160,7 +164,7 @@ public function testStringSupportedScopes() ); } - public function testArraySupportedScopes() + public function testArraySupportedScopes(): void { $scopes = ['scope1', 'scope2', 'scope3', 'scope4']; @@ -180,7 +184,7 @@ public function testArraySupportedScopes() $instance = new FOSOAuthServerExtension(); $instance->load([$config], $this->container); - $this->assertSame( + self::assertSame( $this->container->getParameter('fos_oauth_server.server.options'), [ 'supported_scopes' => 'scope1 scope2 scope3 scope4', @@ -189,7 +193,7 @@ public function testArraySupportedScopes() ); } - public function testArraySupportedScopesWithSpace() + public function testArraySupportedScopesWithSpace(): void { $scopes = ['scope1 scope2', 'scope3', 'scope4']; @@ -209,11 +213,16 @@ public function testArraySupportedScopesWithSpace() $instance = new FOSOAuthServerExtension(); $this->expectException(InvalidConfigurationException::class); - $this->expectExceptionMessage('The array notation for supported_scopes should not contain spaces in array items. Either use full array notation or use the string notation for supported_scopes. See https://git.io/vx1X0 for more informations.'); + $this->expectExceptionMessage( + 'The array notation ' + .'for supported_scopes should not contain spaces in array items.' + .' Either use full array notation or use the string notation for supported_scopes. ' + .'See https://git.io/vx1X0 for more information.' + ); $instance->load([$config], $this->container); } - public function testShouldAliasServivesWhenCustomDriverIsUsed() + public function testShouldAliasServicesWhenCustomDriverIsUsed(): void { $container = new ContainerBuilder(); $extension = new FOSOAuthServerExtension(); @@ -233,19 +242,28 @@ public function testShouldAliasServivesWhenCustomDriverIsUsed() ], ]], $container); - $this->assertTrue($container->hasAlias('fos_oauth_server.storage')); - $this->assertSame('fos_oauth_server.storage.default', (string) $container->getAlias('fos_oauth_server.storage')); + self::assertTrue($container->hasAlias('fos_oauth_server.storage')); + self::assertSame('fos_oauth_server.storage.default', (string) $container->getAlias('fos_oauth_server.storage')); - $this->assertTrue($container->hasAlias('fos_oauth_server.client_manager')); - $this->assertSame('the_client_manager_id', (string) $container->getAlias('fos_oauth_server.client_manager')); + self::assertTrue($container->hasAlias('fos_oauth_server.client_manager')); + self::assertSame('the_client_manager_id', (string) $container->getAlias('fos_oauth_server.client_manager')); - $this->assertTrue($container->hasAlias('fos_oauth_server.access_token_manager')); - $this->assertSame('the_access_token_manager_id', (string) $container->getAlias('fos_oauth_server.access_token_manager')); + self::assertTrue($container->hasAlias('fos_oauth_server.access_token_manager')); + self::assertSame( + 'the_access_token_manager_id', + (string) $container->getAlias('fos_oauth_server.access_token_manager') + ); - $this->assertTrue($container->hasAlias('fos_oauth_server.refresh_token_manager')); - $this->assertSame('the_refresh_token_manager_id', (string) $container->getAlias('fos_oauth_server.refresh_token_manager')); + self::assertTrue($container->hasAlias('fos_oauth_server.refresh_token_manager')); + self::assertSame( + 'the_refresh_token_manager_id', + (string) $container->getAlias('fos_oauth_server.refresh_token_manager') + ); - $this->assertTrue($container->hasAlias('fos_oauth_server.auth_code_manager')); - $this->assertSame('the_auth_code_manager_id', (string) $container->getAlias('fos_oauth_server.auth_code_manager')); + self::assertTrue($container->hasAlias('fos_oauth_server.auth_code_manager')); + self::assertSame( + 'the_auth_code_manager_id', + (string) $container->getAlias('fos_oauth_server.auth_code_manager') + ); } } diff --git a/Tests/DependencyInjection/Security/Factory/OAuthFactoryTest.php b/Tests/DependencyInjection/Security/Factory/OAuthFactoryTest.php index b40a3d58..2e79ec77 100644 --- a/Tests/DependencyInjection/Security/Factory/OAuthFactoryTest.php +++ b/Tests/DependencyInjection/Security/Factory/OAuthFactoryTest.php @@ -14,7 +14,9 @@ namespace FOS\OAuthServerBundle\Tests\DependencyInjection\Security\Factory; use FOS\OAuthServerBundle\DependencyInjection\Security\Factory\OAuthFactory; +use PHPUnit\Framework\TestCase; use Symfony\Component\Config\Definition\Builder\NodeDefinition; +use Symfony\Component\DependencyInjection\ChildDefinition; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; @@ -24,118 +26,52 @@ * * @author Nikola Petkanski */ -class OAuthFactoryTest extends \PHPUnit\Framework\TestCase +class OAuthFactoryTest extends TestCase { /** * @var OAuthFactory */ protected $instance; - /** - * @var string - */ - protected $definitionDecoratorClass; - /** * @var string */ protected $childDefinitionClass; - public function setUp() + public function setUp(): void { - $this->definitionDecoratorClass = 'Symfony\Component\DependencyInjection\DefinitionDecorator'; - $this->childDefinitionClass = 'Symfony\Component\DependencyInjection\ChildDefinition'; + $this->childDefinitionClass = ChildDefinition::class; $this->instance = new OAuthFactory(); parent::setUp(); } - public function testGetPosition() - { - $this->assertSame('pre_auth', $this->instance->getPosition()); - } - - public function testGetKey() + public function testGetPosition(): void { - $this->assertSame('fos_oauth', $this->instance->getKey()); + self::assertSame('pre_auth', $this->instance->getPosition()); } - public function testCreate() + public function testGetKey(): void { - if (class_exists($this->childDefinitionClass)) { - return $this->useChildDefinition(); - } - - if (class_exists($this->definitionDecoratorClass)) { - return $this->useDefinitionDecorator(); - } - - throw new \Exception('Neither DefinitionDecorator nor ChildDefinition exist'); + self::assertSame('fos_oauth', $this->instance->getKey()); } - public function testAddConfigurationDoesNothing() + public function testAddConfigurationDoesNothing(): void { $nodeDefinition = $this->getMockBuilder(NodeDefinition::class) ->disableOriginalConstructor() ->getMock() ; - $this->assertNull($this->instance->addConfiguration($nodeDefinition)); + self::assertNull($this->instance->addConfiguration($nodeDefinition)); } - protected function useDefinitionDecorator() + public function testCreate(): void { - $container = $this->getMockBuilder(ContainerBuilder::class) - ->disableOriginalConstructor() - ->setMethods([ - 'setDefinition', - ]) - ->getMock() - ; - $id = '12'; - $config = []; - $userProvider = 'mock.user.provider.service'; - $defaultEntryPoint = ''; - - $definition = $this->getMockBuilder(Definition::class) - ->disableOriginalConstructor() - ->getMock() - ; - - $container - ->expects($this->exactly(2)) - ->method('setDefinition') - ->withConsecutive( - [ - 'security.authentication.provider.fos_oauth_server.'.$id, - new $this->definitionDecoratorClass('fos_oauth_server.security.authentication.provider'), - ], - [ - 'security.authentication.listener.fos_oauth_server.'.$id, - new $this->definitionDecoratorClass('fos_oauth_server.security.authentication.listener'), - ] - ) - ->willReturnOnConsecutiveCalls( - $definition, - null - ) - ; - - $definition - ->expects($this->once()) - ->method('replaceArgument') - ->with(0, new Reference($userProvider)) - ->willReturn(null) - ; - - $this->assertSame([ - 'security.authentication.provider.fos_oauth_server.'.$id, - 'security.authentication.listener.fos_oauth_server.'.$id, - 'fos_oauth_server.security.entry_point', - ], $this->instance->create($container, $id, $config, $userProvider, $defaultEntryPoint)); + $this->useChildDefinition(); } - protected function useChildDefinition() + private function useChildDefinition(): void { $container = $this->getMockBuilder(ContainerBuilder::class) ->disableOriginalConstructor() @@ -180,7 +116,7 @@ protected function useChildDefinition() ->willReturn(null) ; - $this->assertSame([ + self::assertSame([ 'security.authentication.provider.fos_oauth_server.'.$id, 'security.authentication.listener.fos_oauth_server.'.$id, 'fos_oauth_server.security.entry_point', diff --git a/Tests/Document/AccessTokenManagerFunctionalTest.php b/Tests/Document/AccessTokenManagerFunctionalTest.php new file mode 100644 index 00000000..76c96d18 --- /dev/null +++ b/Tests/Document/AccessTokenManagerFunctionalTest.php @@ -0,0 +1,159 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\OAuthServerBundle\Tests\Document; + +use FOS\OAuthServerBundle\Tests\Functional\TestBundle\Document\AccessToken; +use FOS\OAuthServerBundle\Tests\Functional\TestCase; + +class AccessTokenManagerFunctionalTest extends TestCase +{ + /** + * @var \FOS\OAuthServerBundle\Entity\AccessTokenManager + */ + protected $accessTokenManager; + + /** + * @var \Doctrine\ODM\MongoDB\DocumentManager + */ + protected $documentManager; + + public function setUp(): void + { + parent::setUp(); + + static::bootKernel(['environment' => 'odm']); + + $serviceContainer = self::$container->get('test.service_container'); + $this->documentManager = $serviceContainer->get('doctrine_mongodb')->getManager(); + $this->accessTokenManager = $serviceContainer->get('fos_oauth_server.access_token_manager.default'); + } + + public function tearDown(): void + { + $this->documentManager->getDocumentCollection(AccessToken::class)->deleteMany([]); + + unset($this->documentManager); + + parent::tearDown(); + } + + /** + * Verify a single access token can be found by given token string. + */ + public function testFindTokenByToken(): void + { + // set up two access tokens + $expectedAccessToken = new AccessToken(); + $expectedAccessToken->setToken('expected-test-token'); + $this->documentManager->persist($expectedAccessToken); + + $unexpectedAccessToken = new AccessToken(); + $unexpectedAccessToken->setToken('unexpected-test-token'); + $this->documentManager->persist($unexpectedAccessToken); + + $this->documentManager->flush(); + + // capture the persisted IDs + $expectedAccessTokenId = $expectedAccessToken->getId(); + $unexpectedAccessTokenId = $unexpectedAccessToken->getId(); + + // clear the new documents from doctrine memory + $this->documentManager->clear(); + + // confirm the expected access token is found + $foundAccessToken = $this->accessTokenManager->findTokenByToken('expected-test-token'); + + self::assertInstanceOf(AccessToken::class, $foundAccessToken); + self::assertSame($expectedAccessTokenId, $foundAccessToken->getId()); + self::assertNotSame($unexpectedAccessTokenId, $foundAccessToken->getId()); + } + + /** + * Verify an access token can be updated. + */ + public function testUpdateTokenPersistsAndFlushes(): void + { + // set up an access token, but do not persist it + $accessToken = new AccessToken(); + $accessToken->setToken('test-token'); + + // update the access token + $this->accessTokenManager->updateToken($accessToken); + + // confirm the access token is persisted and flushed + $this->documentManager->clear(); + $foundAccessToken = $this->accessTokenManager->findTokenByToken('test-token'); + + self::assertInstanceOf(AccessToken::class, $foundAccessToken); + self::assertStringMatchesFormat('%s', $foundAccessToken->getId()); + } + + /** + * Verify an access token can be removed. + */ + public function testDeleteToken(): void + { + // set up an access token + $accessToken = new AccessToken(); + $accessToken->setToken('test-token'); + $this->documentManager->persist($accessToken); + $this->documentManager->flush(); + + // remove the access token + $this->accessTokenManager->deleteToken($accessToken); + + // confirm the access token can't be found + $this->documentManager->clear(); + + self::assertNull($this->accessTokenManager->findTokenByToken('test-token')); + } + + /** + * Verify all expired access tokens can be removed in one operation. + */ + public function testDeleteExpired(): void + { + // set up an access token that expired one second ago + $expiredAccessToken1 = new AccessToken(); + $expiredAccessToken1->setToken('expired-test-token-1'); + $expiredAccessToken1->setExpiresAt(time() - 1); + $this->documentManager->persist($expiredAccessToken1); + + // set up an access token that expires in 10 seconds (avoid false failure + // if the test host stalls) + $unexpiredAccessToken = new AccessToken(); + $unexpiredAccessToken->setToken('unexpired-test-token'); + $unexpiredAccessToken->setExpiresAt(time() + 10); + $this->documentManager->persist($unexpiredAccessToken); + + // set up another access token that expired + $expiredAccessToken2 = new AccessToken(); + $expiredAccessToken2->setToken('expired-test-token-2'); + $expiredAccessToken2->setExpiresAt(time() - 10); + $this->documentManager->persist($expiredAccessToken2); + + $this->documentManager->flush(); + + // clear the new documents from doctrine memory + $this->documentManager->clear(); + + // delete all expired + self::assertSame(2, $this->accessTokenManager->deleteExpired()); + + // confirm only the unexpired access token is found + self::assertNull($this->accessTokenManager->findTokenByToken('expired-test-token-1')); + self::assertNull($this->accessTokenManager->findTokenByToken('expired-test-token-2')); + self::assertInstanceOf(AccessToken::class, $this->accessTokenManager->findTokenByToken('unexpired-test-token')); + } +} diff --git a/Tests/Document/AuthCodeManagerFunctionalTest.php b/Tests/Document/AuthCodeManagerFunctionalTest.php new file mode 100644 index 00000000..034c118b --- /dev/null +++ b/Tests/Document/AuthCodeManagerFunctionalTest.php @@ -0,0 +1,161 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\OAuthServerBundle\Tests\Document; + +use FOS\OAuthServerBundle\Tests\Functional\TestBundle\Document\AuthCode; +use FOS\OAuthServerBundle\Tests\Functional\TestCase; + +class AuthCodeManagerFunctionalTest extends TestCase +{ + /** + * @var \FOS\OAuthServerBundle\Document\AuthCodeManager + */ + protected $authCodeManager; + + /** + * @var \Doctrine\ODM\MongoDB\DocumentManager + */ + protected $documentManager; + + public function setUp(): void + { + parent::setUp(); + + static::bootKernel(['environment' => 'odm']); + + $serviceContainer = self::$container->get('test.service_container'); + $this->documentManager = $serviceContainer->get('doctrine_mongodb')->getManager(); + $this->authCodeManager = $serviceContainer->get('fos_oauth_server.auth_code_manager.default'); + } + + public function tearDown(): void + { + $this->documentManager->getDocumentCollection(AuthCode::class)->deleteMany([]); + + unset($this->documentManager); + + parent::tearDown(); + } + + /** + * Verify a single auth code can be found by given criteria. + */ + public function testFindAuthCodeBy(): void + { + // set up two auth codes + $expectedAuthCode = new AuthCode(); + $expectedAuthCode->setToken('expected-test-token'); + $this->documentManager->persist($expectedAuthCode); + + $unexpectedAuthCode = new AuthCode(); + $unexpectedAuthCode->setToken('unexpected-test-token'); + $this->documentManager->persist($unexpectedAuthCode); + + $this->documentManager->flush(); + + // capture the persisted IDs + $expectedAuthCodeId = $expectedAuthCode->getId(); + $unexpectedAuthCodeId = $unexpectedAuthCode->getId(); + + // clear the new documents from doctrine memory + $this->documentManager->clear(); + + // confirm the expected auth code is found + $foundAuthCode = $this->authCodeManager->findAuthCodeBy(['token' => 'expected-test-token']); + + self::assertInstanceOf(AuthCode::class, $foundAuthCode); + self::assertSame($expectedAuthCodeId, $foundAuthCode->getId()); + self::assertNotSame($unexpectedAuthCodeId, $foundAuthCode->getId()); + } + + /** + * Verify an auth code can be updated. + */ + public function testUpdateAuthCode(): void + { + // set up an auth code, but do not persist it + $authCode = new AuthCode(); + $authCode->setToken('test-token'); + + // update the auth code + $this->authCodeManager->updateAuthCode($authCode); + + // confirm the auth code is persisted and flushed + $this->documentManager->clear(); + $foundAuthCode = $this->authCodeManager->findAuthCodeBy(['token' => 'test-token']); + + self::assertInstanceOf(AuthCode::class, $foundAuthCode); + self::assertStringMatchesFormat('%s', $foundAuthCode->getId()); + } + + /** + * Verify an auth code can be removed. + */ + public function testDeleteAuthCode(): void + { + // set up an auth code + $authCode = new AuthCode(); + $authCode->setToken('test-token'); + $this->documentManager->persist($authCode); + $this->documentManager->flush(); + + // remove the auth code + $this->authCodeManager->deleteAuthCode($authCode); + + // confirm the auth code can't be found + $this->documentManager->clear(); + + self::assertNull($this->authCodeManager->findAuthCodeBy(['token' => 'test-token'])); + } + + /** + * Verify all expired auth codes can be removed in one operation. + */ + public function testDeleteExpired(): void + { + // set up an auth code that expired one second ago + $expiredAuthCode1 = new AuthCode(); + $expiredAuthCode1->setExpiresAt(time() - 1); + $this->documentManager->persist($expiredAuthCode1); + + // set up an auth code that expires in 10 seconds (avoid false failure + // if the test host stalls) + $unexpiredAuthCode = new AuthCode(); + $unexpiredAuthCode->setExpiresAt(time() + 10); + $this->documentManager->persist($unexpiredAuthCode); + + // set up another auth code that expired + $expiredAuthCode2 = new AuthCode(); + $expiredAuthCode2->setExpiresAt(time() - 10); + $this->documentManager->persist($expiredAuthCode2); + + $this->documentManager->flush(); + + // capture the persisted IDs + $expiredAuthCodeId1 = $expiredAuthCode1->getId(); + $expiredAuthCodeId2 = $expiredAuthCode2->getId(); + $unexpiredAuthCodeId = $unexpiredAuthCode->getId(); + + // clear the new documents from doctrine memory + $this->documentManager->clear(); + + // delete all expired + self::assertSame(2, $this->authCodeManager->deleteExpired()); + + // confirm only the unexpired auth code is found + self::assertNull($this->authCodeManager->findAuthCodeBy(['id' => $expiredAuthCodeId1])); + self::assertNull($this->authCodeManager->findAuthCodeBy(['id' => $expiredAuthCodeId2])); + self::assertInstanceOf(AuthCode::class, $this->authCodeManager->findAuthCodeBy(['id' => $unexpiredAuthCodeId])); + } +} diff --git a/Tests/Document/AuthCodeManagerTest.php b/Tests/Document/AuthCodeManagerTest.php index f3a86281..09a9f52d 100644 --- a/Tests/Document/AuthCodeManagerTest.php +++ b/Tests/Document/AuthCodeManagerTest.php @@ -13,12 +13,11 @@ namespace FOS\OAuthServerBundle\Tests\Document; -use Doctrine\MongoDB\Query\Builder; use Doctrine\ODM\MongoDB\DocumentManager; -use Doctrine\ODM\MongoDB\DocumentRepository; -use Doctrine\ORM\AbstractQuery; +use Doctrine\ODM\MongoDB\Repository\DocumentRepository; use FOS\OAuthServerBundle\Document\AuthCodeManager; -use FOS\OAuthServerBundle\Model\AuthCodeInterface; +use FOS\OAuthServerBundle\Tests\TestCase; +use PHPUnit\Framework\MockObject\MockObject; /** * @group time-sensitive @@ -27,15 +26,15 @@ * * @author Nikola Petkanski */ -class AuthCodeManagerTest extends \PHPUnit\Framework\TestCase +class AuthCodeManagerTest extends TestCase { /** - * @var \PHPUnit_Framework_MockObject_MockObject|DocumentManager + * @var MockObject|DocumentManager */ protected $documentManager; /** - * @var \PHPUnit_Framework_MockObject_MockObject|DocumentRepository + * @var MockObject|DocumentRepository */ protected $repository; @@ -49,9 +48,9 @@ class AuthCodeManagerTest extends \PHPUnit\Framework\TestCase */ protected $instance; - public function setUp() + public function setUp(): void { - if (!class_exists('\Doctrine\ODM\MongoDB\DocumentManager')) { + if (!class_exists(DocumentManager::class)) { $this->markTestSkipped('Doctrine MongoDB ODM has to be installed for this test to run.'); } @@ -63,7 +62,7 @@ public function setUp() ->disableOriginalConstructor() ->getMock() ; - $this->className = 'TestClassName'.\random_bytes(5); + $this->className = 'TestClassName'; $this->documentManager ->expects($this->once()) @@ -77,142 +76,14 @@ public function setUp() parent::setUp(); } - public function testConstructWillSetParameters() + public function testConstructWillSetParameters(): void { - $this->assertAttributeSame($this->documentManager, 'dm', $this->instance); - $this->assertAttributeSame($this->className, 'class', $this->instance); + self::assertObjectPropertySame($this->documentManager, $this->instance, 'dm'); + self::assertSame($this->className, $this->instance->getClass()); } - public function testGetClassWillReturnClassName() + public function testGetClassWillReturnClassName(): void { - $this->assertSame($this->className, $this->instance->getClass()); - } - - public function testFindAuthCodeBy() - { - $randomResult = \random_bytes(10); - $criteria = [ - \random_bytes(10), - ]; - - $this->repository - ->expects($this->once()) - ->method('findOneBy') - ->with($criteria) - ->willReturn($randomResult) - ; - - $this->assertSame($randomResult, $this->instance->findAuthCodeBy($criteria)); - } - - public function testUpdateAuthCode() - { - $authCode = $this->getMockBuilder(AuthCodeInterface::class) - ->disableOriginalConstructor() - ->getMock() - ; - - $this->documentManager - ->expects($this->once()) - ->method('persist') - ->with($authCode) - ->willReturn(null) - ; - - $this->documentManager - ->expects($this->once()) - ->method('flush') - ->with() - ->willReturn(null) - ; - - $this->assertNull($this->instance->updateAuthCode($authCode)); - } - - public function testDeleteAuthCode() - { - $authCode = $this->getMockBuilder(AuthCodeInterface::class) - ->disableOriginalConstructor() - ->getMock() - ; - - $this->documentManager - ->expects($this->once()) - ->method('remove') - ->with($authCode) - ->willReturn(null) - ; - - $this->documentManager - ->expects($this->once()) - ->method('flush') - ->with() - ->willReturn(null) - ; - - $this->assertNull($this->instance->deleteAuthCode($authCode)); - } - - public function testDeleteExpired() - { - $queryBuilder = $this->getMockBuilder(Builder::class) - ->disableOriginalConstructor() - ->getMock() - ; - - $this->repository - ->expects($this->once()) - ->method('createQueryBuilder') - ->with() - ->willReturn($queryBuilder) - ; - - $queryBuilder - ->expects($this->once()) - ->method('remove') - ->with() - ->willReturn($queryBuilder) - ; - - $queryBuilder - ->expects($this->once()) - ->method('field') - ->with('expiresAt') - ->willReturn($queryBuilder) - ; - - $queryBuilder - ->expects($this->once()) - ->method('lt') - ->with(time()) - ->willReturn($queryBuilder) - ; - - $query = $this->getMockBuilder(AbstractQuery::class) - ->disableOriginalConstructor() - ->getMock() - ; - - $queryBuilder - ->expects($this->once()) - ->method('getQuery') - ->with([ - 'safe' => true, - ]) - ->willReturn($query) - ; - - $data = [ - 'n' => \random_bytes(10), - ]; - - $query - ->expects($this->once()) - ->method('execute') - ->with() - ->willReturn($data) - ; - - $this->assertSame($data['n'], $this->instance->deleteExpired()); + self::assertSame($this->className, $this->instance->getClass()); } } diff --git a/Tests/Document/ClientManagerTest.php b/Tests/Document/ClientManagerTest.php index 4af23fc8..5cc2bc72 100644 --- a/Tests/Document/ClientManagerTest.php +++ b/Tests/Document/ClientManagerTest.php @@ -14,19 +14,23 @@ namespace FOS\OAuthServerBundle\Tests\Document; use Doctrine\ODM\MongoDB\DocumentManager; -use Doctrine\ODM\MongoDB\DocumentRepository; +use Doctrine\ODM\MongoDB\Repository\DocumentRepository; use FOS\OAuthServerBundle\Document\ClientManager; use FOS\OAuthServerBundle\Model\ClientInterface; +use FOS\OAuthServerBundle\Tests\TestCase; +use PHPUnit\Framework\MockObject\MockObject; +use function random_bytes; +use stdClass; /** * Class ClientManagerTest. * * @author Nikola Petkanski */ -class ClientManagerTest extends \PHPUnit\Framework\TestCase +class ClientManagerTest extends TestCase { /** - * @var \PHPUnit_Framework_MockObject_MockObject|DocumentManager + * @var MockObject|DocumentManager */ protected $documentManager; @@ -36,7 +40,7 @@ class ClientManagerTest extends \PHPUnit\Framework\TestCase protected $className; /** - * @var \PHPUnit_Framework_MockObject_MockObject|DocumentRepository + * @var MockObject|DocumentRepository */ protected $repository; @@ -45,9 +49,9 @@ class ClientManagerTest extends \PHPUnit\Framework\TestCase */ protected $instance; - public function setUp() + public function setUp(): void { - if (!class_exists('\Doctrine\ODM\MongoDB\DocumentManager')) { + if (!class_exists(DocumentManager::class)) { $this->markTestSkipped('Doctrine MongoDB ODM has to be installed for this test to run.'); } @@ -59,7 +63,7 @@ public function setUp() ->disableOriginalConstructor() ->getMock() ; - $this->className = 'RandomClassName'.\random_bytes(5); + $this->className = 'RandomClassName'.random_bytes(5); $this->documentManager ->expects($this->once()) @@ -73,23 +77,23 @@ public function setUp() parent::setUp(); } - public function testConstructWillSetParameters() + public function testConstructWillSetParameters(): void { - $this->assertAttributeSame($this->documentManager, 'dm', $this->instance); - $this->assertAttributeSame($this->repository, 'repository', $this->instance); - $this->assertAttributeSame($this->className, 'class', $this->instance); + self::assertObjectPropertySame($this->documentManager, $this->instance, 'dm'); + self::assertObjectPropertySame($this->repository, $this->instance, 'repository'); + self::assertSame($this->className, $this->instance->getClass()); } - public function testGetClass() + public function testGetClass(): void { - $this->assertSame($this->className, $this->instance->getClass()); + self::assertSame($this->className, $this->instance->getClass()); } - public function testFindClientBy() + public function testFindClientBy(): void { - $randomResult = \random_bytes(5); + $randomResult = new stdClass(); $criteria = [ - \random_bytes(5), + random_bytes(5), ]; $this->repository @@ -99,10 +103,10 @@ public function testFindClientBy() ->willReturn($randomResult) ; - $this->assertSame($randomResult, $this->instance->findClientBy($criteria)); + self::assertSame($randomResult, $this->instance->findClientBy($criteria)); } - public function testUpdateClient() + public function testUpdateClient(): void { $client = $this->getMockBuilder(ClientInterface::class) ->disableOriginalConstructor() @@ -123,10 +127,10 @@ public function testUpdateClient() ->willReturn(null) ; - $this->assertNull($this->instance->updateClient($client)); + self::assertNull($this->instance->updateClient($client)); } - public function testDeleteClient() + public function testDeleteClient(): void { $client = $this->getMockBuilder(ClientInterface::class) ->disableOriginalConstructor() @@ -147,6 +151,6 @@ public function testDeleteClient() ->willReturn(null) ; - $this->assertNull($this->instance->deleteClient($client)); + self::assertNull($this->instance->deleteClient($client)); } } diff --git a/Tests/Document/RefreshTokenManagerFunctionalTest.php b/Tests/Document/RefreshTokenManagerFunctionalTest.php new file mode 100644 index 00000000..9cc2642f --- /dev/null +++ b/Tests/Document/RefreshTokenManagerFunctionalTest.php @@ -0,0 +1,159 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\OAuthServerBundle\Tests\Document; + +use FOS\OAuthServerBundle\Tests\Functional\TestBundle\Document\RefreshToken; +use FOS\OAuthServerBundle\Tests\Functional\TestCase; + +class RefreshTokenManagerFunctionalTest extends TestCase +{ + /** + * @var \FOS\OAuthServerBundle\Entity\RefreshTokenManager + */ + protected $refreshTokenManager; + + /** + * @var \Doctrine\ODM\MongoDB\DocumentManager + */ + protected $documentManager; + + public function setUp(): void + { + parent::setUp(); + + static::bootKernel(['environment' => 'odm']); + + $serviceContainer = self::$container->get('test.service_container'); + $this->documentManager = $serviceContainer->get('doctrine_mongodb')->getManager(); + $this->refreshTokenManager = $serviceContainer->get('fos_oauth_server.refresh_token_manager.default'); + } + + public function tearDown(): void + { + $this->documentManager->getDocumentCollection(RefreshToken::class)->deleteMany([]); + + unset($this->documentManager); + + parent::tearDown(); + } + + /** + * Verify a single refresh token can be found by given token string. + */ + public function testFindTokenByToken(): void + { + // set up two refresh tokens + $expectedRefreshToken = new RefreshToken(); + $expectedRefreshToken->setToken('expected-test-token'); + $this->documentManager->persist($expectedRefreshToken); + + $unexpectedRefreshToken = new RefreshToken(); + $unexpectedRefreshToken->setToken('unexpected-test-token'); + $this->documentManager->persist($unexpectedRefreshToken); + + $this->documentManager->flush(); + + // capture the persisted IDs + $expectedRefreshTokenId = $expectedRefreshToken->getId(); + $unexpectedRefreshTokenId = $unexpectedRefreshToken->getId(); + + // clear the new documents from doctrine memory + $this->documentManager->clear(); + + // confirm the expected refresh token is found + $foundRefreshToken = $this->refreshTokenManager->findTokenByToken('expected-test-token'); + + self::assertInstanceOf(RefreshToken::class, $foundRefreshToken); + self::assertSame($expectedRefreshTokenId, $foundRefreshToken->getId()); + self::assertNotSame($unexpectedRefreshTokenId, $foundRefreshToken->getId()); + } + + /** + * Verify an refresh token can be updated. + */ + public function testUpdateTokenPersistsAndFlushes(): void + { + // set up an refresh token, but do not persist it + $refreshToken = new RefreshToken(); + $refreshToken->setToken('test-token'); + + // update the refresh token + $this->refreshTokenManager->updateToken($refreshToken); + + // confirm the refresh token is persisted and flushed + $this->documentManager->clear(); + $foundRefreshToken = $this->refreshTokenManager->findTokenByToken('test-token'); + + self::assertInstanceOf(RefreshToken::class, $foundRefreshToken); + self::assertStringMatchesFormat('%s', $foundRefreshToken->getId()); + } + + /** + * Verify an refresh token can be removed. + */ + public function testDeleteToken(): void + { + // set up an refresh token + $refreshToken = new RefreshToken(); + $refreshToken->setToken('test-token'); + $this->documentManager->persist($refreshToken); + $this->documentManager->flush(); + + // remove the refresh token + $this->refreshTokenManager->deleteToken($refreshToken); + + // confirm the refresh token can't be found + $this->documentManager->clear(); + + self::assertNull($this->refreshTokenManager->findTokenByToken('test-token')); + } + + /** + * Verify all expired refresh tokens can be removed in one operation. + */ + public function testDeleteExpired(): void + { + // set up an refresh token that expired one second ago + $expiredRefreshToken1 = new RefreshToken(); + $expiredRefreshToken1->setToken('expired-test-token-1'); + $expiredRefreshToken1->setExpiresAt(time() - 1); + $this->documentManager->persist($expiredRefreshToken1); + + // set up an refresh token that expires in 10 seconds (avoid false failure + // if the test host stalls) + $unexpiredRefreshToken = new RefreshToken(); + $unexpiredRefreshToken->setToken('unexpired-test-token'); + $unexpiredRefreshToken->setExpiresAt(time() + 10); + $this->documentManager->persist($unexpiredRefreshToken); + + // set up another refresh token that expired + $expiredRefreshToken2 = new RefreshToken(); + $expiredRefreshToken2->setToken('expired-test-token-2'); + $expiredRefreshToken2->setExpiresAt(time() - 10); + $this->documentManager->persist($expiredRefreshToken2); + + $this->documentManager->flush(); + + // clear the new documents from doctrine memory + $this->documentManager->clear(); + + // delete all expired + self::assertSame(2, $this->refreshTokenManager->deleteExpired()); + + // confirm only the unexpired refresh token is found + self::assertNull($this->refreshTokenManager->findTokenByToken('expired-test-token-1')); + self::assertNull($this->refreshTokenManager->findTokenByToken('expired-test-token-2')); + self::assertInstanceOf(RefreshToken::class, $this->refreshTokenManager->findTokenByToken('unexpired-test-token')); + } +} diff --git a/Tests/Document/TokenManagerTest.php b/Tests/Document/TokenManagerTest.php index ff166d34..15903cb7 100644 --- a/Tests/Document/TokenManagerTest.php +++ b/Tests/Document/TokenManagerTest.php @@ -13,12 +13,12 @@ namespace FOS\OAuthServerBundle\Tests\Document; -use Doctrine\MongoDB\Query\Query; use Doctrine\ODM\MongoDB\DocumentManager; -use Doctrine\ODM\MongoDB\DocumentRepository; -use Doctrine\ODM\MongoDB\Query\Builder; +use Doctrine\ODM\MongoDB\Repository\DocumentRepository; use FOS\OAuthServerBundle\Document\AccessToken; use FOS\OAuthServerBundle\Document\TokenManager; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; /** * @group time-sensitive @@ -27,7 +27,7 @@ * * @author Nikola Petkanski */ -class TokenManagerTest extends \PHPUnit\Framework\TestCase +class TokenManagerTest extends TestCase { /** * @var string @@ -35,12 +35,12 @@ class TokenManagerTest extends \PHPUnit\Framework\TestCase protected $className; /** - * @var \PHPUnit_Framework_MockObject_MockObject|DocumentManager + * @var MockObject|DocumentManager */ protected $documentManager; /** - * @var \PHPUnit_Framework_MockObject_MockObject|DocumentRepository + * @var MockObject|DocumentRepository */ protected $repository; @@ -49,9 +49,9 @@ class TokenManagerTest extends \PHPUnit\Framework\TestCase */ protected $instance; - public function setUp() + public function setUp(): void { - if (!class_exists('\Doctrine\ODM\MongoDB\DocumentManager')) { + if (!class_exists(DocumentManager::class)) { $this->markTestSkipped('Doctrine MongoDB ODM has to be installed for this test to run.'); } @@ -75,134 +75,8 @@ public function setUp() $this->instance = new TokenManager($this->documentManager, $this->className); } - public function testFindTokenByToken() + public function testGetClass(): void { - $randomToken = \random_bytes(5); - $randomResult = \random_bytes(5); - - $this->repository - ->expects($this->once()) - ->method('findOneBy') - ->with([ - 'token' => $randomToken, - ]) - ->willReturn($randomResult) - ; - - $this->assertSame($randomResult, $this->instance->findTokenByToken($randomToken)); - } - - public function testUpdateTokenPersistsAndFlushes() - { - $token = $this->getMockBuilder(AccessToken::class) - ->disableOriginalConstructor() - ->getMock() - ; - - $this->documentManager - ->expects($this->once()) - ->method('persist') - ->with($token) - ; - - $this->documentManager - ->expects($this->once()) - ->method('flush') - ->with() - ; - - $this->assertNull($this->instance->updateToken($token)); - } - - public function testGetClass() - { - $this->assertSame($this->className, $this->instance->getClass()); - } - - public function testDeleteToken() - { - $token = $this->getMockBuilder(AccessToken::class) - ->disableOriginalConstructor() - ->getMock() - ; - - $this->documentManager - ->expects($this->once()) - ->method('remove') - ->with($token) - ->willReturn(null) - ; - - $this->documentManager - ->expects($this->once()) - ->method('flush') - ->with() - ->willReturn(null) - ; - - $this->assertNull($this->instance->deleteToken($token)); - } - - public function testDeleteExpired() - { - $queryBuilder = $this->getMockBuilder(Builder::class) - ->disableOriginalConstructor() - ->getMock() - ; - - $this->repository - ->expects($this->once()) - ->method('createQueryBuilder') - ->with() - ->willReturn($queryBuilder) - ; - - $queryBuilder - ->expects($this->once()) - ->method('remove') - ->with() - ->willReturn($queryBuilder) - ; - - $queryBuilder - ->expects($this->once()) - ->method('field') - ->with('expiresAt') - ->willReturn($queryBuilder) - ; - - $queryBuilder - ->expects($this->once()) - ->method('lt') - ->with(time()) - ->willReturn($queryBuilder) - ; - - $query = $this->getMockBuilder(Query::class) - ->disableOriginalConstructor() - ->getMock() - ; - - $queryBuilder - ->expects($this->once()) - ->method('getQuery') - ->with([ - 'safe' => true, - ]) - ->willReturn($query) - ; - - $data = [ - 'n' => \random_bytes(5), - ]; - - $query - ->expects($this->once()) - ->method('execute') - ->with() - ->willReturn($data) - ; - - $this->assertSame($data['n'], $this->instance->deleteExpired()); + self::assertSame($this->className, $this->instance->getClass()); } } diff --git a/Tests/Entity/AuthCodeManagerTest.php b/Tests/Entity/AuthCodeManagerTest.php index ccdd9409..cba3f505 100644 --- a/Tests/Entity/AuthCodeManagerTest.php +++ b/Tests/Entity/AuthCodeManagerTest.php @@ -20,6 +20,8 @@ use Doctrine\ORM\QueryBuilder; use FOS\OAuthServerBundle\Entity\AuthCodeManager; use FOS\OAuthServerBundle\Model\AuthCodeInterface; +use FOS\OAuthServerBundle\Tests\TestCase; +use PHPUnit\Framework\MockObject\MockObject; /** * @group time-sensitive @@ -28,10 +30,10 @@ * * @author Nikola Petkanski */ -class AuthCodeManagerTest extends \PHPUnit\Framework\TestCase +class AuthCodeManagerTest extends TestCase { /** - * @var \PHPUnit_Framework_MockObject_MockObject|EntityManagerInterface + * @var MockObject|EntityManagerInterface */ protected $entityManager; @@ -45,31 +47,31 @@ class AuthCodeManagerTest extends \PHPUnit\Framework\TestCase */ protected $instance; - public function setUp() + public function setUp(): void { $this->entityManager = $this->getMockBuilder(EntityManagerInterface::class) ->disableOriginalConstructor() ->getMock() ; - $this->className = 'TestClassName'.\random_bytes(5); + $this->className = 'TestClassName'; $this->instance = new AuthCodeManager($this->entityManager, $this->className); parent::setUp(); } - public function testConstructWillSetParameters() + public function testConstructWillSetParameters(): void { - $this->assertAttributeSame($this->entityManager, 'em', $this->instance); - $this->assertAttributeSame($this->className, 'class', $this->instance); + self::assertObjectPropertySame($this->entityManager, $this->instance, 'em'); + self::assertSame($this->className, $this->instance->getClass()); } - public function testGetClassWillReturnClassName() + public function testGetClassWillReturnClassName(): void { - $this->assertSame($this->className, $this->instance->getClass()); + self::assertSame($this->className, $this->instance->getClass()); } - public function testFindAuthCodeBy() + public function testFindAuthCodeBy(): void { $repository = $this->getMockBuilder(ObjectRepository::class) ->disableOriginalConstructor() @@ -95,10 +97,10 @@ public function testFindAuthCodeBy() ->willReturn($randomResult) ; - $this->assertSame($randomResult, $this->instance->findAuthCodeBy($criteria)); + self::assertSame($randomResult, $this->instance->findAuthCodeBy($criteria)); } - public function testUpdateAuthCode() + public function testUpdateAuthCode(): void { $authCode = $this->getMockBuilder(AuthCodeInterface::class) ->disableOriginalConstructor() @@ -119,10 +121,10 @@ public function testUpdateAuthCode() ->willReturn(null) ; - $this->assertNull($this->instance->updateAuthCode($authCode)); + self::assertNull($this->instance->updateAuthCode($authCode)); } - public function testDeleteAuthCode() + public function testDeleteAuthCode(): void { $authCode = $this->getMockBuilder(AuthCodeInterface::class) ->disableOriginalConstructor() @@ -143,10 +145,10 @@ public function testDeleteAuthCode() ->willReturn(null) ; - $this->assertNull($this->instance->deleteAuthCode($authCode)); + self::assertNull($this->instance->deleteAuthCode($authCode)); } - public function testDeleteExpired() + public function testDeleteExpired(): void { $randomResult = \random_bytes(10); @@ -214,6 +216,6 @@ public function testDeleteExpired() ->willReturn($randomResult) ; - $this->assertSame($randomResult, $this->instance->deleteExpired()); + self::assertSame($randomResult, $this->instance->deleteExpired()); } } diff --git a/Tests/Entity/ClientManagerTest.php b/Tests/Entity/ClientManagerTest.php index d575d320..194ab5f4 100644 --- a/Tests/Entity/ClientManagerTest.php +++ b/Tests/Entity/ClientManagerTest.php @@ -17,16 +17,19 @@ use Doctrine\ORM\EntityRepository; use FOS\OAuthServerBundle\Entity\ClientManager; use FOS\OAuthServerBundle\Model\ClientInterface; +use FOS\OAuthServerBundle\Tests\TestCase; +use PHPUnit\Framework\MockObject\MockObject; +use function random_bytes; /** * Class ClientManagerTest. * * @author Nikola Petkanski */ -class ClientManagerTest extends \PHPUnit\Framework\TestCase +class ClientManagerTest extends TestCase { /** - * @var \PHPUnit_Framework_MockObject_MockObject|EntityManagerInterface + * @var MockObject|EntityManagerInterface */ protected $entityManager; @@ -36,7 +39,7 @@ class ClientManagerTest extends \PHPUnit\Framework\TestCase protected $className; /** - * @var \PHPUnit_Framework_MockObject_MockObject|EntityRepository + * @var MockObject|EntityRepository */ protected $repository; @@ -45,7 +48,7 @@ class ClientManagerTest extends \PHPUnit\Framework\TestCase */ protected $instance; - public function setUp() + public function setUp(): void { $this->entityManager = $this->getMockBuilder(EntityManagerInterface::class) ->disableOriginalConstructor() @@ -55,7 +58,7 @@ public function setUp() ->disableOriginalConstructor() ->getMock() ; - $this->className = 'RandomClassName'.\random_bytes(5); + $this->className = 'RandomClassName'.random_bytes(5); $this->entityManager ->expects($this->once()) @@ -69,24 +72,24 @@ public function setUp() parent::setUp(); } - public function testConstructWillSetParameters() + public function testConstructWillSetParameters(): void { - $this->assertAttributeSame($this->entityManager, 'em', $this->instance); - $this->assertAttributeSame($this->repository, 'repository', $this->instance); - $this->assertAttributeSame($this->className, 'class', $this->instance); + self::assertObjectPropertySame($this->entityManager, $this->instance, 'em'); + self::assertObjectPropertySame($this->repository, $this->instance, 'repository'); + self::assertSame($this->className, $this->instance->getClass()); } - public function testGetClass() + public function testGetClass(): void { - $this->assertSame($this->className, $this->instance->getClass()); + self::assertSame($this->className, $this->instance->getClass()); } - public function testFindClientBy() + public function testFindClientBy(): void { $criteria = [ - \random_bytes(5), + random_bytes(5), ]; - $randomResult = \random_bytes(5); + $randomResult = random_bytes(5); $this->repository ->expects($this->once()) @@ -95,10 +98,10 @@ public function testFindClientBy() ->willReturn($randomResult) ; - $this->assertSame($randomResult, $this->instance->findClientBy($criteria)); + self::assertSame($randomResult, $this->instance->findClientBy($criteria)); } - public function testUpdateClient() + public function testUpdateClient(): void { $client = $this->getMockBuilder(ClientInterface::class) ->disableOriginalConstructor() @@ -119,10 +122,10 @@ public function testUpdateClient() ->willReturn(null) ; - $this->assertNull($this->instance->updateClient($client)); + self::assertNull($this->instance->updateClient($client)); } - public function testDeleteClient() + public function testDeleteClient(): void { $client = $this->getMockBuilder(ClientInterface::class) ->disableOriginalConstructor() @@ -143,6 +146,6 @@ public function testDeleteClient() ->willReturn(null) ; - $this->assertNull($this->instance->deleteClient($client)); + self::assertNull($this->instance->deleteClient($client)); } } diff --git a/Tests/Entity/TokenManagerTest.php b/Tests/Entity/TokenManagerTest.php index acdeca16..97f03543 100644 --- a/Tests/Entity/TokenManagerTest.php +++ b/Tests/Entity/TokenManagerTest.php @@ -21,6 +21,9 @@ use FOS\OAuthServerBundle\Entity\AccessToken; use FOS\OAuthServerBundle\Entity\TokenManager; use FOS\OAuthServerBundle\Model\TokenInterface; +use FOS\OAuthServerBundle\Tests\TestCase; +use PHPUnit\Framework\MockObject\MockObject; +use function random_bytes; /** * @group time-sensitive @@ -29,15 +32,15 @@ * * @author Nikola Petkanski */ -class TokenManagerTest extends \PHPUnit\Framework\TestCase +class TokenManagerTest extends TestCase { /** - * @var \PHPUnit_Framework_MockObject_MockObject|EntityManagerInterface + * @var MockObject|EntityManagerInterface */ protected $entityManager; /** - * @var \PHPUnit_Framework_MockObject_MockObject|EntityRepository + * @var MockObject|EntityRepository */ protected $repository; @@ -51,7 +54,7 @@ class TokenManagerTest extends \PHPUnit\Framework\TestCase */ protected $instance; - public function setUp() + public function setUp(): void { $this->className = AccessToken::class; $this->repository = $this->getMockBuilder(EntityRepository::class) @@ -73,14 +76,14 @@ public function setUp() $this->instance = new TokenManager($this->entityManager, $this->className); } - public function testConstructWillSetParameters() + public function testConstructWillSetParameters(): void { - $this->assertAttributeSame($this->entityManager, 'em', $this->instance); - $this->assertAttributeSame($this->repository, 'repository', $this->instance); - $this->assertAttributeSame($this->className, 'class', $this->instance); + self::assertObjectPropertySame($this->entityManager, $this->instance, 'em'); + self::assertObjectPropertySame($this->repository, $this->instance, 'repository'); + self::assertSame($this->className, $this->instance->getClass()); } - public function testUpdateTokenPersistsAndFlushes() + public function testUpdateTokenPersistsAndFlushes(): void { $token = new AccessToken(); @@ -96,20 +99,20 @@ public function testUpdateTokenPersistsAndFlushes() ->with() ; - $this->assertNull($this->instance->updateToken($token)); + self::assertNull($this->instance->updateToken($token)); } - public function testGetClass() + public function testGetClass(): void { - $this->assertSame($this->className, $this->instance->getClass()); + self::assertSame($this->className, $this->instance->getClass()); } - public function testFindTokenBy() + public function testFindTokenBy(): void { - $randomResult = \random_bytes(5); + $randomResult = random_bytes(5); $criteria = [ - \random_bytes(5), + random_bytes(5), ]; $this->repository @@ -119,11 +122,12 @@ public function testFindTokenBy() ->willReturn($randomResult) ; - $this->assertSame($randomResult, $this->instance->findTokenBy($criteria)); + self::assertSame($randomResult, $this->instance->findTokenBy($criteria)); } - public function testUpdateToken() + public function testUpdateToken(): void { + /** @var TokenInterface $token */ $token = $this->getMockBuilder(TokenInterface::class) ->disableOriginalConstructor() ->getMock() @@ -143,11 +147,12 @@ public function testUpdateToken() ->willReturn(null) ; - $this->assertNull($this->instance->updateToken($token)); + self::assertNull($this->instance->updateToken($token)); } - public function testDeleteToken() + public function testDeleteToken(): void { + /** @var TokenInterface $token */ $token = $this->getMockBuilder(TokenInterface::class) ->disableOriginalConstructor() ->getMock() @@ -167,12 +172,12 @@ public function testDeleteToken() ->willReturn(null) ; - $this->assertNull($this->instance->deleteToken($token)); + self::assertNull($this->instance->deleteToken($token)); } - public function testDeleteExpired() + public function testDeleteExpired(): void { - $randomResult = \random_bytes(10); + $randomResult = random_bytes(10); $queryBuilder = $this->getMockBuilder(QueryBuilder::class) ->disableOriginalConstructor() @@ -226,6 +231,6 @@ public function testDeleteExpired() ->willReturn($randomResult) ; - $this->assertSame($randomResult, $this->instance->deleteExpired()); + self::assertSame($randomResult, $this->instance->deleteExpired()); } } diff --git a/Tests/FOSOAuthServerBundleTest.php b/Tests/FOSOAuthServerBundleTest.php index 049229e6..c74c1fb1 100644 --- a/Tests/FOSOAuthServerBundleTest.php +++ b/Tests/FOSOAuthServerBundleTest.php @@ -16,21 +16,17 @@ use FOS\OAuthServerBundle\DependencyInjection\Compiler; use FOS\OAuthServerBundle\DependencyInjection\Security\Factory\OAuthFactory; use FOS\OAuthServerBundle\FOSOAuthServerBundle; +use PHPUnit\Framework\MockObject\MockObject; use Symfony\Bundle\SecurityBundle\DependencyInjection\SecurityExtension; use Symfony\Component\DependencyInjection\ContainerBuilder; class FOSOAuthServerBundleTest extends \PHPUnit\Framework\TestCase { - protected function setUp() - { - parent::setUp(); - } - - public function testConstruction() + public function testConstruction(): void { $bundle = new FOSOAuthServerBundle(); - /** @var ContainerBuilder|\PHPUnit_Framework_MockObject_MockObject $containerBuilder */ + /** @var ContainerBuilder|MockObject $containerBuilder */ $containerBuilder = $this->getMockBuilder(ContainerBuilder::class) ->disableOriginalConstructor() ->setMethods([ @@ -40,7 +36,7 @@ public function testConstruction() ->getMock() ; - /** @var SecurityExtension|\PHPUnit_Framework_MockObject_MockObject $securityExtension */ + /** @var SecurityExtension|MockObject $securityExtension */ $securityExtension = $this->getMockBuilder(SecurityExtension::class) ->disableOriginalConstructor() ->getMock() @@ -64,9 +60,8 @@ public function testConstruction() ->expects($this->at(1)) ->method('addCompilerPass') ->withConsecutive( - new Compiler\GrantExtensionsCompilerPass(), - new Compiler\TokenStorageCompilerPass(), - new Compiler\RequestStackCompilerPass() + [new Compiler\GrantExtensionsCompilerPass()], + [new Compiler\RequestStackCompilerPass()] ) ->willReturnOnConsecutiveCalls( $containerBuilder, @@ -75,6 +70,6 @@ public function testConstruction() ) ; - $this->assertNull($bundle->build($containerBuilder)); + self::assertNull($bundle->build($containerBuilder)); } } diff --git a/Tests/Form/Handler/AuthorizeFormHandlerTest.php b/Tests/Form/Handler/AuthorizeFormHandlerTest.php index d680a1d8..4e888615 100644 --- a/Tests/Form/Handler/AuthorizeFormHandlerTest.php +++ b/Tests/Form/Handler/AuthorizeFormHandlerTest.php @@ -15,28 +15,35 @@ use FOS\OAuthServerBundle\Form\Handler\AuthorizeFormHandler; use FOS\OAuthServerBundle\Form\Model\Authorize; -use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Serialization\Author; +use FOS\OAuthServerBundle\Tests\TestCase; +use InvalidArgumentException; +use PHPUnit\Framework\MockObject\MockObject; +use function random_bytes; +use ReflectionException; +use ReflectionMethod; +use ReflectionObject; +use stdClass; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; -/** - * Class AuthorizeFormHandlerTest. - * - * @author Nikola Petkanski - */ -class AuthorizeFormHandlerTest extends \PHPUnit\Framework\TestCase +class AuthorizeFormHandlerTest extends TestCase { + /** @var FormInterface | MockObject */ protected $form; + /** @var Request | MockObject */ protected $request; + /** @var ParameterBag | MockObject */ protected $requestQuery; + /** @var ParameterBag | MockObject */ protected $requestRequest; + /** @var ContainerInterface | MockObject */ protected $container; /** @@ -44,7 +51,7 @@ class AuthorizeFormHandlerTest extends \PHPUnit\Framework\TestCase */ protected $instance; - public function setUp() + public function setUp(): void { $this->form = $this->getMockBuilder(FormInterface::class) ->disableOriginalConstructor() @@ -78,7 +85,7 @@ public function setUp() parent::setUp(); } - public function testConstructWillAcceptRequestObjectAsRequest() + public function testConstructWillAcceptRequestObjectAsRequest(): void { $request = $this->getMockBuilder(Request::class) ->disableOriginalConstructor() @@ -87,11 +94,10 @@ public function testConstructWillAcceptRequestObjectAsRequest() $this->instance = new AuthorizeFormHandler($this->form, $request); - $this->assertAttributeSame($this->form, 'form', $this->instance); - $this->assertAttributeSame($request, 'requestStack', $this->instance); + $this->assertAttributesWereSet($request); } - public function testConstructWillAcceptRequestStackObjectAsRequest() + public function testConstructWillAcceptRequestStackObjectAsRequest(): void { $requestStack = $this->getMockBuilder(RequestStack::class) ->disableOriginalConstructor() @@ -100,38 +106,35 @@ public function testConstructWillAcceptRequestStackObjectAsRequest() $this->instance = new AuthorizeFormHandler($this->form, $requestStack); - $this->assertAttributeSame($this->form, 'form', $this->instance); - $this->assertAttributeSame($requestStack, 'requestStack', $this->instance); + $this->assertAttributesWereSet($requestStack); } public function testConstructWillAcceptNullAsRequest() { $this->instance = new AuthorizeFormHandler($this->form, null); - $this->assertAttributeSame($this->form, 'form', $this->instance); - $this->assertAttributeSame(null, 'requestStack', $this->instance); + $this->assertAttributesWereSet(null); $this->instance = new AuthorizeFormHandler($this->form); - $this->assertAttributeSame($this->form, 'form', $this->instance); - $this->assertAttributeSame(null, 'requestStack', $this->instance); + $this->assertAttributesWereSet(null); } - public function testConstructWillThrowException() + public function testConstructWillThrowException(): void { $exceptionMessage = sprintf( 'Argument 2 of %s must be an instanceof RequestStack or Request', AuthorizeFormHandler::class ); - $this->expectException(\InvalidArgumentException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage($exceptionMessage); - new AuthorizeFormHandler($this->form, new \stdClass()); + new AuthorizeFormHandler($this->form, new stdClass()); } - public function testIsAcceptedWillProxyValueToFormData() + public function testIsAcceptedWillProxyValueToFormData(): void { - $data = new \stdClass(); - $data->accepted = \random_bytes(10); + $data = new stdClass(); + $data->accepted = random_bytes(10); $this->form ->expects($this->once()) @@ -140,15 +143,15 @@ public function testIsAcceptedWillProxyValueToFormData() ->willReturn($data) ; - $this->assertSame($data->accepted, $this->instance->isAccepted()); + self::assertSame($data->accepted, $this->instance->isAccepted()); } - public function testIsRejectedWillNegateAcceptedValueFromFormData() + public function testIsRejectedWillNegateAcceptedValueFromFormData(): void { - $dataWithAcceptedValueFalse = new \stdClass(); + $dataWithAcceptedValueFalse = new stdClass(); $dataWithAcceptedValueFalse->accepted = false; - $dataWithAcceptedValueTrue = new \stdClass(); + $dataWithAcceptedValueTrue = new stdClass(); $dataWithAcceptedValueTrue->accepted = true; $this->form @@ -160,14 +163,14 @@ public function testIsRejectedWillNegateAcceptedValueFromFormData() ) ; - $this->assertTrue($this->instance->isRejected()); - $this->assertFalse($this->instance->isRejected()); + self::assertTrue($this->instance->isRejected()); + self::assertFalse($this->instance->isRejected()); } - public function testGetScopeWillProxyValueToFormData() + public function testGetScopeWillProxyValueToFormData(): void { - $data = new \stdClass(); - $data->scope = \random_bytes(10); + $data = new stdClass(); + $data->scope = random_bytes(10); $this->form ->expects($this->once()) @@ -176,16 +179,16 @@ public function testGetScopeWillProxyValueToFormData() ->willReturn($data) ; - $this->assertSame($data->scope, $this->instance->getScope()); + self::assertSame($data->scope, $this->instance->getScope()); } - public function testGetCurrentRequestWillReturnRequestObject() + public function testGetCurrentRequestWillReturnRequestObject(): void { $method = $this->getReflectionMethod('getCurrentRequest'); - $this->assertSame($this->request, $method->invoke($this->instance)); + self::assertSame($this->request, $method->invoke($this->instance)); } - public function testGetCurrentRequestWillReturnCurrentRequestFromRequestStack() + public function testGetCurrentRequestWillReturnCurrentRequestFromRequestStack(): void { $requestStack = $this->getMockBuilder(RequestStack::class) ->disableOriginalConstructor() @@ -193,7 +196,7 @@ public function testGetCurrentRequestWillReturnCurrentRequestFromRequestStack() ; $this->instance = new AuthorizeFormHandler($this->form, $requestStack); - $request = new \stdClass(); + $request = new stdClass(); $requestStack ->expects($this->once()) @@ -203,15 +206,15 @@ public function testGetCurrentRequestWillReturnCurrentRequestFromRequestStack() ; $method = $this->getReflectionMethod('getCurrentRequest'); - $this->assertSame($request, $method->invoke($this->instance)); + self::assertSame($request, $method->invoke($this->instance)); } - public function testGetCurrentRequestWillReturnRequestServiceFromContainerIfNoneIsSet() + public function testGetCurrentRequestWillReturnRequestServiceFromContainerIfNoneIsSet(): void { $this->instance = new AuthorizeFormHandler($this->form, null); $this->instance->setContainer($this->container); - $randomData = \random_bytes(10); + $randomData = random_bytes(10); $this->container ->expects($this->at(0)) @@ -221,22 +224,22 @@ public function testGetCurrentRequestWillReturnRequestServiceFromContainerIfNone ; $method = $this->getReflectionMethod('getCurrentRequest'); - $this->assertSame($randomData, $method->invoke($this->instance)); + self::assertSame($randomData, $method->invoke($this->instance)); } /** * @TODO Fix this behavior. This method MUST not modify $_GET. */ - public function testOnSuccessWillReplaceGETSuperGlobal() + public function testOnSuccessWillReplaceGETSuperGlobal(): void { $method = $this->getReflectionMethod('onSuccess'); - $data = new \stdClass(); - $data->client_id = \random_bytes(10); - $data->response_type = \random_bytes(10); - $data->redirect_uri = \random_bytes(10); - $data->state = \random_bytes(10); - $data->scope = \random_bytes(10); + $data = new stdClass(); + $data->client_id = random_bytes(10); + $data->response_type = random_bytes(10); + $data->redirect_uri = random_bytes(10); + $data->state = random_bytes(10); + $data->scope = random_bytes(10); $this->form ->expects($this->exactly(5)) @@ -255,12 +258,12 @@ public function testOnSuccessWillReplaceGETSuperGlobal() 'scope' => $data->scope, ]; - $this->assertNull($method->invoke($this->instance)); + self::assertNull($method->invoke($this->instance)); - $this->assertSame($expectedSuperGlobalValue, $_GET); + self::assertSame($expectedSuperGlobalValue, $_GET); } - public function testProcessWillReturnFalseIfRequestIsNull() + public function testProcessWillReturnFalseIfRequestIsNull(): void { $this->instance = new AuthorizeFormHandler($this->form, null); $this->instance->setContainer($this->container); @@ -272,10 +275,10 @@ public function testProcessWillReturnFalseIfRequestIsNull() ->willReturn(null) ; - $this->assertFalse($this->instance->process()); + self::assertFalse($this->instance->process()); } - public function testProcessWillSetFormData() + public function testProcessWillSetFormData(): void { $this->requestRequest ->expects($this->once()) @@ -285,8 +288,8 @@ public function testProcessWillSetFormData() ; $dataMock = [ - \random_bytes(10), - \random_bytes(10), + random_bytes(10), + random_bytes(10), ]; $this->requestQuery @@ -306,10 +309,10 @@ public function testProcessWillSetFormData() ->willReturn($this->form) ; - $this->assertFalse($this->instance->process()); + self::assertFalse($this->instance->process()); } - public function testProcessWillHandleRequestOnPost() + public function testProcessWillHandleRequestOnPost(): void { $this->requestRequest ->expects($this->once()) @@ -319,8 +322,8 @@ public function testProcessWillHandleRequestOnPost() ; $dataMock = [ - \random_bytes(10), - \random_bytes(10), + random_bytes(10), + random_bytes(10), ]; $this->requestQuery @@ -354,6 +357,13 @@ public function testProcessWillHandleRequestOnPost() ->willReturn($this->form) ; + $this->form + ->expects($this->once()) + ->method('isSubmitted') + ->with() + ->willReturn(true) + ; + $this->form ->expects($this->once()) ->method('isValid') @@ -361,10 +371,10 @@ public function testProcessWillHandleRequestOnPost() ->willReturn(false) ; - $this->assertFalse($this->instance->process()); + self::assertFalse($this->instance->process()); } - public function testProcessWillHandleRequestOnPostAndWillProcessDataIfFormIsValid() + public function testProcessWillHandleRequestOnPostAndWillProcessDataIfFormIsValid(): void { $this->requestRequest ->expects($this->once()) @@ -373,12 +383,12 @@ public function testProcessWillHandleRequestOnPostAndWillProcessDataIfFormIsVali ->willReturn(true) ; - $query = new \stdClass(); - $query->client_id = \random_bytes(10); - $query->response_type = \random_bytes(10); - $query->redirect_uri = \random_bytes(10); - $query->state = \random_bytes(10); - $query->scope = \random_bytes(10); + $query = new stdClass(); + $query->client_id = random_bytes(10); + $query->response_type = random_bytes(10); + $query->redirect_uri = random_bytes(10); + $query->state = random_bytes(10); + $query->scope = random_bytes(10); $this->requestQuery ->expects($this->once()) @@ -413,6 +423,13 @@ public function testProcessWillHandleRequestOnPostAndWillProcessDataIfFormIsVali ->willReturn($this->form) ; + $this->form + ->expects($this->once()) + ->method('isSubmitted') + ->with() + ->willReturn(true) + ; + $this->form ->expects($this->once()) ->method('isValid') @@ -427,7 +444,7 @@ public function testProcessWillHandleRequestOnPostAndWillProcessDataIfFormIsVali ->willReturn($formData) ; - $this->assertSame([], $_GET); + self::assertSame([], $_GET); $expectedSuperGlobalValue = [ 'client_id' => $query->client_id, @@ -437,22 +454,29 @@ public function testProcessWillHandleRequestOnPostAndWillProcessDataIfFormIsVali 'scope' => $query->scope, ]; - $this->assertTrue($this->instance->process()); + self::assertTrue($this->instance->process()); - $this->assertSame($expectedSuperGlobalValue, $_GET); + self::assertSame($expectedSuperGlobalValue, $_GET); } /** - * @param string $methodName - * - * @return \ReflectionMethod + * @throws ReflectionException */ - protected function getReflectionMethod($methodName) + protected function getReflectionMethod(string $methodName): ReflectionMethod { - $reflectionObject = new \ReflectionObject($this->instance); + $reflectionObject = new ReflectionObject($this->instance); $reflectionMethod = $reflectionObject->getMethod($methodName); $reflectionMethod->setAccessible(true); return $reflectionMethod; } + + /** + * @param MockObject $request + */ + private function assertAttributesWereSet(?MockObject $request): void + { + self::assertObjectPropertySame($this->form, $this->instance, 'form'); + self::assertObjectPropertySame($request, $this->instance, 'requestStack'); + } } diff --git a/Tests/Form/Type/AuthorizeFormTypeTest.php b/Tests/Form/Type/AuthorizeFormTypeTest.php index a4c77ae6..8a743dc9 100644 --- a/Tests/Form/Type/AuthorizeFormTypeTest.php +++ b/Tests/Form/Type/AuthorizeFormTypeTest.php @@ -16,6 +16,8 @@ use FOS\OAuthServerBundle\Form\Model\Authorize; use FOS\OAuthServerBundle\Form\Type\AuthorizeFormType; use FOS\OAuthServerBundle\Util\LegacyFormHelper; +use PHPUnit\Framework\MockObject\MockObject; +use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilder; use Symfony\Component\Form\Forms; use Symfony\Component\Form\Test\TypeTestCase; @@ -28,7 +30,7 @@ class AuthorizeFormTypeTest extends TypeTestCase */ protected $instance; - protected function setUp() + protected function setUp(): void { parent::setUp(); @@ -42,7 +44,7 @@ protected function setUp() $this->instance = new AuthorizeFormType(); } - public function testSubmit() + public function testSubmit(): void { $accepted = true; $formData = [ @@ -55,25 +57,25 @@ public function testSubmit() $authorize = new Authorize($accepted, $formData); - $form = $this->factory->create(LegacyFormHelper::getType('FOS\OAuthServerBundle\Form\Type\AuthorizeFormType'), $authorize); + $form = $this->factory->create(LegacyFormHelper::getType(AuthorizeFormType::class), $authorize); $form->submit($formData); - $this->assertTrue($form->isSynchronized()); - $this->assertSame($authorize, $form->getData()); - $this->assertSame($accepted, $authorize->accepted); + self::assertTrue($form->isSynchronized()); + self::assertSame($authorize, $form->getData()); + self::assertSame($accepted, $authorize->accepted); $view = $form->createView(); $children = $view->children; foreach (array_keys($formData) as $key) { - $this->assertArrayHasKey($key, $children); + self::assertArrayHasKey($key, $children); } } - public function testConfigureOptionsWillSetDefaultsOnTheOptionsResolver() + public function testConfigureOptionsWillSetDefaultsOnTheOptionsResolver(): void { - /** @var \PHPUnit_Framework_MockObject_MockObject|OptionsResolver $resolver */ + /** @var MockObject|OptionsResolver $resolver */ $resolver = $this->getMockBuilder(OptionsResolver::class) ->disableOriginalConstructor() ->getMock() @@ -83,25 +85,29 @@ public function testConfigureOptionsWillSetDefaultsOnTheOptionsResolver() ->expects($this->once()) ->method('setDefaults') ->with([ - 'data_class' => 'FOS\OAuthServerBundle\Form\Model\Authorize', + 'data_class' => Authorize::class, + 'validation_groups' => [], ]) ->willReturn($resolver) ; - $this->assertNull($this->instance->configureOptions($resolver)); + self::assertNull($this->instance->configureOptions($resolver)); } - public function testGetName() + public function testGetName(): void { - $this->assertSame('fos_oauth_server_authorize', $this->instance->getName()); + self::assertSame('fos_oauth_server_authorize', $this->instance->getName()); } - public function testGetBlockPrefix() + public function testGetBlockPrefix(): void { - $this->assertSame('fos_oauth_server_authorize', $this->instance->getBlockPrefix()); + self::assertSame('fos_oauth_server_authorize', $this->instance->getBlockPrefix()); } - protected function getTypes() + /** + * @return array + */ + protected function getTypes(): array { return [ new AuthorizeFormType(), diff --git a/Tests/Functional/AppKernel.php b/Tests/Functional/AppKernel.php index e97ffc18..a5b065b8 100644 --- a/Tests/Functional/AppKernel.php +++ b/Tests/Functional/AppKernel.php @@ -21,16 +21,18 @@ class AppKernel extends Kernel public function registerBundles() { $bundles = [ + new \FOS\OAuthServerBundle\FOSOAuthServerBundle(), + new \FOS\OAuthServerBundle\Tests\Functional\TestBundle\TestBundle(), new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(), + new \Symfony\Bundle\MonologBundle\MonologBundle(), new \Symfony\Bundle\SecurityBundle\SecurityBundle(), new \Symfony\Bundle\TwigBundle\TwigBundle(), - new \FOS\OAuthServerBundle\FOSOAuthServerBundle(), - - new \FOS\OAuthServerBundle\Tests\Functional\TestBundle\TestBundle(), ]; if ('orm' === $this->getEnvironment()) { $bundles[] = new \Doctrine\Bundle\DoctrineBundle\DoctrineBundle(); + } elseif ('odm' === $this->getEnvironment()) { + $bundles[] = new \Doctrine\Bundle\MongoDBBundle\DoctrineMongoDBBundle(); } return $bundles; @@ -41,7 +43,7 @@ public function getCacheDir() return sys_get_temp_dir().'/FOSOAuthServerBundle/'; } - public function registerContainerConfiguration(LoaderInterface $loader) + public function registerContainerConfiguration(LoaderInterface $loader): void { $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml'); } diff --git a/Tests/Functional/BootTest.php b/Tests/Functional/BootTest.php index 331f88c0..3e8a4dd8 100644 --- a/Tests/Functional/BootTest.php +++ b/Tests/Functional/BootTest.php @@ -13,6 +13,8 @@ namespace FOS\OAuthServerBundle\Tests\Functional; +use Exception; + class BootTest extends TestCase { /** @@ -20,23 +22,24 @@ class BootTest extends TestCase * * @param string $env */ - public function testBoot($env) + public function testBoot($env): void { try { - $kernel = static::createKernel(['env' => $env]); + $kernel = static::createKernel(['environment' => $env]); $kernel->boot(); // no exceptions were thrown self::assertTrue(true); - } catch (\Exception $exception) { + } catch (Exception $exception) { $this->fail($exception->getMessage()); } } - public function getTestBootData() + public function getTestBootData(): array { return [ - ['orm'], + 'booting the kernel with SQL configurations' => ['env' => 'orm'], + 'booting the kernel with Mongo configurations' => ['env' => 'odm'], ]; } } diff --git a/Tests/Functional/TestBundle/Document/AccessToken.php b/Tests/Functional/TestBundle/Document/AccessToken.php new file mode 100644 index 00000000..6e9975ad --- /dev/null +++ b/Tests/Functional/TestBundle/Document/AccessToken.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\OAuthServerBundle\Tests\Functional\TestBundle\Document; + +use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB; +use FOS\OAuthServerBundle\Document\AccessToken as BaseAccessToken; +use FOS\OAuthServerBundle\Model\ClientInterface; +use Symfony\Component\Security\Core\User\UserInterface; + +/** + * @MongoDB\Document( + * db="fos_oauth_server_test", + * collection="access_token" + * ) + */ +class AccessToken extends BaseAccessToken +{ + /** + * @var int + * @MongoDB\Id + */ + protected $id; + + /** + * @var int + * @MongoDB\Field(type="int") + */ + protected $expiresAt; + + /** + * @var string + * @MongoDB\Field(type="string") + */ + protected $scope; + + /** + * @var string + * @MongoDB\Field(type="string") + */ + protected $token; + + /** + * @var ClientInterface + * @MongoDB\EmbedOne(targetDocument="FOS\OAuthServerBundle\Tests\Functional\TestBundle\Document\Client") + */ + protected $client; + + /** + * @var UserInterface + * @MongoDB\EmbedOne(targetDocument="FOS\OAuthServerBundle\Tests\Functional\TestBundle\Document\User") + */ + protected $user; +} diff --git a/Tests/Functional/TestBundle/Document/AuthCode.php b/Tests/Functional/TestBundle/Document/AuthCode.php new file mode 100644 index 00000000..dab6c55b --- /dev/null +++ b/Tests/Functional/TestBundle/Document/AuthCode.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\OAuthServerBundle\Tests\Functional\TestBundle\Document; + +use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB; +use FOS\OAuthServerBundle\Document\AuthCode as BaseAuthCode; +use FOS\OAuthServerBundle\Model\ClientInterface; +use Symfony\Component\Security\Core\User\UserInterface; + +/** + * @MongoDB\Document( + * db="fos_oauth_server_test", + * collection="auth_code" + * ) + */ +class AuthCode extends BaseAuthCode +{ + /** + * @var string + * @MongoDB\Id + */ + protected $id; + + /** + * @var int + * @MongoDB\Field(type="int") + */ + protected $expiresAt; + + /** + * @var string + * @MongoDB\Field(type="string") + */ + protected $scope; + + /** + * @var string + * @MongoDB\Field(type="string") + */ + protected $token; + + /** + * @var ClientInterface + * @MongoDB\EmbedOne(targetDocument="FOS\OAuthServerBundle\Tests\Functional\TestBundle\Document\Client") + */ + protected $client; + + /** + * @var UserInterface + * @MongoDB\EmbedOne(targetDocument="FOS\OAuthServerBundle\Tests\Functional\TestBundle\Document\User") + */ + protected $user; +} diff --git a/Tests/Functional/TestBundle/Document/Client.php b/Tests/Functional/TestBundle/Document/Client.php new file mode 100644 index 00000000..5e6e7f91 --- /dev/null +++ b/Tests/Functional/TestBundle/Document/Client.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\OAuthServerBundle\Tests\Functional\TestBundle\Document; + +use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB; +use FOS\OAuthServerBundle\Document\Client as BaseClient; + +/** + * @MongoDB\EmbeddedDocument + */ +class Client extends BaseClient +{ + /** + * @var int + * @MongoDB\Id + */ + protected $id; +} diff --git a/Tests/Functional/TestBundle/Document/RefreshToken.php b/Tests/Functional/TestBundle/Document/RefreshToken.php new file mode 100644 index 00000000..a781ce54 --- /dev/null +++ b/Tests/Functional/TestBundle/Document/RefreshToken.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\OAuthServerBundle\Tests\Functional\TestBundle\Document; + +use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB; +use FOS\OAuthServerBundle\Document\RefreshToken as BaseRefreshToken; +use FOS\OAuthServerBundle\Model\ClientInterface; +use Symfony\Component\Security\Core\User\UserInterface; + +/** + * @MongoDB\Document( + * db="fos_oauth_server_test", + * collection="refresh_token" + * ) + */ +class RefreshToken extends BaseRefreshToken +{ + /** + * @var int + * @MongoDB\Id + */ + protected $id; + + /** + * @var int + * @MongoDB\Field(type="int") + */ + protected $expiresAt; + + /** + * @var string + * @MongoDB\Field(type="string") + */ + protected $scope; + + /** + * @var string + * @MongoDB\Field(type="string") + */ + protected $token; + + /** + * @var ClientInterface + * @MongoDB\EmbedOne(targetDocument="FOS\OAuthServerBundle\Tests\Functional\TestBundle\Document\Client") + */ + protected $client; + + /** + * @var UserInterface + * @MongoDB\EmbedOne(targetDocument="FOS\OAuthServerBundle\Tests\Functional\TestBundle\Document\User") + */ + protected $user; +} diff --git a/Tests/Functional/TestBundle/Document/User.php b/Tests/Functional/TestBundle/Document/User.php new file mode 100644 index 00000000..47887458 --- /dev/null +++ b/Tests/Functional/TestBundle/Document/User.php @@ -0,0 +1,67 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\OAuthServerBundle\Tests\Functional\TestBundle\Document; + +use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB; +use Symfony\Component\Security\Core\User\UserInterface; + +/** + * @MongoDB\EmbeddedDocument + */ +class User implements UserInterface +{ + /** + * @MongoDB\Id + */ + protected $id; + + /** + * @MongoDB\Field(type="string") + */ + protected $password; + + public function getId() + { + return $this->id; + } + + public function getRoles(): array + { + return ['ROLE_USER']; + } + + public function getPassword(): ?string + { + return $this->password; + } + + public function setPassword($password): void + { + $this->password = $password; + } + + public function getSalt(): ?string + { + return ''; + } + + public function getUsername(): string + { + return $this->getId(); + } + + public function eraseCredentials(): void + { + } +} diff --git a/Tests/Functional/TestBundle/Entity/AccessToken.php b/Tests/Functional/TestBundle/Entity/AccessToken.php index 78ffb576..6b3d6a58 100644 --- a/Tests/Functional/TestBundle/Entity/AccessToken.php +++ b/Tests/Functional/TestBundle/Entity/AccessToken.php @@ -15,6 +15,8 @@ use Doctrine\ORM\Mapping as ORM; use FOS\OAuthServerBundle\Entity\AccessToken as BaseAccessToken; +use FOS\OAuthServerBundle\Model\ClientInterface; +use Symfony\Component\Security\Core\User\UserInterface; /** * @ORM\Entity @@ -23,6 +25,7 @@ class AccessToken extends BaseAccessToken { /** + * @var int * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") @@ -30,12 +33,14 @@ class AccessToken extends BaseAccessToken protected $id; /** + * @var ClientInterface * @ORM\ManyToOne(targetEntity="Client") * @ORM\JoinColumn(nullable=false) */ protected $client; /** + * @var UserInterface * @ORM\ManyToOne(targetEntity="User") */ protected $user; diff --git a/Tests/Functional/TestBundle/Entity/AuthCode.php b/Tests/Functional/TestBundle/Entity/AuthCode.php index 0d654696..59967437 100644 --- a/Tests/Functional/TestBundle/Entity/AuthCode.php +++ b/Tests/Functional/TestBundle/Entity/AuthCode.php @@ -15,6 +15,8 @@ use Doctrine\ORM\Mapping as ORM; use FOS\OAuthServerBundle\Entity\AuthCode as BaseAuthCode; +use FOS\OAuthServerBundle\Model\ClientInterface; +use Symfony\Component\Security\Core\User\UserInterface; /** * @ORM\Entity @@ -23,6 +25,7 @@ class AuthCode extends BaseAuthCode { /** + * @var int * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") @@ -30,12 +33,14 @@ class AuthCode extends BaseAuthCode protected $id; /** + * @var ClientInterface * @ORM\ManyToOne(targetEntity="Client") * @ORM\JoinColumn(nullable=false) */ protected $client; /** + * @var UserInterface * @ORM\ManyToOne(targetEntity="User") */ protected $user; diff --git a/Tests/Functional/TestBundle/Entity/Client.php b/Tests/Functional/TestBundle/Entity/Client.php index 0832f334..0d19c867 100644 --- a/Tests/Functional/TestBundle/Entity/Client.php +++ b/Tests/Functional/TestBundle/Entity/Client.php @@ -23,6 +23,7 @@ class Client extends BaseClient { /** + * @var int * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") diff --git a/Tests/Functional/TestBundle/Entity/RefreshToken.php b/Tests/Functional/TestBundle/Entity/RefreshToken.php index f8aadfa9..ba7820b7 100644 --- a/Tests/Functional/TestBundle/Entity/RefreshToken.php +++ b/Tests/Functional/TestBundle/Entity/RefreshToken.php @@ -15,6 +15,8 @@ use Doctrine\ORM\Mapping as ORM; use FOS\OAuthServerBundle\Entity\RefreshToken as BaseRefreshToken; +use FOS\OAuthServerBundle\Model\ClientInterface; +use Symfony\Component\Security\Core\User\UserInterface; /** * @ORM\Entity @@ -23,6 +25,7 @@ class RefreshToken extends BaseRefreshToken { /** + * @var int * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") @@ -30,12 +33,14 @@ class RefreshToken extends BaseRefreshToken protected $id; /** + * @var ClientInterface * @ORM\ManyToOne(targetEntity="Client") * @ORM\JoinColumn(nullable=false) */ protected $client; /** + * @var UserInterface * @ORM\ManyToOne(targetEntity="User") */ protected $user; diff --git a/Tests/Functional/TestBundle/Entity/User.php b/Tests/Functional/TestBundle/Entity/User.php index 61363bec..8486a8fd 100644 --- a/Tests/Functional/TestBundle/Entity/User.php +++ b/Tests/Functional/TestBundle/Entity/User.php @@ -38,31 +38,32 @@ public function getId() return $this->id; } - public function getRoles() + public function getRoles(): array { return ['ROLE_USER']; } - public function getPassword() + public function getPassword(): ?string { return $this->password; } - public function setPassword($password) + public function setPassword($password): void { $this->password = $password; } - public function getSalt() + public function getSalt(): ?string { + return ''; } - public function getUsername() + public function getUsername(): string { return $this->getId(); } - public function eraseCredentials() + public function eraseCredentials(): void { } } diff --git a/Tests/Functional/TestBundle/Manager/AccessTokenManager.php b/Tests/Functional/TestBundle/Manager/AccessTokenManager.php new file mode 100644 index 00000000..3cf46826 --- /dev/null +++ b/Tests/Functional/TestBundle/Manager/AccessTokenManager.php @@ -0,0 +1,76 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\OAuthServerBundle\Tests\Functional\TestBundle\Manager; + +use FOS\OAuthServerBundle\Model\AccessToken; +use FOS\OAuthServerBundle\Model\AccessTokenManagerInterface; +use FOS\OAuthServerBundle\Model\TokenInterface; +use FOS\OAuthServerBundle\Model\TokenManager; + +class AccessTokenManager extends TokenManager implements AccessTokenManagerInterface +{ + /** + * {@inheritdoc} + */ + public function findTokenBy(array $criteria): ?AccessToken + { + // create an instance as if found + $accessToken = new AccessToken(); + + return $accessToken; + } + + /** + * {@inheritdoc} + */ + public function findTokenByToken($token): ?AccessToken + { + // create an instance as if found + $accessToken = new AccessToken(); + $accessToken->setToken($token); + + return $accessToken; + } + + /** + * {@inheritdoc} + */ + public function getClass(): string + { + return self::class; + } + + /** + * {@inheritdoc} + */ + public function updateToken(TokenInterface $token): void + { + } + + /** + * {@inheritdoc} + */ + public function deleteToken(TokenInterface $token): void + { + } + + /** + * {@inheritdoc} + */ + public function deleteExpired(): int + { + // return a count as if entities deleted + return 1; + } +} diff --git a/Tests/Functional/TestBundle/Manager/AuthCodeManager.php b/Tests/Functional/TestBundle/Manager/AuthCodeManager.php new file mode 100644 index 00000000..76c49246 --- /dev/null +++ b/Tests/Functional/TestBundle/Manager/AuthCodeManager.php @@ -0,0 +1,75 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\OAuthServerBundle\Tests\Functional\TestBundle\Manager; + +use FOS\OAuthServerBundle\Model\AuthCode; +use FOS\OAuthServerBundle\Model\AuthCodeInterface; +use FOS\OAuthServerBundle\Model\AuthCodeManager as BaseAuthCodeManager; + +class AuthCodeManager extends BaseAuthCodeManager +{ + /** + * {@inheritdoc} + */ + public function findAuthCodeBy(array $criteria): AuthCode + { + // create an instance as if found + $authCode = new AuthCode(); + + return $authCode; + } + + /** + * {@inheritdoc} + */ + public function findAuthCodeByToken($token) + { + // create an instance as if found + $authCode = new AuthCode(); + $authCode->setToken($token); + + return $authCode; + } + + /** + * {@inheritdoc} + */ + public function getClass(): string + { + return self::class; + } + + /** + * {@inheritdoc} + */ + public function updateAuthCode(AuthCodeInterface $authCode): void + { + } + + /** + * {@inheritdoc} + */ + public function deleteAuthCode(AuthCodeInterface $authCode): void + { + } + + /** + * {@inheritdoc} + */ + public function deleteExpired(): int + { + // return a count as if entities deleted + return 1; + } +} diff --git a/Tests/Functional/TestBundle/Manager/ClientManager.php b/Tests/Functional/TestBundle/Manager/ClientManager.php new file mode 100644 index 00000000..e500a1db --- /dev/null +++ b/Tests/Functional/TestBundle/Manager/ClientManager.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\OAuthServerBundle\Tests\Functional\TestBundle\Manager; + +use FOS\OAuthServerBundle\Model\Client; +use FOS\OAuthServerBundle\Model\ClientInterface; +use FOS\OAuthServerBundle\Model\ClientManager as BaseClientManager; +use ReflectionClass; + +class ClientManager extends BaseClientManager +{ + /** + * {@inheritdoc} + */ + public function findClientBy(array $criteria): ?Client + { + // create an instance as if found + $client = new Client(); + + return $client; + } + + /** + * {@inheritdoc} + */ + public function findClientByPublicId($publicId): ?Client + { + if (false === $pos = mb_strpos($publicId, '_')) { + return null; + } + + $id = mb_substr($publicId, 0, $pos); + $randomId = mb_substr($publicId, $pos + 1); + + // create an instance as if found + $client = new Client(); + $client->setRandomId($randomId); + + $reflectionClass = new ReflectionClass($client); + $reflectionProperty = $reflectionClass->getProperty('id'); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($client, $id); + + return $client; + } + + /** + * {@inheritdoc} + */ + public function getClass(): string + { + return self::class; + } + + /** + * {@inheritdoc} + */ + public function updateClient(ClientInterface $client): void + { + } + + /** + * {@inheritdoc} + */ + public function deleteClient(ClientInterface $client): void + { + } +} diff --git a/Tests/Functional/TestBundle/Manager/RefreshTokenManager.php b/Tests/Functional/TestBundle/Manager/RefreshTokenManager.php new file mode 100644 index 00000000..f388bccb --- /dev/null +++ b/Tests/Functional/TestBundle/Manager/RefreshTokenManager.php @@ -0,0 +1,76 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\OAuthServerBundle\Tests\Functional\TestBundle\Manager; + +use FOS\OAuthServerBundle\Model\RefreshToken; +use FOS\OAuthServerBundle\Model\RefreshTokenManagerInterface; +use FOS\OAuthServerBundle\Model\TokenInterface; +use FOS\OAuthServerBundle\Model\TokenManager; + +class RefreshTokenManager extends TokenManager implements RefreshTokenManagerInterface +{ + /** + * {@inheritdoc} + */ + public function findTokenBy(array $criteria): ?RefreshToken + { + // create an instance as if found + $refreshToken = new RefreshToken(); + + return $refreshToken; + } + + /** + * {@inheritdoc} + */ + public function findTokenByToken($token): ?RefreshToken + { + // create an instance as if found + $refreshToken = new RefreshToken(); + $refreshToken->setToken($token); + + return $refreshToken; + } + + /** + * {@inheritdoc} + */ + public function getClass(): string + { + return self::class; + } + + /** + * {@inheritdoc} + */ + public function updateToken(TokenInterface $token): void + { + } + + /** + * {@inheritdoc} + */ + public function deleteToken(TokenInterface $token): void + { + } + + /** + * {@inheritdoc} + */ + public function deleteExpired(): int + { + // return a count as if entities deleted + return 1; + } +} diff --git a/Tests/Functional/TestCase.php b/Tests/Functional/TestCase.php index 4f816620..7d2c0f22 100644 --- a/Tests/Functional/TestCase.php +++ b/Tests/Functional/TestCase.php @@ -13,32 +13,75 @@ namespace FOS\OAuthServerBundle\Tests\Functional; +use LogicException; +use Symfony\Bundle\FrameworkBundle\KernelBrowser; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Component\Filesystem\Filesystem; -use Symfony\Component\HttpKernel\KernelInterface; abstract class TestCase extends WebTestCase { /** - * @var null|KernelInterface + * @var KernelBrowser */ - protected static $kernel; + protected $client; - protected function setUp() + protected function setUp(): void { $fs = new Filesystem(); $fs->remove(sys_get_temp_dir().'/FOSOAuthServerBundle/'); } - protected function tearDown() + /** + * Client response assertion of status code and response content. + */ + protected function assertResponse(int $statusCode, string $content, bool $fullFailOutput = false): void { - static::$kernel = null; - } + if (!($this->client instanceof KernelBrowser)) { + throw new LogicException('Test attempts to check response, but client does not exist; use createClient() to set the test case client property.'); + } - protected static function createKernel(array $options = []) - { - $env = @$options['env'] ?: 'test'; + $this->assertSame( + $statusCode, + $this->client->getResponse()->getStatusCode(), + sprintf('Failed asserting that response status code "%d" is "%d".', $this->client->getResponse()->getStatusCode(), $statusCode) + ); + + $responseContent = $this->client->getResponse()->getContent(); + + if ('' === $responseContent && '' === $content) { + $this->assertTrue(true); + + return; + } + + if ('' === $responseContent) { + $this->fail(sprintf('Response content is empty, expected "%s".', $content)); + } elseif ('' === $content) { + // this differs from assertStringContainsString, which does not + // fail on an empty string expectation + $this->fail($fullFailOutput || mb_strlen($responseContent) < 100 + ? sprintf('Failed asserting that response "%s" is empty.', $responseContent) + : sprintf( + 'Failed asserting that response "%s ... %s" is empty.', + mb_substr($responseContent, 0, 40), + mb_substr($responseContent, mb_strlen($responseContent) - 40) + ) + ); + } - return new AppKernel($env, true); + // not using assertStringContainsString to avoid full HTML doc in the + // fail message + if (mb_strpos($responseContent, $content) === false) { + $this->fail($fullFailOutput || mb_strlen($responseContent) < 100 + ? sprintf('Failed asserting that response "%s" contains "%s".', $responseContent, $content) + : sprintf( + 'Failed asserting that response "%s ... %s" contains "%s".', + mb_substr($responseContent, 0, 40), + mb_substr($responseContent, mb_strlen($responseContent) - 40), + $content + ) + ); + } + $this->assertTrue(true); } } diff --git a/Tests/Functional/config/config.yml b/Tests/Functional/config/config.yml index c46afdef..b89acc43 100644 --- a/Tests/Functional/config/config.yml +++ b/Tests/Functional/config/config.yml @@ -1,13 +1,19 @@ framework: - templating: - engines: ["twig"] form: ~ secret: test + test: true router: - resource: "%kernel.root_dir%/config/routing.yml" + resource: "%kernel.project_dir%/Tests/Functional/config/routing.yml" fos_oauth_server: +monolog: + handlers: + main: + type: stream + path: '%kernel.logs_dir%/%kernel.environment%.log' + level: debug + security: role_hierarchy: ROLE_ADMIN: ROLE_USER diff --git a/Tests/Functional/config/config_odm.yml b/Tests/Functional/config/config_odm.yml new file mode 100644 index 00000000..134bee30 --- /dev/null +++ b/Tests/Functional/config/config_odm.yml @@ -0,0 +1,38 @@ +imports: + - { resource: config.yml } + +doctrine_mongodb: + connections: + default: + server: mongodb://localhost:27017 + options: {} + document_managers: + default: + mappings: + TestBundle: + type: annotation + dir: '%kernel.project_dir%/Tests/Functional/TestBundle/Document' + prefix: FOS\OAuthServerBundle\Tests\Functional\TestBundle\Document\ + is_bundle: false + +fos_oauth_server: + db_driver: mongodb + service: + user_provider: security.user.provider.concrete.main + + client_class: FOS\OAuthServerBundle\Tests\Functional\TestBundle\Document\Client + access_token_class: FOS\OAuthServerBundle\Tests\Functional\TestBundle\Document\AccessToken + refresh_token_class: FOS\OAuthServerBundle\Tests\Functional\TestBundle\Document\RefreshToken + auth_code_class: FOS\OAuthServerBundle\Tests\Functional\TestBundle\Document\AuthCode + +security: + encoders: + FOS\OAuthServerBundle\Tests\Functional\TestBundle\Document\User: plaintext + + providers: + main: + mongodb: { class: FOS\OAuthServerBundle\Tests\Functional\TestBundle\Document\User, property: id } + +services: + doctrine.odm.mongodb.document_manager: + alias: 'doctrine_mongodb.odm.default_document_manager' diff --git a/Tests/Functional/config/config_test.yml b/Tests/Functional/config/config_test.yml new file mode 100644 index 00000000..cc6427b8 --- /dev/null +++ b/Tests/Functional/config/config_test.yml @@ -0,0 +1,25 @@ +imports: + - { resource: config.yml } + +fos_oauth_server: + db_driver: custom + service: + client_manager: FOS\OAuthServerBundle\Tests\Functional\TestBundle\Manager\ClientManager + access_token_manager: FOS\OAuthServerBundle\Tests\Functional\TestBundle\Manager\AccessTokenManager + refresh_token_manager: FOS\OAuthServerBundle\Tests\Functional\TestBundle\Manager\RefreshTokenManager + auth_code_manager: FOS\OAuthServerBundle\Tests\Functional\TestBundle\Manager\AuthCodeManager + user_provider: security.user.provider.concrete.main + + client_class: FOS\OAuthServerBundle\Tests\Functional\TestBundle\Entity\Client + access_token_class: FOS\OAuthServerBundle\Tests\Functional\TestBundle\Entity\AccessToken + refresh_token_class: FOS\OAuthServerBundle\Tests\Functional\TestBundle\Entity\RefreshToken + auth_code_class: FOS\OAuthServerBundle\Tests\Functional\TestBundle\Entity\AuthCode + +services: + # autowiring + _defaults: + autowire: true + autoconfigure: true + FOS\OAuthServerBundle\Tests\Functional\TestBundle\: + resource: '%kernel.project_dir%/Tests/Functional/TestBundle/*' + exclude: '%kernel.project_dir%/Tests/Functional/TestBundle/Entity' diff --git a/Tests/Functional/config/routing.yml b/Tests/Functional/config/routing.yml index e69de29b..8d64ac6c 100644 --- a/Tests/Functional/config/routing.yml +++ b/Tests/Functional/config/routing.yml @@ -0,0 +1,4 @@ +fos_oauth_server_token: + resource: '@FOSOAuthServerBundle/Resources/config/routing/token.xml' +fos_oauth_server_authorize: + resource: '@FOSOAuthServerBundle/Resources/config/routing/authorize.xml' diff --git a/Tests/Model/TokenTest.php b/Tests/Model/TokenTest.php index 053032c3..1be83114 100644 --- a/Tests/Model/TokenTest.php +++ b/Tests/Model/TokenTest.php @@ -30,15 +30,15 @@ class TokenTest extends TestCase * @param mixed $expiresAt * @param mixed $expect */ - public function testHasExpired($expiresAt, $expect) + public function testHasExpired($expiresAt, $expect): void { $token = new Token(); $token->setExpiresAt($expiresAt); - $this->assertSame($expect, $token->hasExpired()); + self::assertSame($expect, $token->hasExpired()); } - public static function getTestHasExpiredData() + public static function getTestHasExpiredData(): array { return [ [time() + 60, false], @@ -47,18 +47,18 @@ public static function getTestHasExpiredData() ]; } - public function testExpiresIn() + public function testExpiresIn(): void { $token = new Token(); - $this->assertSame(PHP_INT_MAX, $token->getExpiresIn()); + self::assertSame(PHP_INT_MAX, $token->getExpiresIn()); } - public function testExpiresInWithExpiresAt() + public function testExpiresInWithExpiresAt(): void { $token = new Token(); $token->setExpiresAt(time() + 60); - $this->assertSame(60, $token->getExpiresIn()); + self::assertSame(60, $token->getExpiresIn()); } } diff --git a/Tests/Propel/AuthCodeManagerTest.php b/Tests/Propel/AuthCodeManagerTest.php index 4d49a57e..a9cebcfa 100644 --- a/Tests/Propel/AuthCodeManagerTest.php +++ b/Tests/Propel/AuthCodeManagerTest.php @@ -24,11 +24,11 @@ */ class AuthCodeManagerTest extends PropelTestCase { - const AUTH_CODE_CLASS = 'FOS\OAuthServerBundle\Propel\AuthCode'; + public const AUTH_CODE_CLASS = AuthCode::class; protected $manager; - public function setUp() + public function setUp(): void { parent::setUp(); @@ -36,14 +36,14 @@ public function setUp() AuthCodeQuery::create()->deleteAll(); } - public function testConstruct() + public function testConstruct(): void { - $this->assertSame(self::AUTH_CODE_CLASS, $this->manager->getClass()); + self::assertSame(self::AUTH_CODE_CLASS, $this->manager->getClass()); } public function testCreateClass() { - $this->assertInstanceOf(self::AUTH_CODE_CLASS, $this->manager->createAuthCode()); + self::assertInstanceOf(self::AUTH_CODE_CLASS, $this->manager->createAuthCode()); } public function testUpdate() @@ -78,7 +78,7 @@ public function testFindAuthCodeReturnsNullIfNotFound() { $authCode = $this->manager->findAuthCodeBy(['token' => '12345']); - $this->assertNull($authCode); + self::assertNull($authCode); } public function testFindAuthCode() @@ -86,8 +86,8 @@ public function testFindAuthCode() $authCode = $this->createAuthCode('12345'); $return = $this->manager->findAuthCodeBy(['token' => '12345']); - $this->assertNotNull($return); - $this->assertSame($authCode, $return); + self::assertNotNull($return); + self::assertSame($authCode, $return); } public function testFindAuthCodeByToken() @@ -95,27 +95,27 @@ public function testFindAuthCodeByToken() $authCode = $this->createAuthCode('12345'); $return = $this->manager->findAuthCodeByToken('12345'); - $this->assertNotNull($return); - $this->assertSame($authCode, $return); + self::assertNotNull($return); + self::assertSame($authCode, $return); } public function testFindAuthCodeByTokenReturnsNullIfNotFound() { $return = $this->manager->findAuthCodeByToken('12345'); - $this->assertNull($return); + self::assertNull($return); } public function testFindAuthCodeWithInvalidData() { $token = $this->manager->findAuthCodeBy(['foo' => '12345']); - $this->assertNull($token); + self::assertNull($token); $token = $this->manager->findAuthCodeBy([]); - $this->assertNull($token); + self::assertNull($token); $token = $this->manager->findAuthCodeBy(['token']); - $this->assertNull($token); + self::assertNull($token); } public function testDeleteExpired() @@ -123,12 +123,12 @@ public function testDeleteExpired() $a1 = $this->createAuthCode('12345', time() + 100); $a2 = $this->createAuthCode('67890', time() - 100); - $this->assertSame(2, AuthCodeQuery::create()->count()); + self::assertSame(2, AuthCodeQuery::create()->count()); $nb = $this->manager->deleteExpired(); - $this->assertSame(1, $nb); - $this->assertTrue($a1->equals(AuthCodeQuery::create()->findOne())); + self::assertSame(1, $nb); + self::assertTrue($a1->equals(AuthCodeQuery::create()->findOne())); } protected function createAuthCode($token, $expiresAt = false) diff --git a/Tests/Propel/AuthCodeTest.php b/Tests/Propel/AuthCodeTest.php index e8993bc4..6b68952d 100644 --- a/Tests/Propel/AuthCodeTest.php +++ b/Tests/Propel/AuthCodeTest.php @@ -33,7 +33,7 @@ public function testHasExpired($expiresAt, $expect) $token = new AuthCode(); $token->setExpiresAt($expiresAt); - $this->assertSame($expect, $token->hasExpired()); + self::assertSame($expect, $token->hasExpired()); } public static function getTestHasExpiredData() @@ -49,7 +49,7 @@ public function testExpiresIn() { $token = new AuthCode(); - $this->assertSame(PHP_INT_MAX, $token->getExpiresIn()); + self::assertSame(PHP_INT_MAX, $token->getExpiresIn()); } public function testExpiresInWithExpiresAt() @@ -57,6 +57,6 @@ public function testExpiresInWithExpiresAt() $token = new AuthCode(); $token->setExpiresAt(time() + 60); - $this->assertSame(60, $token->getExpiresIn()); + self::assertSame(60, $token->getExpiresIn()); } } diff --git a/Tests/Propel/ClientManagerTest.php b/Tests/Propel/ClientManagerTest.php index 16bea8c6..703c0e8d 100644 --- a/Tests/Propel/ClientManagerTest.php +++ b/Tests/Propel/ClientManagerTest.php @@ -19,11 +19,11 @@ class ClientManagerTest extends PropelTestCase { - const CLIENT_CLASS = 'FOS\OAuthServerBundle\Propel\Client'; + const CLIENT_CLASS = Client::class; protected $manager; - public function setUp() + public function setUp(): void { parent::setUp(); @@ -33,17 +33,17 @@ public function setUp() public function testConstruct() { - $this->assertSame(self::CLIENT_CLASS, $this->manager->getClass()); + self::assertSame(self::CLIENT_CLASS, $this->manager->getClass()); } public function testCreateClass() { - $this->assertInstanceOf(self::CLIENT_CLASS, $this->manager->createClient()); + self::assertInstanceOf(self::CLIENT_CLASS, $this->manager->createClient()); } public function testUpdate() { - $client = $this->getMockBuilder('FOS\OAuthServerBundle\Propel\Client') + $client = $this->getMockBuilder(Client::class) ->disableOriginalConstructor() ->getMock() ; @@ -57,7 +57,8 @@ public function testUpdate() public function testDelete() { - $client = $this->getMockBuilder('FOS\OAuthServerBundle\Propel\Client') + /** @var Client $client */ + $client = $this->getMockBuilder(Client::class) ->disableOriginalConstructor() ->getMock() ; @@ -73,19 +74,19 @@ public function testFindClientReturnsNullIfNotFound() { $client = $this->manager->findClientBy(['id' => '1', 'randomId' => '2345']); - $this->assertNull($client); + self::assertNull($client); } public function testFindClientWithInvalidCriteria() { $client = $this->manager->findClientBy(['randomId' => '2345']); - $this->assertNull($client); + self::assertNull($client); $client = $this->manager->findClientBy(['id' => '2345']); - $this->assertNull($client); + self::assertNull($client); $client = $this->manager->findClientBy(['foo' => '2345']); - $this->assertNull($client); + self::assertNull($client); } public function testFindClient() @@ -93,8 +94,8 @@ public function testFindClient() $client = $this->createClient('2345'); $return = $this->manager->findClientBy(['id' => '1', 'randomId' => '2345']); - $this->assertNotNull($return); - $this->assertSame($client, $return); + self::assertNotNull($return); + self::assertSame($client, $return); } public function testFindClientByPublicId() @@ -102,28 +103,28 @@ public function testFindClientByPublicId() $client = $this->createClient('12345'); $return = $this->manager->findClientByPublicId('1_12345'); - $this->assertNotNull($return); - $this->assertSame($client, $return); + self::assertNotNull($return); + self::assertSame($client, $return); } public function testFindClientByPublicIdReturnsNullIfNotFound() { $return = $this->manager->findClientByPublicId('1_12345'); - $this->assertNull($return); + self::assertNull($return); } public function testFindClientByPublicIdReturnsNullIfInvalidPublicId() { $return = $this->manager->findClientByPublicId('1'); - $this->assertNull($return); + self::assertNull($return); $return = $this->manager->findClientByPublicId(''); - $this->assertNull($return); + self::assertNull($return); // invalid type // $return = $this->manager->findClientByPublicId(null); - // $this->assertNull($return); + // self::assertNull($return); } protected function createClient($randomId) diff --git a/Tests/Propel/ClientTest.php b/Tests/Propel/ClientTest.php index f10cb282..cbcadb85 100644 --- a/Tests/Propel/ClientTest.php +++ b/Tests/Propel/ClientTest.php @@ -22,28 +22,28 @@ public function testConstructor() { $client = new Client(); - $this->assertNotNull($client->getRandomId()); - $this->assertNotNull($client->getSecret()); + self::assertNotNull($client->getRandomId()); + self::assertNotNull($client->getSecret()); $types = $client->getAllowedGrantTypes(); - $this->assertCount(1, $types); - $this->assertSame(OAuth2::GRANT_TYPE_AUTH_CODE, $types[0]); + self::assertCount(1, $types); + self::assertSame(OAuth2::GRANT_TYPE_AUTH_CODE, $types[0]); } - public function testCheckSecretWithInvalidArgument() + public function testCheckSecretWithInvalidArgument(): void { $client = new Client(); - $this->assertFalse($client->checkSecret('foo')); - $this->assertFalse($client->checkSecret('')); - $this->assertFalse($client->checkSecret(null)); + self::assertFalse($client->checkSecret('foo')); + self::assertFalse($client->checkSecret('')); + self::assertFalse($client->checkSecret(null)); } - public function testCheckSecret() + public function testCheckSecret(): void { $client = new Client(); $client->setSecret('foo'); - $this->assertTrue($client->checkSecret('foo')); + self::assertTrue($client->checkSecret('foo')); } } diff --git a/Tests/Propel/PropelTestCase.php b/Tests/Propel/PropelTestCase.php index c0b65fba..5e810730 100644 --- a/Tests/Propel/PropelTestCase.php +++ b/Tests/Propel/PropelTestCase.php @@ -14,12 +14,13 @@ namespace FOS\OAuthServerBundle\Tests\Propel; use FOS\OAuthServerBundle\Tests\TestCase; +use Propel; class PropelTestCase extends TestCase { - public function setUp() + public function setUp(): void { - if (!class_exists('\Propel')) { + if (!class_exists(Propel::class)) { $this->markTestSkipped('Propel is not installed.'); } } diff --git a/Tests/Propel/TokenManagerTest.php b/Tests/Propel/TokenManagerTest.php index 6de63827..8e7439fa 100644 --- a/Tests/Propel/TokenManagerTest.php +++ b/Tests/Propel/TokenManagerTest.php @@ -24,11 +24,11 @@ */ class TokenManagerTest extends PropelTestCase { - const TOKEN_CLASS = 'FOS\OAuthServerBundle\Propel\RefreshToken'; + const TOKEN_CLASS = Token::class; protected $manager; - public function setUp() + public function setUp(): void { parent::setUp(); @@ -38,18 +38,18 @@ public function setUp() public function testConstruct() { - $this->assertSame(self::TOKEN_CLASS, $this->manager->getClass()); + self::assertSame(self::TOKEN_CLASS, $this->manager->getClass()); } public function testCreateClass() { $this->manager = new TokenManager('Token'); - $this->assertInstanceOf('Token', $this->manager->createToken()); + self::assertInstanceOf('Token', $this->manager->createToken()); } public function testUpdate() { - $token = $this->getMockBuilder('FOS\OAuthServerBundle\Propel\Token') + $token = $this->getMockBuilder(\FOS\OAuthServerBundle\Propel\Token::class) ->disableOriginalConstructor() ->getMock() ; @@ -79,19 +79,19 @@ public function testFindTokenReturnsNullIfNotFound() { $token = $this->manager->findTokenBy(['token' => '12345']); - $this->assertNull($token); + self::assertNull($token); } public function testFindTokenWithInvalidData() { $token = $this->manager->findTokenBy(['foo' => '12345']); - $this->assertNull($token); + self::assertNull($token); $token = $this->manager->findTokenBy([]); - $this->assertNull($token); + self::assertNull($token); $token = $this->manager->findTokenBy(['token']); - $this->assertNull($token); + self::assertNull($token); } public function testFindToken() @@ -99,8 +99,8 @@ public function testFindToken() $token = $this->createToken('12345'); $return = $this->manager->findTokenBy(['token' => '12345']); - $this->assertNotNull($return); - $this->assertSame($token, $return); + self::assertNotNull($return); + self::assertSame($token, $return); } public function testFindTokenByToken() @@ -108,15 +108,15 @@ public function testFindTokenByToken() $token = $this->createToken('12345'); $return = $this->manager->findTokenByToken('12345'); - $this->assertNotNull($return); - $this->assertSame($token, $return); + self::assertNotNull($return); + self::assertSame($token, $return); } public function testFindTokenByTokenReturnsNullIfNotFound() { $return = $this->manager->findTokenByToken('12345'); - $this->assertNull($return); + self::assertNull($return); } public function testDeleteExpired() @@ -124,12 +124,12 @@ public function testDeleteExpired() $a1 = $this->createToken('12345', time() + 100); $a2 = $this->createToken('67890', time() - 100); - $this->assertSame(2, TokenQuery::create()->count()); + self::assertSame(2, TokenQuery::create()->count()); $nb = $this->manager->deleteExpired(); - $this->assertSame(1, $nb); - $this->assertTrue($a1->equals(TokenQuery::create()->findOne())); + self::assertSame(1, $nb); + self::assertTrue($a1->equals(TokenQuery::create()->findOne())); } protected function createToken($tokenString, $expiresAt = false) diff --git a/Tests/Propel/TokenTest.php b/Tests/Propel/TokenTest.php index 6ad9e931..5effb30f 100644 --- a/Tests/Propel/TokenTest.php +++ b/Tests/Propel/TokenTest.php @@ -28,15 +28,15 @@ class TokenTest extends PropelTestCase * @param mixed $expiresAt * @param mixed $expect */ - public function testHasExpired($expiresAt, $expect) + public function testHasExpired($expiresAt, $expect): void { $token = new Token(); $token->setExpiresAt($expiresAt); - $this->assertSame($expect, $token->hasExpired()); + self::assertSame($expect, $token->hasExpired()); } - public static function getTestHasExpiredData() + public static function getTestHasExpiredData(): array { return [ [time() + 60, false], @@ -45,19 +45,19 @@ public static function getTestHasExpiredData() ]; } - public function testExpiresIn() + public function testExpiresIn(): void { $token = new Token(); - $this->assertSame(PHP_INT_MAX, $token->getExpiresIn()); + self::assertSame(PHP_INT_MAX, $token->getExpiresIn()); } - public function testExpiresInWithExpiresAt() + public function testExpiresInWithExpiresAt(): void { $token = new Token(); $token->setExpiresAt(time() + 60); - $this->assertSame(60, $token->getExpiresIn()); + self::assertSame(60, $token->getExpiresIn()); } } diff --git a/Tests/Security/Authentication/Provider/OAuthProviderTest.php b/Tests/Security/Authentication/Provider/OAuthProviderTest.php index 4c0aa41e..8bacf79a 100644 --- a/Tests/Security/Authentication/Provider/OAuthProviderTest.php +++ b/Tests/Security/Authentication/Provider/OAuthProviderTest.php @@ -17,20 +17,21 @@ use FOS\OAuthServerBundle\Security\Authentication\Provider\OAuthProvider; use FOS\OAuthServerBundle\Security\Authentication\Token\OAuthToken; use OAuth2\OAuth2; -use Symfony\Component\Security\Core\Role\Role; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; use Symfony\Component\Security\Core\User\UserCheckerInterface; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserProviderInterface; -class OAuthProviderTest extends \PHPUnit\Framework\TestCase +class OAuthProviderTest extends TestCase { /** - * @var \PHPUnit_Framework_MockObject_MockObject|UserInterface + * @var MockObject|UserInterface */ protected $user; /** - * @var \PHPUnit_Framework_MockObject_MockObject|UserProviderInterface + * @var MockObject|UserProviderInterface */ protected $userProvider; @@ -40,7 +41,7 @@ class OAuthProviderTest extends \PHPUnit\Framework\TestCase protected $provider; /** - * @var \PHPUnit_Framework_MockObject_MockObject|OAuth2 + * @var MockObject|OAuth2 */ protected $serverService; @@ -49,7 +50,7 @@ class OAuthProviderTest extends \PHPUnit\Framework\TestCase */ protected $userChecker; - public function setUp() + public function setUp(): void { $this->user = $this->getMockBuilder(UserInterface::class) ->disableOriginalConstructor() @@ -71,14 +72,14 @@ public function setUp() $this->provider = new OAuthProvider($this->userProvider, $this->serverService, $this->userChecker); } - public function testAuthenticateReturnsTokenIfValid() + public function testAuthenticateReturnsTokenIfValid(): void { $token = new OAuthToken(); $token->setToken('x'); $this->user->expects($this->once()) ->method('getRoles') - ->will($this->returnValue(['ROLE_USER'])) + ->willReturn(['ROLE_USER']) ; $accessToken = new AccessToken(); @@ -87,21 +88,21 @@ public function testAuthenticateReturnsTokenIfValid() $this->serverService->expects($this->once()) ->method('verifyAccessToken') ->with('x') - ->will($this->returnValue($accessToken)) + ->willReturn($accessToken) ; $result = $this->provider->authenticate($token); - $this->assertSame($this->user, $result->getUser()); - $this->assertSame($token->getToken(), $result->getToken()); - $this->assertTrue($result->isAuthenticated()); - $this->assertCount(1, $result->getRoles()); + self::assertSame($this->user, $result->getUser()); + self::assertSame($token->getToken(), $result->getToken()); + self::assertTrue($result->isAuthenticated()); + self::assertCount(1, $result->getRoleNames()); - $roles = $result->getRoles(); - $this->assertSame('ROLE_USER', $roles[0]->getRole()); + $roles = $result->getRoleNames(); + self::assertSame('ROLE_USER', $roles[0]); } - public function testAuthenticateReturnsTokenIfValidEvenIfNullData() + public function testAuthenticateReturnsTokenIfValidEvenIfNullData(): void { $token = new OAuthToken(); $token->setToken('x'); @@ -111,17 +112,17 @@ public function testAuthenticateReturnsTokenIfValidEvenIfNullData() $this->serverService->expects($this->once()) ->method('verifyAccessToken') ->with('x') - ->will($this->returnValue($accessToken)) + ->willReturn($accessToken) ; $result = $this->provider->authenticate($token); - $this->assertNull($result->getUser()); - $this->assertTrue($result->isAuthenticated()); - $this->assertCount(0, $result->getRoles()); + self::assertNull($result->getUser()); + self::assertTrue($result->isAuthenticated()); + self::assertCount(0, $result->getRoleNames()); } - public function testAuthenticateTransformsScopesAsRoles() + public function testAuthenticateTransformsScopesAsRoles(): void { $token = new OAuthToken(); $token->setToken('x'); @@ -132,23 +133,23 @@ public function testAuthenticateTransformsScopesAsRoles() $this->serverService->expects($this->once()) ->method('verifyAccessToken') ->with('x') - ->will($this->returnValue($accessToken)) + ->willReturn($accessToken) ; $result = $this->provider->authenticate($token); - $this->assertNull($result->getUser()); - $this->assertTrue($result->isAuthenticated()); + self::assertNull($result->getUser()); + self::assertTrue($result->isAuthenticated()); - $roles = $result->getRoles(); - $this->assertCount(2, $roles); - $this->assertInstanceOf(Role::class, $roles[0]); - $this->assertSame('ROLE_FOO', $roles[0]->getRole()); - $this->assertInstanceOf(Role::class, $roles[1]); - $this->assertSame('ROLE_BAR', $roles[1]->getRole()); + $roles = $result->getRoleNames(); + self::assertCount(2, $roles); + //self::assertInstanceOf(\Symfony\Component\Security\Core\Role::class, $roles[0]); + self::assertSame('ROLE_FOO', $roles[0]); + //self::assertInstanceOf(Role::class, $roles[1]); + self::assertSame('ROLE_BAR', $roles[1]); } - public function testAuthenticateWithNullScope() + public function testAuthenticateWithNullScope(): void { $this->markTestIncomplete('Scope is not nullable'); @@ -161,19 +162,19 @@ public function testAuthenticateWithNullScope() $this->serverService->expects($this->once()) ->method('verifyAccessToken') ->with('x') - ->will($this->returnValue($accessToken)) + ->willReturn($accessToken) ; $result = $this->provider->authenticate($token); - $this->assertNull($result->getUser()); - $this->assertTrue($result->isAuthenticated()); + self::assertNull($result->getUser()); + self::assertTrue($result->isAuthenticated()); - $roles = $result->getRoles(); - $this->assertCount(0, $roles); + $roles = $result->getRoleNames(); + self::assertCount(0, $roles); } - public function testAuthenticateWithEmptyScope() + public function testAuthenticateWithEmptyScope(): void { $token = new OAuthToken(); $token->setToken('x'); @@ -184,15 +185,15 @@ public function testAuthenticateWithEmptyScope() $this->serverService->expects($this->once()) ->method('verifyAccessToken') ->with('x') - ->will($this->returnValue($accessToken)) + ->willReturn($accessToken) ; $result = $this->provider->authenticate($token); - $this->assertNull($result->getUser()); - $this->assertTrue($result->isAuthenticated()); + self::assertNull($result->getUser()); + self::assertTrue($result->isAuthenticated()); - $roles = $result->getRoles(); - $this->assertCount(0, $roles); + $roles = $result->getRoleNames(); + self::assertCount(0, $roles); } } diff --git a/Tests/Security/Authentification/Token/OAuthTokenTest.php b/Tests/Security/Authentification/Token/OAuthTokenTest.php index 31f41bdb..cb2392f1 100644 --- a/Tests/Security/Authentification/Token/OAuthTokenTest.php +++ b/Tests/Security/Authentification/Token/OAuthTokenTest.php @@ -15,53 +15,54 @@ use FOS\OAuthServerBundle\Model\TokenInterface; use FOS\OAuthServerBundle\Security\Authentication\Token\OAuthToken; +use PHPUnit\Framework\TestCase; -class OAuthTokenTest extends \PHPUnit\Framework\TestCase +class OAuthTokenTest extends TestCase { /** * @var OAuthToken */ protected $instance; - public function setUp() + public function setUp(): void { $this->instance = new OAuthToken(); parent::setUp(); } - public function testSetTokenWillSetToken() + public function testSetTokenWillSetToken(): void { $token = $this->getMockBuilder(TokenInterface::class) ->disableOriginalConstructor() ->getMock() ; - $this->assertNull($this->instance->setToken($token)); - $this->assertAttributeSame($token, 'token', $this->instance); + self::assertNull($this->instance->setToken($token)); + self::assertSame($token, $this->instance->getToken()); } - public function testGetTokenWillReturnToken() + public function testGetTokenWillReturnToken(): void { $token = $this->getMockBuilder(TokenInterface::class) ->disableOriginalConstructor() ->getMock() ; - $this->assertNull($this->instance->getToken()); - $this->assertNull($this->instance->setToken($token)); - $this->assertSame($token, $this->instance->getToken()); + self::assertNull($this->instance->getToken()); + self::assertNull($this->instance->setToken($token)); + self::assertSame($token, $this->instance->getToken()); } - public function testGetCredentialsWillReturnToken() + public function testGetCredentialsWillReturnToken(): void { $token = $this->getMockBuilder(TokenInterface::class) ->disableOriginalConstructor() ->getMock() ; - $this->assertNull($this->instance->getCredentials()); - $this->assertNull($this->instance->setToken($token)); - $this->assertSame($token, $this->instance->getCredentials()); + self::assertNull($this->instance->getCredentials()); + self::assertNull($this->instance->setToken($token)); + self::assertSame($token, $this->instance->getCredentials()); } } diff --git a/Tests/Security/Firewall/OAuthListenerTest.php b/Tests/Security/Firewall/OAuthListenerTest.php index ee46b558..e57db957 100644 --- a/Tests/Security/Firewall/OAuthListenerTest.php +++ b/Tests/Security/Firewall/OAuthListenerTest.php @@ -17,21 +17,27 @@ use FOS\OAuthServerBundle\Security\Firewall\OAuthListener; use FOS\OAuthServerBundle\Tests\TestCase; use OAuth2\OAuth2; +use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; +use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; class OAuthListenerTest extends TestCase { + /** @var MockObject | OAuth2 */ protected $serverService; + /** @var MockObject | AuthenticationManagerInterface */ protected $authManager; - protected $securityContext; + /** @var MockObject | TokenStorageInterface */ + protected $tokenStorage; + /** @var MockObject | RequestEvent */ protected $event; - public function setUp() + public function setUp(): void { $this->serverService = $this->getMockBuilder(OAuth2::class) ->disableOriginalConstructor() @@ -44,63 +50,58 @@ public function setUp() ->getMock() ; - if (interface_exists('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')) { - $this->securityContext = $this - ->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface') - ->disableOriginalConstructor() - ->getMock() - ; - } else { - $this->securityContext = $this->getMockBuilder('Symfony\Component\Security\Core\SecurityContextInterface') - ->disableOriginalConstructor() - ->getMock() - ; - } + $this->tokenStorage = $this + ->getMockBuilder(TokenStorageInterface::class) + ->disableOriginalConstructor() + ->getMock() + ; $this->event = $this - ->getMockBuilder(GetResponseEvent::class) + ->getMockBuilder(RequestEvent::class) ->disableOriginalConstructor() ->getMock() ; } - public function testHandle() + public function testHandle(): void { - $listener = new OAuthListener($this->securityContext, $this->authManager, $this->serverService); + $listener = new OAuthListener($this->tokenStorage, $this->authManager, $this->serverService); $this->serverService ->expects($this->once()) ->method('getBearerToken') - ->will($this->returnValue('a-token')) + ->willReturn('a-token') ; $this->authManager ->expects($this->once()) ->method('authenticate') + ->with($this->isInstanceOf(OAuthToken::class)) ->will($this->returnArgument(0)) ; - $this->securityContext + $this->tokenStorage ->expects($this->once()) ->method('setToken') - ->will($this->returnArgument(0)) + ->with($this->callback(function ($value) { + return $value instanceof OAuthToken + && $value->getToken() === 'a-token' + ; + })) ; - /** @var OAuthToken $token */ - $token = $listener->handle($this->event); - - $this->assertInstanceOf(OAuthToken::class, $token); - $this->assertSame('a-token', $token->getToken()); + // no return, trigger the expectations + $listener->handle($this->event); } - public function testHandleResponse() + public function testHandleResponse(): void { - $listener = new OAuthListener($this->securityContext, $this->authManager, $this->serverService); + $listener = new OAuthListener($this->tokenStorage, $this->authManager, $this->serverService); $this->serverService ->expects($this->once()) ->method('getBearerToken') - ->will($this->returnValue('a-token')) + ->willReturn('a-token') ; $response = $this->getMockBuilder(Response::class) @@ -111,10 +112,11 @@ public function testHandleResponse() $this->authManager ->expects($this->once()) ->method('authenticate') - ->will($this->returnValue($response)) + ->with($this->isInstanceOf(OAuthToken::class)) + ->willReturn($response) ; - $this->securityContext + $this->tokenStorage ->expects($this->never()) ->method('setToken') ; @@ -122,11 +124,36 @@ public function testHandleResponse() $this->event ->expects($this->once()) ->method('setResponse') - ->will($this->returnArgument(0)) + ->with($this->equalTo($response)) + ; + + // no return, trigger the expectations + $listener->handle($this->event); + } + + public function testHandleAnonymousAuthentication(): void + { + $listener = new OAuthListener($this->tokenStorage, $this->authManager, $this->serverService); + + $this->serverService + ->expects($this->once()) + ->method('getBearerToken') + ->willReturn(null) ; - $ret = $listener->handle($this->event); + $this->tokenStorage + ->expects($this->never()) + ->method('setToken') + ; + + $this->event + ->expects($this->never()) + ->method('setResponse') + ; + + // no return, trigger the expectations + $listener->handle($this->event); - $this->assertSame($response, $ret); + $this->assertNull($this->tokenStorage->getToken()); } } diff --git a/Tests/Storage/OAuthStorageTest.php b/Tests/Storage/OAuthStorageTest.php index f628327b..2cf06d51 100644 --- a/Tests/Storage/OAuthStorageTest.php +++ b/Tests/Storage/OAuthStorageTest.php @@ -16,34 +16,49 @@ use FOS\OAuthServerBundle\Model\AccessToken; use FOS\OAuthServerBundle\Model\AccessTokenManagerInterface; use FOS\OAuthServerBundle\Model\AuthCode; +use FOS\OAuthServerBundle\Model\AuthCodeInterface; use FOS\OAuthServerBundle\Model\AuthCodeManagerInterface; use FOS\OAuthServerBundle\Model\Client; use FOS\OAuthServerBundle\Model\ClientManagerInterface; use FOS\OAuthServerBundle\Model\RefreshToken; use FOS\OAuthServerBundle\Model\RefreshTokenManagerInterface; +use FOS\OAuthServerBundle\Storage\GrantExtensionInterface; use FOS\OAuthServerBundle\Storage\OAuthStorage; +use OAuth2\Model\IOAuth2Client; +use OAuth2\OAuth2ServerException; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; +use ReflectionClass; use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface; +use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface; use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserProviderInterface; -class OAuthStorageTest extends \PHPUnit\Framework\TestCase +class OAuthStorageTest extends TestCase { + /** @var ClientManagerInterface | MockObject */ protected $clientManager; + /** @var AccessTokenManagerInterface | MockObject */ protected $accessTokenManager; + /** @var RefreshTokenManagerInterface | MockObject */ protected $refreshTokenManager; + /** @var AuthCodeManagerInterface | MockObject */ protected $authCodeManager; + /** @var UserProviderInterface | MockObject */ protected $userProvider; + /** @var EncoderFactoryInterface | MockObject */ protected $encoderFactory; + /** @var OAuthStorage */ protected $storage; - public function setUp() + public function setUp(): void { $this->clientManager = $this->getMockBuilder(ClientManagerInterface::class) ->disableOriginalConstructor() @@ -70,38 +85,44 @@ public function setUp() ->getMock() ; - $this->storage = new OAuthStorage($this->clientManager, $this->accessTokenManager, $this->refreshTokenManager, $this->authCodeManager, $this->userProvider, $this->encoderFactory); + $this->storage = new OAuthStorage( + $this->clientManager, + $this->accessTokenManager, + $this->refreshTokenManager, + $this->authCodeManager, + $this->userProvider, + $this->encoderFactory + ); } - public function testGetClientReturnsClientWithGivenId() + public function testGetClientReturnsClientWithGivenId(): void { $client = new Client(); $this->clientManager->expects($this->once()) ->method('findClientByPublicId') ->with('123_abc') - ->will($this->returnValue($client)) + ->willReturn($client) ; - $this->assertSame($client, $this->storage->getClient('123_abc')); + self::assertSame($client, $this->storage->getClient('123_abc')); } - public function testGetClientReturnsNullIfNotExists() + public function testGetClientReturnsNullIfNotExists(): void { - $client = new Client(); - $this->clientManager->expects($this->once()) ->method('findClientByPublicId') ->with('123_abc') - ->will($this->returnValue(null)) + ->willReturn(null) ; - $this->assertNull($this->storage->getClient('123_abc')); + self::assertNull($this->storage->getClient('123_abc')); } - public function testCheckClientCredentialsThrowsIfInvalidClientClass() + public function testCheckClientCredentialsThrowsIfInvalidClientClass(): void { - $client = $this->getMockBuilder('OAuth2\Model\IOAuth2Client') + /** @var IOAuth2Client $client */ + $client = $this->getMockBuilder(IOAuth2Client::class) ->disableOriginalConstructor() ->getMock() ; @@ -110,51 +131,50 @@ public function testCheckClientCredentialsThrowsIfInvalidClientClass() $this->storage->checkClientCredentials($client, 'dummy'); } - public function testCheckClientCredentialsReturnsTrueOnValidCredentials() + public function testCheckClientCredentialsReturnsTrueOnValidCredentials(): void { $client = new Client(); $client->setSecret('dummy'); - $this->assertTrue($this->storage->checkClientCredentials($client, 'dummy')); + self::assertTrue($this->storage->checkClientCredentials($client, 'dummy')); } - public function testCheckClientCredentialsReturnsFalseOnValidCredentials() + public function testCheckClientCredentialsReturnsFalseOnValidCredentials(): void { $client = new Client(); $client->setSecret('dummy'); - $this->assertFalse($this->storage->checkClientCredentials($client, 'passe')); + self::assertFalse($this->storage->checkClientCredentials($client, 'passe')); } - public function testGetAccessTokenReturnsAccessTokenWithGivenId() + public function testGetAccessTokenReturnsAccessTokenWithGivenId(): void { $token = new AccessToken(); $this->accessTokenManager->expects($this->once()) ->method('findTokenByToken') ->with('123_abc') - ->will($this->returnValue($token)) + ->willReturn($token) ; - $this->assertSame($token, $this->storage->getAccessToken('123_abc')); + self::assertSame($token, $this->storage->getAccessToken('123_abc')); } - public function testGetAccessTokenReturnsNullIfNotExists() + public function testGetAccessTokenReturnsNullIfNotExists(): void { - $token = new AccessToken(); - $this->accessTokenManager->expects($this->once()) ->method('findTokenByToken') ->with('123_abc') - ->will($this->returnValue(null)) + ->willReturn(null) ; - $this->assertNull($this->storage->getAccessToken('123_abc')); + self::assertNull($this->storage->getAccessToken('123_abc')); } - public function testCreateAccessTokenThrowsOnInvalidClientClass() + public function testCreateAccessTokenThrowsOnInvalidClientClass(): void { - $client = $this->getMockBuilder('OAuth2\Model\IOAuth2Client') + /** @var IOAuth2Client $client */ + $client = $this->getMockBuilder(IOAuth2Client::class) ->disableOriginalConstructor() ->getMock() ; @@ -163,20 +183,20 @@ public function testCreateAccessTokenThrowsOnInvalidClientClass() $this->storage->createAccessToken('foo', $client, new User(42), 1, 'foo bar'); } - public function testCreateAccessToken() + public function testCreateAccessToken(): void { $savedToken = null; $this->accessTokenManager->expects($this->once()) ->method('createToken') ->with() - ->will($this->returnValue(new AccessToken())) + ->willReturn(new AccessToken()) ; $this->accessTokenManager->expects($this->once()) ->method('updateToken') - ->will($this->returnCallback(function ($token) use (&$savedToken) { + ->willReturnCallback(function ($token) use (&$savedToken) { $savedToken = $token; - })) + }) ; $client = new Client(); @@ -184,30 +204,30 @@ public function testCreateAccessToken() $token = $this->storage->createAccessToken('foo', $client, $user, 1, 'foo bar'); - $this->assertSame($token, $savedToken); + self::assertSame($token, $savedToken); - $this->assertSame('foo', $token->getToken()); - $this->assertSame($client, $token->getClient()); - $this->assertSame($user, $token->getData()); - $this->assertSame($user, $token->getUser()); - $this->assertSame(1, $token->getExpiresAt()); - $this->assertSame('foo bar', $token->getScope()); + self::assertSame('foo', $token->getToken()); + self::assertSame($client, $token->getClient()); + self::assertSame($user, $token->getData()); + self::assertSame($user, $token->getUser()); + self::assertSame(1, $token->getExpiresAt()); + self::assertSame('foo bar', $token->getScope()); } - public function testCreateAccessTokenWithoutUser() + public function testCreateAccessTokenWithoutUser(): void { $savedToken = null; $this->accessTokenManager->expects($this->once()) ->method('createToken') ->with() - ->will($this->returnValue(new AccessToken())) + ->willReturn(new AccessToken()) ; $this->accessTokenManager->expects($this->once()) ->method('updateToken') - ->will($this->returnCallback(function ($token) use (&$savedToken) { + ->willReturnCallback(function ($token) use (&$savedToken) { $savedToken = $token; - })) + }) ; $client = new Client(); @@ -215,36 +235,36 @@ public function testCreateAccessTokenWithoutUser() $token = $this->storage->createAccessToken('foo', $client, $user, 1, 'foo bar'); - $this->assertSame($token, $savedToken); + self::assertSame($token, $savedToken); } - public function testGetRefreshTokenReturnsRefreshTokenWithGivenId() + public function testGetRefreshTokenReturnsRefreshTokenWithGivenId(): void { $token = new RefreshToken(); $this->refreshTokenManager->expects($this->once()) ->method('findTokenByToken') ->with('123_abc') - ->will($this->returnValue($token)) + ->willReturn($token) ; - $this->assertSame($token, $this->storage->getRefreshToken('123_abc')); + self::assertSame($token, $this->storage->getRefreshToken('123_abc')); } - public function testGetRefreshTokenReturnsNullIfNotExists() + public function testGetRefreshTokenReturnsNullIfNotExists(): void { $this->refreshTokenManager->expects($this->once()) ->method('findTokenByToken') ->with('123_abc') - ->will($this->returnValue(null)) + ->willReturn(null) ; - $this->assertNull($this->storage->getRefreshToken('123_abc')); + self::assertNull($this->storage->getRefreshToken('123_abc')); } - public function testCreateRefreshTokenThrowsOnInvalidClientClass() + public function testCreateRefreshTokenThrowsOnInvalidClientClass(): void { - $client = $this->getMockBuilder('OAuth2\Model\IOAuth2Client') + $client = $this->getMockBuilder(IOAuth2Client::class) ->disableOriginalConstructor() ->getMock() ; @@ -253,20 +273,20 @@ public function testCreateRefreshTokenThrowsOnInvalidClientClass() $this->storage->createRefreshToken('foo', $client, 42, 1, 'foo bar'); } - public function testCreateRefreshToken() + public function testCreateRefreshToken(): void { $savedToken = null; $this->refreshTokenManager->expects($this->once()) ->method('createToken') ->with() - ->will($this->returnValue(new RefreshToken())) + ->willReturn(new RefreshToken()) ; $this->refreshTokenManager->expects($this->once()) ->method('updateToken') - ->will($this->returnCallback(function ($token) use (&$savedToken) { + ->willReturnCallback(function ($token) use (&$savedToken) { $savedToken = $token; - })) + }) ; $client = new Client(); @@ -274,30 +294,30 @@ public function testCreateRefreshToken() $token = $this->storage->createRefreshToken('foo', $client, $user, 1, 'foo bar'); - $this->assertSame($token, $savedToken); + self::assertSame($token, $savedToken); - $this->assertSame('foo', $token->getToken()); - $this->assertSame($client, $token->getClient()); - $this->assertSame($user, $token->getData()); - $this->assertSame($user, $token->getUser()); - $this->assertSame(1, $token->getExpiresAt()); - $this->assertSame('foo bar', $token->getScope()); + self::assertSame('foo', $token->getToken()); + self::assertSame($client, $token->getClient()); + self::assertSame($user, $token->getData()); + self::assertSame($user, $token->getUser()); + self::assertSame(1, $token->getExpiresAt()); + self::assertSame('foo bar', $token->getScope()); } - public function testCreateRefreshTokenWithoutUser() + public function testCreateRefreshTokenWithoutUser(): void { $savedToken = null; $this->refreshTokenManager->expects($this->once()) ->method('createToken') ->with() - ->will($this->returnValue(new RefreshToken())) + ->willReturn(new RefreshToken()) ; $this->refreshTokenManager->expects($this->once()) ->method('updateToken') - ->will($this->returnCallback(function ($token) use (&$savedToken) { + ->willReturnCallback(function ($token) use (&$savedToken) { $savedToken = $token; - })) + }) ; $client = new Client(); @@ -305,12 +325,13 @@ public function testCreateRefreshTokenWithoutUser() $token = $this->storage->createRefreshToken('foo', $client, $user, 1, 'foo bar'); - $this->assertSame($token, $savedToken); + self::assertSame($token, $savedToken); } - public function testCheckRestrictedGrantTypeThrowsOnInvalidClientClass() + public function testCheckRestrictedGrantTypeThrowsOnInvalidClientClass(): void { - $client = $this->getMockBuilder('OAuth2\Model\IOAuth2Client') + /** @var IOAuth2Client $client */ + $client = $this->getMockBuilder(IOAuth2Client::class) ->disableOriginalConstructor() ->getMock() ; @@ -320,19 +341,20 @@ public function testCheckRestrictedGrantTypeThrowsOnInvalidClientClass() $this->storage->checkRestrictedGrantType($client, 'foo'); } - public function testCheckRestrictedGrantType() + public function testCheckRestrictedGrantType(): void { $client = new Client(); $client->setAllowedGrantTypes(['foo', 'bar']); - $this->assertTrue($this->storage->checkRestrictedGrantType($client, 'foo')); - $this->assertTrue($this->storage->checkRestrictedGrantType($client, 'bar')); - $this->assertFalse($this->storage->checkRestrictedGrantType($client, 'baz')); + self::assertTrue($this->storage->checkRestrictedGrantType($client, 'foo')); + self::assertTrue($this->storage->checkRestrictedGrantType($client, 'bar')); + self::assertFalse($this->storage->checkRestrictedGrantType($client, 'baz')); } - public function testCheckUserCredentialsThrowsOnInvalidClientClass() + public function testCheckUserCredentialsThrowsOnInvalidClientClass(): void { - $client = $this->getMockBuilder('OAuth2\Model\IOAuth2Client') + /** @var IOAuth2Client $client */ + $client = $this->getMockBuilder(IOAuth2Client::class) ->disableOriginalConstructor() ->getMock() ; @@ -342,7 +364,7 @@ public function testCheckUserCredentialsThrowsOnInvalidClientClass() $this->storage->checkUserCredentials($client, 'Joe', 'baz'); } - public function testCheckUserCredentialsCatchesAuthenticationExceptions() + public function testCheckUserCredentialsCatchesAuthenticationExceptions(): void { $client = new Client(); @@ -355,86 +377,86 @@ public function testCheckUserCredentialsCatchesAuthenticationExceptions() $result = $this->storage->checkUserCredentials($client, 'Joe', 'baz'); - $this->assertFalse($result); + self::assertFalse($result); } - public function testCheckUserCredentialsReturnsTrueOnValidCredentials() + public function testCheckUserCredentialsReturnsTrueOnValidCredentials(): void { $client = new Client(); - $user = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface') + $user = $this->getMockBuilder(UserInterface::class) ->disableOriginalConstructor() ->getMock() ; $user->expects($this->once()) - ->method('getPassword')->with()->will($this->returnValue('foo')); + ->method('getPassword')->with()->willReturn('foo'); $user->expects($this->once()) - ->method('getSalt')->with()->will($this->returnValue('bar')); + ->method('getSalt')->with()->willReturn('bar'); - $encoder = $this->getMockBuilder('Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface') + $encoder = $this->getMockBuilder(PasswordEncoderInterface::class) ->disableOriginalConstructor() ->getMock() ; $encoder->expects($this->once()) ->method('isPasswordValid') ->with('foo', 'baz', 'bar') - ->will($this->returnValue(true)) + ->willReturn(true) ; $this->userProvider->expects($this->once()) ->method('loadUserByUsername') ->with('Joe') - ->will($this->returnValue($user)) + ->willReturn($user) ; $this->encoderFactory->expects($this->once()) ->method('getEncoder') ->with($user) - ->will($this->returnValue($encoder)) + ->willReturn($encoder) ; - $this->assertSame([ + self::assertSame([ 'data' => $user, ], $this->storage->checkUserCredentials($client, 'Joe', 'baz')); } - public function testCheckUserCredentialsReturnsFalseOnInvalidCredentials() + public function testCheckUserCredentialsReturnsFalseOnInvalidCredentials(): void { $client = new Client(); - $user = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface') + $user = $this->getMockBuilder(UserInterface::class) ->disableOriginalConstructor() ->getMock() ; $user->expects($this->once()) - ->method('getPassword')->with()->will($this->returnValue('foo')); + ->method('getPassword')->with()->willReturn('foo'); $user->expects($this->once()) - ->method('getSalt')->with()->will($this->returnValue('bar')); + ->method('getSalt')->with()->willReturn('bar'); - $encoder = $this->getMockBuilder('Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface') + $encoder = $this->getMockBuilder(PasswordEncoderInterface::class) ->disableOriginalConstructor() ->getMock() ; $encoder->expects($this->once()) ->method('isPasswordValid') ->with('foo', 'baz', 'bar') - ->will($this->returnValue(false)) + ->willReturn(false) ; $this->userProvider->expects($this->once()) ->method('loadUserByUsername') ->with('Joe') - ->will($this->returnValue($user)) + ->willReturn($user) ; $this->encoderFactory->expects($this->once()) ->method('getEncoder') ->with($user) - ->will($this->returnValue($encoder)) + ->willReturn($encoder) ; - $this->assertFalse($this->storage->checkUserCredentials($client, 'Joe', 'baz')); + self::assertFalse($this->storage->checkUserCredentials($client, 'Joe', 'baz')); } - public function testCheckUserCredentialsReturnsFalseIfUserNotExist() + public function testCheckUserCredentialsReturnsFalseIfUserNotExist(): void { $client = new Client(); @@ -444,12 +466,12 @@ public function testCheckUserCredentialsReturnsFalseIfUserNotExist() ->willThrowException(new AuthenticationException('No such user')) ; - $this->assertFalse($this->storage->checkUserCredentials($client, 'Joe', 'baz')); + self::assertFalse($this->storage->checkUserCredentials($client, 'Joe', 'baz')); } - public function testCreateAuthCodeThrowsOnInvalidClientClass() + public function testCreateAuthCodeThrowsOnInvalidClientClass(): void { - $client = $this->getMockBuilder('OAuth2\Model\IOAuth2Client') + $client = $this->getMockBuilder(IOAuth2Client::class) ->disableOriginalConstructor() ->getMock() ; @@ -458,20 +480,20 @@ public function testCreateAuthCodeThrowsOnInvalidClientClass() $this->storage->createAuthCode('foo', $client, 42, 'http://www.example.com/', 1, 'foo bar'); } - public function testCreateAuthCode() + public function testCreateAuthCode(): void { $savedCode = null; $this->authCodeManager->expects($this->once()) ->method('createAuthCode') ->with() - ->will($this->returnValue(new AuthCode())) + ->willReturn(new AuthCode()) ; $this->authCodeManager->expects($this->once()) ->method('updateAuthCode') - ->will($this->returnCallback(function ($code) use (&$savedCode) { + ->willReturnCallback(static function ($code) use (&$savedCode) { $savedCode = $code; - })) + }) ; $client = new Client(); @@ -479,95 +501,103 @@ public function testCreateAuthCode() $code = $this->storage->createAuthCode('foo', $client, $user, 'http://www.example.com/', 1, 'foo bar'); - $this->assertSame($code, $savedCode); + self::assertSame($code, $savedCode); - $this->assertSame('foo', $code->getToken()); - $this->assertSame($client, $code->getClient()); - $this->assertSame($user, $code->getData()); - $this->assertSame($user, $code->getUser()); - $this->assertSame(1, $code->getExpiresAt()); - $this->assertSame('foo bar', $code->getScope()); + self::assertSame('foo', $code->getToken()); + //TODO getClient doesn't exist on $code AuthCodeInterface - not sure what to do here + //self::assertSame($client, $code->getClient()); + self::assertSame($user, $code->getData()); + self::assertSame($user, $code->getUser()); + self::assertSame(1, $code->getExpiresAt()); + self::assertSame('foo bar', $code->getScope()); } - public function testGetAuthCodeReturnsAuthCodeWithGivenId() + public function testGetAuthCodeReturnsAuthCodeWithGivenId(): void { $code = new AuthCode(); $this->authCodeManager->expects($this->once()) ->method('findAuthCodeByToken') ->with('123_abc') - ->will($this->returnValue($code)) + ->willReturn($code) ; - $this->assertSame($code, $this->storage->getAuthCode('123_abc')); + self::assertSame($code, $this->storage->getAuthCode('123_abc')); } - public function testGetAuthCodeReturnsNullIfNotExists() + public function testGetAuthCodeReturnsNullIfNotExists(): void { $this->authCodeManager->expects($this->once()) ->method('findAuthCodeByToken') ->with('123_abc') - ->will($this->returnValue(null)) + ->willReturn(null) ; - $this->assertNull($this->storage->getAuthCode('123_abc')); + self::assertNull($this->storage->getAuthCode('123_abc')); } - public function testValidGrantExtension() + public function testValidGrantExtension(): void { - $grantExtension = $this->getMockBuilder('FOS\OAuthServerBundle\Storage\GrantExtensionInterface') + $grantExtension = $this->getMockBuilder(GrantExtensionInterface::class) ->disableOriginalConstructor() ->getMock() ; $grantExtension ->expects($this->once()) ->method('checkGrantExtension') - ->will($this->returnValue(true)) + ->willReturn(true) ; $this->storage->setGrantExtension('https://friendsofsymfony.com/grants/foo', $grantExtension); - $client = $this->getMockBuilder('OAuth2\Model\IOAuth2Client') + $client = $this->getMockBuilder(IOAuth2Client::class) ->disableOriginalConstructor() ->getMock() ; - $this->assertTrue($this->storage->checkGrantExtension($client, 'https://friendsofsymfony.com/grants/foo', [], [])); + self::assertTrue( + $this->storage->checkGrantExtension( + $client, + 'https://friendsofsymfony.com/grants/foo', + [], + [] + ) + ); } - public function testInvalidGrantExtension() + public function testInvalidGrantExtension(): void { - $this->expectException(\OAuth2\OAuth2ServerException::class); + $this->expectException(OAuth2ServerException::class); - $client = $this->getMockBuilder('OAuth2\Model\IOAuth2Client') + $client = $this->getMockBuilder(IOAuth2Client::class) ->disableOriginalConstructor() ->getMock() ; $this->storage->checkGrantExtension($client, 'https://friendsofsymfony.com/grants/bar', [], []); } - public function testDoubleSetGrantExtension() + public function testDoubleSetGrantExtension(): void { - $grantExtension = $this->getMockBuilder('FOS\OAuthServerBundle\Storage\GrantExtensionInterface') + $grantExtension = $this->getMockBuilder(GrantExtensionInterface::class) ->disableOriginalConstructor() ->getMock() ; - $grantExtension2 = $this->getMockBuilder('FOS\OAuthServerBundle\Storage\GrantExtensionInterface') + $grantExtension2 = $this->getMockBuilder(GrantExtensionInterface::class) ->disableOriginalConstructor() ->getMock() ; $this->storage->setGrantExtension($uri = 'https://friendsofsymfony.com/grants/foo', $grantExtension); $this->storage->setGrantExtension($uri, $grantExtension2); - $storageClass = new \ReflectionClass(get_class($this->storage)); + $storageClass = new ReflectionClass(get_class($this->storage)); $grantExtensionsProperty = $storageClass->getProperty('grantExtensions'); $grantExtensionsProperty->setAccessible(true); $grantExtensions = $grantExtensionsProperty->getValue($this->storage); - $this->assertSame($grantExtension2, $grantExtensions[$uri]); + self::assertSame($grantExtension2, $grantExtensions[$uri]); } - public function testMarkAuthCodeAsUsedIfAuthCodeFound() + public function testMarkAuthCodeAsUsedIfAuthCodeFound(): void { - $authCode = $this->getMockBuilder('FOS\OAuthServerBundle\Model\AuthCodeInterface') + $authCode = $this->getMockBuilder(AuthCodeInterface::class) ->disableOriginalConstructor() ->getMock() ; @@ -575,24 +605,24 @@ public function testMarkAuthCodeAsUsedIfAuthCodeFound() $this->authCodeManager->expects($this->atLeastOnce()) ->method('findAuthCodeByToken') ->with('123_abc') - ->will($this->returnValue($authCode)) + ->willReturn($authCode) ; $this->authCodeManager->expects($this->atLeastOnce()) ->method('deleteAuthCode') ->with($authCode) - ->will($this->returnValue(null)) + ->willReturn(null) ; $this->storage->markAuthCodeAsUsed('123_abc'); } - public function testMarkAuthCodeAsUsedIfAuthCodeNotFound() + public function testMarkAuthCodeAsUsedIfAuthCodeNotFound(): void { $this->authCodeManager->expects($this->atLeastOnce()) ->method('findAuthCodeByToken') ->with('123_abc') - ->will($this->returnValue(null)) + ->willReturn(null) ; $this->authCodeManager->expects($this->never()) @@ -605,31 +635,35 @@ public function testMarkAuthCodeAsUsedIfAuthCodeNotFound() class User implements UserInterface { + /** @var int */ private $username; - public function __construct($username) + public function __construct(int $username) { $this->username = $username; } - public function getRoles() + public function getRoles(): array { + return []; } - public function getPassword() + public function getPassword(): string { + return ''; } - public function getSalt() + public function getSalt(): string { + return ''; } - public function getUsername() + public function getUsername(): int { return $this->username; } - public function eraseCredentials() + public function eraseCredentials(): void { } } diff --git a/Tests/TestCase.php b/Tests/TestCase.php index 7ec4c0d9..dbbc2d26 100644 --- a/Tests/TestCase.php +++ b/Tests/TestCase.php @@ -13,6 +13,32 @@ namespace FOS\OAuthServerBundle\Tests; -class TestCase extends \PHPUnit\Framework\TestCase +use PHPUnit\Framework\TestCase as BaseTestCase; +use ReflectionClass; + +class TestCase extends BaseTestCase { + /** + * Assert sameness to the value of an object's private or protected member. + * + * @param mixed $expected + */ + protected static function assertObjectPropertySame($expected, object $object, string $property): void + { + self::assertSame($expected, self::getProtectedMemberValue($object, $property)); + } + + /** + * Get the value of an object's private or protected member. + * + * @return mixed + */ + protected static function getProtectedMemberValue(object $object, string $property) + { + $reflectionClass = new ReflectionClass($object); + $reflectionProperty = $reflectionClass->getProperty($property); + $reflectionProperty->setAccessible(true); + + return $reflectionProperty->getValue($object); + } } diff --git a/Tests/Util/RandomTest.php b/Tests/Util/RandomTest.php index 830232a9..d81f0826 100644 --- a/Tests/Util/RandomTest.php +++ b/Tests/Util/RandomTest.php @@ -15,17 +15,18 @@ use FOS\OAuthServerBundle\Util\Random; use phpmock\phpunit\PHPMock; +use PHPUnit\Framework\TestCase; /** * Class RandomTest. * * @author Nikola Petkanski willReturn($baseConvertResult) ; - $this->assertSame($baseConvertResult, Random::generateToken()); + self::assertSame($baseConvertResult, Random::generateToken()); } } diff --git a/Util/LegacyFormHelper.php b/Util/LegacyFormHelper.php index 5653f855..b6cb7870 100644 --- a/Util/LegacyFormHelper.php +++ b/Util/LegacyFormHelper.php @@ -13,6 +13,11 @@ namespace FOS\OAuthServerBundle\Util; +use FOS\OAuthServerBundle\Form\Type\AuthorizeFormType; +use InvalidArgumentException; +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\HiddenType; + /** * @internal * @@ -20,9 +25,10 @@ */ final class LegacyFormHelper { + /** @var array */ private static $map = [ - 'Symfony\Component\Form\Extension\Core\Type\HiddenType' => 'hidden', - 'FOS\OAuthServerBundle\Form\Type\AuthorizeFormType' => 'fos_oauth_server_authorize', + HiddenType::class => 'hidden', + AuthorizeFormType::class => 'fos_oauth_server_authorize', ]; private function __construct() @@ -33,21 +39,21 @@ private function __clone() { } - public static function getType($class) + public static function getType(string $class) { if (!self::isLegacy()) { return $class; } if (!isset(self::$map[$class])) { - throw new \InvalidArgumentException(sprintf('Form type with class "%s" can not be found. Please check for typos or add it to the map in LegacyFormHelper', $class)); + throw new InvalidArgumentException(sprintf('Form type with class "%s" can not be found. '.'Please check for typos or add it to the map in LegacyFormHelper', $class)); } return self::$map[$class]; } - public static function isLegacy() + public static function isLegacy(): bool { - return !method_exists('Symfony\Component\Form\AbstractType', 'getBlockPrefix'); + return !method_exists(AbstractType::class, 'getBlockPrefix'); } } diff --git a/Util/Random.php b/Util/Random.php index f0c10ed5..45324491 100644 --- a/Util/Random.php +++ b/Util/Random.php @@ -20,7 +20,7 @@ */ class Random { - public static function generateToken() + public static function generateToken(): string { $bytes = random_bytes(32); diff --git a/composer.json b/composer.json index c73ffe63..f98b47fc 100644 --- a/composer.json +++ b/composer.json @@ -15,31 +15,43 @@ "homepage": "https://github.com/FriendsOfSymfony/FOSOAuthServerBundle/contributors" } ], + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/elchris/oauth2-php" + } + ], "require": { - "php": "^7.1", - "friendsofsymfony/oauth2-php": "~1.1", - "symfony/dependency-injection": "~3.0|~4.0", - "symfony/framework-bundle": "~3.0|~4.0", - "symfony/security-bundle": "~3.0|~4.0" + "php": ">=7.2", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/framework-bundle": "^4.4|^5.0", + "symfony/security-bundle": "^4.4|^5.0", + "friendsofsymfony/oauth2-php": "dev-symfony-5" }, "require-dev": { - "doctrine/doctrine-bundle": "~1.0", - "doctrine/mongodb-odm": "~1.0", - "doctrine/orm": "~2.2", - "phing/phing": "~2.4", - "php-mock/php-mock-phpunit": "~1.0|~2.0", - "phpstan/phpstan-phpunit": "~0.9", - "phpstan/phpstan-shim": "~0.9", - "phpunit/phpunit": "~5.0|~6.0", - "propel/propel1": "~1.6", - "symfony/class-loader": "~3.0|~4.0", - "symfony/console": "~3.0|~4.0", - "symfony/form": "~3.0|~4.0", - "symfony/phpunit-bridge": "~3.0|~4.0", - "symfony/templating": "~3.0|~4.0", - "symfony/twig-bundle": "~3.0|^4.0", - "symfony/yaml": "~3.0|~4.0", - "willdurand/propel-typehintable-behavior": "~1.0" + "ext-pdo_sqlite": "*", + "ext-mongodb": "*", + "dms/phpunit-arraysubset-asserts": "^0.1.0", + "doctrine/doctrine-bundle": "^2.0", + "doctrine/mongodb-odm-bundle": "^4.1", + "doctrine/orm": "^2.7", + "friendsofphp/php-cs-fixer": "^2.16", + "phing/phing": "^2.16", + "php-mock/php-mock-phpunit": "^2.6", + "phpstan/phpstan": "^0.12.10", + "phpstan/phpstan-phpunit": "^0.12.6", + "phpunit/phpunit": "^8.5", + "propel/propel1": "^1.7", + "roave/security-advisories": "dev-master", + "symfony/browser-kit": "^5.0", + "symfony/class-loader": "^3.4", + "symfony/console": "^5.0", + "symfony/form": "^5.0", + "symfony/monolog-bundle": "^3.5", + "symfony/phpunit-bridge": "^5.0", + "symfony/twig-bundle": "^5.0", + "symfony/yaml": "^5.0", + "willdurand/propel-typehintable-behavior": "^1.0" }, "suggest": { "doctrine/doctrine-bundle": "*", @@ -49,6 +61,11 @@ "symfony/form" : "Needed to be able to use the AuthorizeFormType", "symfony/console": "Needed to be able to use commands" }, + "scripts": { + "lint": "./vendor/bin/php-cs-fixer fix .", + "test": "./vendor/bin/phpunit", + "phpstan": "./vendor/bin/phpstan analyse ." + }, "autoload": { "psr-4": { "FOS\\OAuthServerBundle\\": "" }, "exclude-from-classmap": ["/Tests/"] @@ -59,6 +76,9 @@ "extra": { "branch-alias": { "dev-master": "2.0-dev" + }, + "symfony": { + "require": "4.4.*|5.0.*" } } } diff --git a/phpstan.neon b/phpstan.neon.dist similarity index 98% rename from phpstan.neon rename to phpstan.neon.dist index c94c6e65..035c59a7 100644 --- a/phpstan.neon +++ b/phpstan.neon.dist @@ -19,3 +19,4 @@ parameters: - '#Call to an undefined method Symfony\\Component\\Config\\Definition\\Builder\\NodeDefinition::children().#' # expected - '#Parameter \#2 $requestStack of class FOS\OAuthServerBundle\Form\Handler\AuthorizeFormHandler constructor expects Symfony\Component\HttpFoundation\Request|Symfony\Component\HttpFoundation\RequestStack|null, stdClass given.#' + level: 6 diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 5192b311..79c1174d 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -6,6 +6,10 @@ + + + + ./