diff --git a/.gitignore b/.gitignore
index 23fcec14..9d86457e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,4 +11,5 @@ phpunit.xml
.phpunit.result.cache
# Tests
-tests/.kernel/
+tests/config/reference.php
+tests/.var/
diff --git a/composer.json b/composer.json
index 9d6bcb74..d172a6ea 100644
--- a/composer.json
+++ b/composer.json
@@ -37,7 +37,7 @@
"phpstan/phpstan": "^2.1",
"phpstan/phpstan-symfony": "^2.0",
"symfony/browser-kit": "^6.4|^7.4|^8.0",
- "symfony/phpunit-bridge": "^7.4|^8.0"
+ "symfony/phpunit-bridge": "^8.1"
},
"conflict": {
"doctrine/doctrine-bundle": "<2.8.0",
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 9b5a7741..0bca5df7 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -9,10 +9,8 @@
failOnWarning="true"
>
-
-
+
-
diff --git a/tests/Acceptance/CustomPersistenceManagerTest.php b/tests/Acceptance/CustomPersistenceManagerTest.php
index aa2da8a8..fe9f72bd 100644
--- a/tests/Acceptance/CustomPersistenceManagerTest.php
+++ b/tests/Acceptance/CustomPersistenceManagerTest.php
@@ -24,11 +24,9 @@
use League\Bundle\OAuth2ServerBundle\Tests\Fixtures\FakeRefreshTokenManager;
use League\Bundle\OAuth2ServerBundle\Tests\Fixtures\FixtureFactory;
use League\Bundle\OAuth2ServerBundle\Tests\TestHelper;
-use League\Bundle\OAuth2ServerBundle\Tests\TestKernel;
use League\Bundle\OAuth2ServerBundle\ValueObject\RedirectUri;
use PHPUnit\Framework\MockObject\MockObject;
use Symfony\Bundle\FrameworkBundle\Console\Application;
-use Symfony\Component\HttpKernel\KernelInterface;
class CustomPersistenceManagerTest extends AbstractAcceptanceTest
{
@@ -40,7 +38,7 @@ class CustomPersistenceManagerTest extends AbstractAcceptanceTest
protected function setUp(): void
{
- $this->client = self::createClient();
+ $this->client = self::createClient(['environment' => 'custom_persistence']);
$this->accessTokenManager = $this->createMock(AccessTokenManagerInterface::class);
$this->clientManager = $this->createMock(ClientManagerInterface::class);
$this->refreshTokenManager = $this->createMock(RefreshTokenManagerInterface::class);
@@ -177,23 +175,4 @@ public function testSuccessfullDeviceCodeRequest(): void
$this->client->getResponse();
static::assertResponseIsSuccessful();
}
-
- protected static function createKernel(array $options = []): KernelInterface
- {
- return new TestKernel(
- 'test',
- false,
- null,
- [
- 'custom' => [
- 'access_token_manager' => 'test.access_token_manager',
- 'authorization_code_manager' => 'test.authorization_code_manager',
- 'client_manager' => 'test.client_manager',
- 'refresh_token_manager' => 'test.refresh_token_manager',
- 'credentials_revoker' => 'test.credentials_revoker',
- 'device_code_manager' => 'test.device_code_manager',
- ],
- ]
- );
- }
}
diff --git a/tests/Acceptance/JwtLeewayConfigurationTest.php b/tests/Acceptance/JwtLeewayConfigurationTest.php
index d0a23982..e1dd8482 100644
--- a/tests/Acceptance/JwtLeewayConfigurationTest.php
+++ b/tests/Acceptance/JwtLeewayConfigurationTest.php
@@ -5,16 +5,14 @@
namespace League\Bundle\OAuth2ServerBundle\Tests\Acceptance;
use League\Bundle\OAuth2ServerBundle\Repository\AccessTokenRepository;
-use League\Bundle\OAuth2ServerBundle\Tests\TestKernel;
use League\OAuth2\Server\AuthorizationValidators\BearerTokenValidator;
use Symfony\Bundle\FrameworkBundle\Console\Application;
-use Symfony\Component\HttpKernel\KernelInterface;
class JwtLeewayConfigurationTest extends AbstractAcceptanceTest
{
protected function setUp(): void
{
- $this->client = self::createClient();
+ $this->client = self::createClient(['environment' => 'jwt_leeway']);
$this->application = new Application($this->client->getKernel());
}
@@ -27,16 +25,4 @@ public function testLeewayConfigurationIsSet(): void
$expected = new BearerTokenValidator($tokenRepository, new \DateInterval('PT60S'));
$this->assertEquals($expected, $validator);
}
-
- protected static function createKernel(array $options = []): KernelInterface
- {
- return new TestKernel(
- 'test',
- false,
- [
- 'public_key' => '%env(PUBLIC_KEY_PATH)%',
- 'jwt_leeway' => 'PT60S',
- ]
- );
- }
}
diff --git a/tests/Integration/AuthorizationServerCustomGrantTest.php b/tests/Integration/AuthorizationServerCustomGrantTest.php
index ea0e0efa..5268b28e 100644
--- a/tests/Integration/AuthorizationServerCustomGrantTest.php
+++ b/tests/Integration/AuthorizationServerCustomGrantTest.php
@@ -12,7 +12,7 @@ final class AuthorizationServerCustomGrantTest extends KernelTestCase
{
public function testAuthorizationServerHasOurCustomGrantEnabled(): void
{
- static::bootKernel();
+ static::bootKernel(['environment' => 'fake_grant']);
/** @var AuthorizationServer $authorizationServer */
$authorizationServer = self::getContainer()->get(AuthorizationServer::class);
diff --git a/tests/TestKernel.php b/tests/TestKernel.php
index bd72ecd4..c9e565c9 100644
--- a/tests/TestKernel.php
+++ b/tests/TestKernel.php
@@ -4,273 +4,63 @@
namespace League\Bundle\OAuth2ServerBundle\Tests;
-use Doctrine\DBAL\Platforms\SQLitePlatform;
+use Doctrine\Bundle\DoctrineBundle\DoctrineBundle;
+use League\Bundle\OAuth2ServerBundle\LeagueOAuth2ServerBundle;
use League\Bundle\OAuth2ServerBundle\Manager\AccessTokenManagerInterface;
use League\Bundle\OAuth2ServerBundle\Manager\AuthorizationCodeManagerInterface;
use League\Bundle\OAuth2ServerBundle\Manager\ClientManagerInterface;
use League\Bundle\OAuth2ServerBundle\Manager\DeviceCodeManagerInterface;
use League\Bundle\OAuth2ServerBundle\Manager\RefreshTokenManagerInterface;
use League\Bundle\OAuth2ServerBundle\Manager\ScopeManagerInterface;
-use League\Bundle\OAuth2ServerBundle\Tests\Fixtures\FakeAccessTokenManager;
-use League\Bundle\OAuth2ServerBundle\Tests\Fixtures\FakeAuthorizationCodeManager;
-use League\Bundle\OAuth2ServerBundle\Tests\Fixtures\FakeClientManager;
-use League\Bundle\OAuth2ServerBundle\Tests\Fixtures\FakeCredentialsRevoker;
-use League\Bundle\OAuth2ServerBundle\Tests\Fixtures\FakeDeviceCodeManager;
-use League\Bundle\OAuth2ServerBundle\Tests\Fixtures\FakeGrant;
-use League\Bundle\OAuth2ServerBundle\Tests\Fixtures\FakeRefreshTokenManager;
-use League\Bundle\OAuth2ServerBundle\Tests\Fixtures\FixtureFactory;
-use League\Bundle\OAuth2ServerBundle\Tests\Fixtures\SecurityTestController;
-use Symfony\Component\Config\Loader\LoaderInterface;
+use League\Bundle\OAuth2ServerBundle\Service\CredentialsRevokerInterface;
+use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
+use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
+use Symfony\Bundle\SecurityBundle\SecurityBundle;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
-use Symfony\Component\HttpKernel\Controller\ValueResolverInterface;
use Symfony\Component\HttpKernel\Kernel;
final class TestKernel extends Kernel implements CompilerPassInterface
{
- public function __construct(
- string $environment,
- bool $debug,
- private ?array $resourceServiceConfig = null,
- private ?array $persistenceConfig = null,
- ) {
- parent::__construct($environment, $debug);
- }
+ use MicroKernelTrait;
- public function boot(): void
+ public function registerBundles(): iterable
{
- $this->initializeEnvironmentVariables();
-
- parent::boot();
+ yield new DoctrineBundle();
+ yield new FrameworkBundle();
+ yield new SecurityBundle();
+ yield new LeagueOAuth2ServerBundle();
}
- public function registerBundles(): iterable
+ public function getProjectDir(): string
{
- return [
- new \Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
- new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
- new \Symfony\Bundle\SecurityBundle\SecurityBundle(),
- new \League\Bundle\OAuth2ServerBundle\LeagueOAuth2ServerBundle(),
- ];
+ return __DIR__;
}
public function getCacheDir(): string
{
- $cacheDirectory = 'cache';
-
- // create unique cache directory when custom config is provided
- if (null !== $this->resourceServiceConfig || null !== $this->persistenceConfig) {
- $cacheDirectory = '/cache/' . hash('sha256', serialize(($this->resourceServiceConfig ?? []) + ($this->persistenceConfig ?? [])));
- }
-
- return \sprintf('%s/tests/.kernel/' . $cacheDirectory, $this->getProjectDir());
+ return $this->getProjectDir() . '/.var/cache/' . $this->environment;
}
public function getLogDir(): string
{
- return \sprintf('%s/tests/.kernel/logs', $this->getProjectDir());
+ return $this->getProjectDir() . '/.var/log/' . $this->environment;
}
public function process(ContainerBuilder $container): void
{
- $this->exposeManagerServices($container);
- }
-
- public function registerContainerConfiguration(LoaderInterface $loader): void
- {
- $loader->load(function (ContainerBuilder $container) {
- $doctrine = [
- 'dbal' => [
- 'driver' => 'pdo_sqlite',
- 'charset' => 'utf8mb4',
- 'url' => 'sqlite:///:memory:',
- 'default_table_options' => [
- 'charset' => 'utf8mb4',
- 'utf8mb4_unicode_ci' => 'utf8mb4_unicode_ci',
- ],
- ],
- ];
-
- $doctrine['orm'] = [];
- $container->loadFromExtension('doctrine', $doctrine);
-
- $framework = [
- 'secret' => 'nope',
- 'test' => null,
- 'router' => [
- 'resource' => __DIR__ . '/Fixtures/routes.php',
- 'type' => 'php',
- 'utf8' => true,
- ],
- 'http_method_override' => true,
- 'php_errors' => ['log' => true],
- ];
-
- if (interface_exists(ValueResolverInterface::class)) {
- $framework['handle_all_throwables'] = true;
- }
-
- $container->loadFromExtension('framework', $framework);
-
- if (!$container->hasDefinition('kernel')) {
- $container->register('kernel', static::class)
- ->setSynthetic(true)
- ->setPublic(true)
- ->addTag('routing.route_loader');
- }
-
- $security = [
- 'firewalls' => [
- 'test' => [
- 'provider' => 'in_memory',
- 'pattern' => '^/security-test',
- 'stateless' => true,
- 'oauth2' => true,
- ],
- 'authorization' => [
- 'provider' => 'in_memory',
- 'pattern' => '^/authorize',
- 'http_basic' => true,
- 'stateless' => true,
- ],
- ],
- 'providers' => [
- 'in_memory' => [
- 'memory' => [
- 'users' => [
- FixtureFactory::FIXTURE_USER => [
- 'roles' => ['ROLE_USER'],
- ],
- FixtureFactory::FIXTURE_USER_TWO => [
- 'roles' => ['ROLE_USER'],
- ],
- ],
- ],
- ],
- 'another_provider' => [
- 'memory' => [
- 'users' => [
- FixtureFactory::FIXTURE_USER => [
- 'roles' => ['ROLE_USER'],
- ],
- FixtureFactory::FIXTURE_USER_TWO => [
- 'roles' => ['ROLE_USER'],
- ],
- ],
- ],
- ],
- ],
- 'access_control' => [
- [
- 'path' => '^/authorize',
- 'roles' => 'IS_AUTHENTICATED',
- ],
- [
- 'path' => '^/device-code',
- 'roles' => 'IS_AUTHENTICATED',
- ],
- ],
- ];
-
- $container->loadFromExtension('security', $security);
-
- $container->loadFromExtension('league_oauth2_server', [
- 'authorization_server' => [
- 'private_key' => '%env(PRIVATE_KEY_PATH)%',
- 'encryption_key' => '%env(ENCRYPTION_KEY)%',
- 'enable_password_grant' => true,
- 'enable_implicit_grant' => true,
- ],
- 'resource_server' => $this->resourceServiceConfig ?? ['public_key' => '%env(PUBLIC_KEY_PATH)%'],
- 'scopes' => [
- 'available' => [
- FixtureFactory::FIXTURE_SCOPE_FIRST,
- FixtureFactory::FIXTURE_SCOPE_SECOND,
- ],
- 'default' => [
- FixtureFactory::FIXTURE_SCOPE_SECOND,
- ],
- ],
- 'persistence' => $this->persistenceConfig ?? ['doctrine' => ['entity_manager' => 'default']],
- ]);
-
- $this->configureControllers($container);
- $this->configureDatabaseServices($container);
- $this->configureCustomPersistenceServices($container);
- $this->registerFakeGrant($container);
- });
- }
-
- private function exposeManagerServices(ContainerBuilder $container): void
- {
- $container
- ->getAlias(ScopeManagerInterface::class)
- ->setPublic(true)
- ;
-
- $container
- ->getAlias(ClientManagerInterface::class)
- ->setPublic(true)
- ;
-
- $container
- ->getAlias(AccessTokenManagerInterface::class)
- ->setPublic(true)
- ;
-
- $container
- ->getAlias(RefreshTokenManagerInterface::class)
- ->setPublic(true)
- ;
-
- $container
- ->getAlias(AuthorizationCodeManagerInterface::class)
- ->setPublic(true)
- ;
-
- $container
- ->getAlias(DeviceCodeManagerInterface::class)
- ->setPublic(true)
- ;
- }
-
- private function configureControllers(ContainerBuilder $container): void
- {
- $container
- ->register(SecurityTestController::class)
- ->setAutoconfigured(true)
- ->setAutowired(true)
- ;
- }
-
- private function configureDatabaseServices(ContainerBuilder $container): void
- {
- $container
- ->register(SQLitePlatform::class)
- ->setAutoconfigured(true)
- ->setAutowired(true)
- ;
- }
-
- private function configureCustomPersistenceServices(ContainerBuilder $container): void
- {
- $container->register('test.access_token_manager', FakeAccessTokenManager::class)->setPublic(true);
- $container->register('test.authorization_code_manager', FakeAuthorizationCodeManager::class)->setPublic(true);
- $container->register('test.client_manager', FakeClientManager::class)->setPublic(true);
- $container->register('test.refresh_token_manager', FakeRefreshTokenManager::class)->setPublic(true);
- $container->register('test.credentials_revoker', FakeCredentialsRevoker::class)->setPublic(true);
- $container->register('test.device_code_manager', FakeDeviceCodeManager::class)->setPublic(true);
- }
-
- private function registerFakeGrant(ContainerBuilder $container): void
- {
- $container->register(FakeGrant::class)->setAutoconfigured(true);
- }
+ $publicServicesAlias = [
+ ScopeManagerInterface::class,
+ ClientManagerInterface::class,
+ AccessTokenManagerInterface::class,
+ RefreshTokenManagerInterface::class,
+ AuthorizationCodeManagerInterface::class,
+ DeviceCodeManagerInterface::class,
+ CredentialsRevokerInterface::class,
+ ];
- private function initializeEnvironmentVariables(): void
- {
- putenv(\sprintf('PRIVATE_KEY_PATH=%s', TestHelper::PRIVATE_KEY_PATH));
- putenv(\sprintf('PUBLIC_KEY_PATH=%s', TestHelper::PUBLIC_KEY_PATH));
- putenv(\sprintf('ENCRYPTION_KEY=%s', TestHelper::ENCRYPTION_KEY));
+ foreach ($publicServicesAlias as $serviceAlias) {
+ $container->getAlias($serviceAlias)->setPublic(true);
+ }
}
}
diff --git a/tests/config/packages/custom_persistence/league_oauth2_server.php b/tests/config/packages/custom_persistence/league_oauth2_server.php
new file mode 100644
index 00000000..63e7deab
--- /dev/null
+++ b/tests/config/packages/custom_persistence/league_oauth2_server.php
@@ -0,0 +1,20 @@
+extension('league_oauth2_server', [
+ 'persistence' => [
+ 'custom' => [
+ 'access_token_manager' => 'test.access_token_manager',
+ 'authorization_code_manager' => 'test.authorization_code_manager',
+ 'client_manager' => 'test.client_manager',
+ 'refresh_token_manager' => 'test.refresh_token_manager',
+ 'credentials_revoker' => 'test.credentials_revoker',
+ 'device_code_manager' => 'test.device_code_manager',
+ ],
+ ],
+ ]);
+};
diff --git a/tests/config/packages/doctrine.php b/tests/config/packages/doctrine.php
new file mode 100644
index 00000000..16755702
--- /dev/null
+++ b/tests/config/packages/doctrine.php
@@ -0,0 +1,20 @@
+extension('doctrine', [
+ 'dbal' => [
+ 'driver' => 'pdo_sqlite',
+ 'charset' => 'utf8mb4',
+ 'url' => 'sqlite:///:memory:',
+ 'default_table_options' => [
+ 'charset' => 'utf8mb4',
+ 'collate' => 'utf8mb4_unicode_ci',
+ ],
+ ],
+ 'orm' => [],
+ ]);
+};
diff --git a/tests/config/packages/framework.php b/tests/config/packages/framework.php
new file mode 100644
index 00000000..ed217af8
--- /dev/null
+++ b/tests/config/packages/framework.php
@@ -0,0 +1,17 @@
+extension('framework', [
+ 'secret' => 'nope',
+ 'test' => true,
+ 'http_method_override' => false,
+ 'handle_all_throwables' => true,
+ 'php_errors' => [
+ 'log' => true,
+ ],
+ ]);
+};
diff --git a/tests/config/packages/jwt_leeway/league_oauth2_server.php b/tests/config/packages/jwt_leeway/league_oauth2_server.php
new file mode 100644
index 00000000..86ac40a4
--- /dev/null
+++ b/tests/config/packages/jwt_leeway/league_oauth2_server.php
@@ -0,0 +1,13 @@
+extension('league_oauth2_server', [
+ 'resource_server' => [
+ 'jwt_leeway' => 'PT60S',
+ ],
+ ]);
+};
diff --git a/tests/config/packages/league_oauth2_server.php b/tests/config/packages/league_oauth2_server.php
new file mode 100644
index 00000000..b9329e29
--- /dev/null
+++ b/tests/config/packages/league_oauth2_server.php
@@ -0,0 +1,34 @@
+extension('league_oauth2_server', [
+ 'authorization_server' => [
+ 'private_key' => TestHelper::PRIVATE_KEY_PATH,
+ 'encryption_key' => TestHelper::ENCRYPTION_KEY,
+ 'enable_password_grant' => true,
+ 'enable_implicit_grant' => true,
+ ],
+ 'resource_server' => ['public_key' => TestHelper::PUBLIC_KEY_PATH],
+ 'scopes' => [
+ 'available' => [
+ FixtureFactory::FIXTURE_SCOPE_FIRST,
+ FixtureFactory::FIXTURE_SCOPE_SECOND,
+ ],
+ 'default' => [
+ FixtureFactory::FIXTURE_SCOPE_SECOND,
+ ],
+ ],
+ 'persistence' => [
+ 'doctrine' => [
+ 'entity_manager' => 'default',
+ ],
+ ],
+ ]);
+};
diff --git a/tests/config/packages/security.php b/tests/config/packages/security.php
new file mode 100644
index 00000000..58f06782
--- /dev/null
+++ b/tests/config/packages/security.php
@@ -0,0 +1,62 @@
+extension('security', [
+ 'firewalls' => [
+ 'test' => [
+ 'provider' => 'in_memory',
+ 'pattern' => '^/security-test',
+ 'stateless' => true,
+ 'oauth2' => true,
+ ],
+ 'authorization' => [
+ 'provider' => 'in_memory',
+ 'pattern' => '^/authorize',
+ 'http_basic' => true,
+ 'stateless' => true,
+ ],
+ ],
+ 'providers' => [
+ 'in_memory' => [
+ 'memory' => [
+ 'users' => [
+ FixtureFactory::FIXTURE_USER => [
+ 'roles' => ['ROLE_USER'],
+ ],
+ FixtureFactory::FIXTURE_USER_TWO => [
+ 'roles' => ['ROLE_USER'],
+ ],
+ ],
+ ],
+ ],
+ 'another_provider' => [
+ 'memory' => [
+ 'users' => [
+ FixtureFactory::FIXTURE_USER => [
+ 'roles' => ['ROLE_USER'],
+ ],
+ FixtureFactory::FIXTURE_USER_TWO => [
+ 'roles' => ['ROLE_USER'],
+ ],
+ ],
+ ],
+ ],
+ ],
+ 'access_control' => [
+ [
+ 'path' => '^/authorize',
+ 'roles' => 'IS_AUTHENTICATED',
+ ],
+ [
+ 'path' => '^/device-code',
+ 'roles' => 'IS_AUTHENTICATED',
+ ],
+ ],
+ ]);
+};
diff --git a/tests/config/routes.php b/tests/config/routes.php
new file mode 100644
index 00000000..8c1c6c5d
--- /dev/null
+++ b/tests/config/routes.php
@@ -0,0 +1,29 @@
+add('security_test', '/security-test')
+ ->controller([SecurityTestController::class, 'helloAction'])
+
+ ->add('security_test_scopes', '/security-test-scopes')
+ ->controller([SecurityTestController::class, 'scopeAction'])
+ ->defaults([
+ 'oauth2_scopes' => [FixtureFactory::FIXTURE_SCOPE_FIRST],
+ ])
+
+ ->add('security_test_roles', '/security-test-roles')
+ ->controller([SecurityTestController::class, 'rolesAction'])
+ ->defaults([
+ 'oauth2_scopes' => [FixtureFactory::FIXTURE_SCOPE_FIRST],
+ ])
+
+ ->add('security_test_authorization', '/security-test-authorization')
+ ->controller([SecurityTestController::class, 'authorizationAction'])
+ ;
+};
diff --git a/tests/config/routes/league_oauth2_server.php b/tests/config/routes/league_oauth2_server.php
new file mode 100644
index 00000000..32fe3cd0
--- /dev/null
+++ b/tests/config/routes/league_oauth2_server.php
@@ -0,0 +1,9 @@
+import('@LeagueOAuth2ServerBundle/config/routes.php');
+};
diff --git a/tests/config/services.php b/tests/config/services.php
new file mode 100644
index 00000000..9f94d444
--- /dev/null
+++ b/tests/config/services.php
@@ -0,0 +1,17 @@
+services()
+ ->set(SecurityTestController::class)
+ ->autoconfigure()
+ ->autowire()
+ ->set('logger', NullLogger::class)
+ ;
+};
diff --git a/tests/config/services_custom_persistence.php b/tests/config/services_custom_persistence.php
new file mode 100644
index 00000000..4ef69582
--- /dev/null
+++ b/tests/config/services_custom_persistence.php
@@ -0,0 +1,23 @@
+services()
+ ->set('test.access_token_manager', FakeAccessTokenManager::class)
+ ->set('test.authorization_code_manager', FakeAuthorizationCodeManager::class)
+ ->set('test.client_manager', FakeClientManager::class)
+ ->set('test.refresh_token_manager', FakeRefreshTokenManager::class)
+ ->set('test.credentials_revoker', FakeCredentialsRevoker::class)
+ ->set('test.device_code_manager', FakeDeviceCodeManager::class)
+ ;
+};
diff --git a/tests/config/services_fake_grant.php b/tests/config/services_fake_grant.php
new file mode 100644
index 00000000..c8e881c7
--- /dev/null
+++ b/tests/config/services_fake_grant.php
@@ -0,0 +1,14 @@
+services()
+ ->set(FakeGrant::class)
+ ->autoconfigure()
+ ;
+};