From 0cd73a887a211b69625b4f6e0ae45ff6678f6eef Mon Sep 17 00:00:00 2001 From: Willem Mouwen Date: Fri, 9 Feb 2024 18:58:50 +0100 Subject: [PATCH] Support Doctrine ORM 3.0 --- .github/workflows/static-analysis.yml | 11 ++++- .github/workflows/unit-tests.yml | 10 +++- composer.json | 2 +- src/Model/AbstractClient.php | 48 +++++-------------- src/Model/RefreshToken.php | 25 ++-------- .../Authenticator/OAuth2Authenticator.php | 25 ++-------- .../Exception/InsufficientScopesException.php | 2 +- .../OAuth2AuthenticationException.php | 7 +-- .../OAuth2AuthenticationFailedException.php | 2 +- .../DoctrineCredentialsRevokerTest.php | 4 +- 10 files changed, 48 insertions(+), 88 deletions(-) diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index cf73b695..2498ceca 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -11,6 +11,12 @@ jobs: static-analysis: name: "static analysis" runs-on: "ubuntu-latest" + strategy: + fail-fast: false + matrix: + doctrine-orm: ['2.14.*', '2.18.*', '3.0.*'] + composer-flags: ['--prefer-stable'] + steps: - name: "checkout" uses: "actions/checkout@v4" @@ -18,8 +24,11 @@ jobs: - name: "build the environment" run: "dev/bin/docker-compose build" + - name: "require specific Doctrine ORM version" + run: "dev/bin/php composer require --ansi ${{ matrix.composer-flags }} doctrine/orm:${{ matrix.doctrine-orm }}" + - name: "install dependencies" - run: "dev/bin/php composer update --prefer-stable" + run: "dev/bin/php composer update --ansi ${{ matrix.composer-flags }}" - name: "run static analysis" run: "dev/bin/php psalm --shepherd --stats" diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index f2116e6f..96b16f82 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -16,13 +16,18 @@ jobs: matrix: php: ['8.1', '8.2', '8.3'] symfony: ['5.4.*', '6.4.*', '7.0.*'] + doctrine-orm: ['2.14.*', '2.18.*', '3.0.*'] composer-flags: ['--prefer-stable'] can-fail: [false] exclude: - php: "8.1" symfony: "7.0.*" + - doctrine-orm: "2.14.*" + symfony: "6.4.*" + - doctrine-orm: "2.14.*" + symfony: "7.0.*" - name: "PHP ${{ matrix.php }} - Symfony ${{ matrix.symfony }}${{ matrix.composer-flags != '' && format(' - Composer {0}', matrix.composer-flags) || '' }}" + name: "PHP ${{ matrix.php }} - Doctrine ${{ matrix.doctrine-orm }} - Symfony ${{ matrix.symfony }}${{ matrix.composer-flags != '' && format(' - Composer {0}', matrix.composer-flags) || '' }}" env: SYMFONY_REQUIRE: ${{ matrix.symfony }} @@ -34,6 +39,9 @@ jobs: - name: "build the PHP environment" run: "dev/bin/docker-compose build --build-arg PHP_VERSION=${{ matrix.php }} --build-arg XDEBUG_VERSION='3.3.1' php" + - name: "require specific Doctrine ORM version" + run: "dev/bin/php composer require --ansi ${{ matrix.composer-flags }} doctrine/orm:${{ matrix.doctrine-orm }}" + - name: "install dependencies" run: "dev/bin/php composer update --ansi ${{ matrix.composer-flags }}" diff --git a/composer.json b/composer.json index 45c7fcaf..5c806fc2 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "require": { "php": "^8.1", "doctrine/doctrine-bundle": "^2.0.8", - "doctrine/orm": "^2.7.1", + "doctrine/orm": "^2.14|^3.0", "league/oauth2-server": "^8.3", "nyholm/psr7": "^1.4", "psr/http-factory": "^1.0", diff --git a/src/Model/AbstractClient.php b/src/Model/AbstractClient.php index d653440f..5dca622e 100644 --- a/src/Model/AbstractClient.php +++ b/src/Model/AbstractClient.php @@ -15,45 +15,21 @@ */ abstract class AbstractClient implements ClientInterface { - /** - * @var string - */ - private $name; + private string $name; + protected string $identifier; + private ?string $secret; - /** - * @var string - */ - protected $identifier; + /** @var list */ + private array $redirectUris = []; - /** - * @var string|null - */ - private $secret; + /** @var list */ + private array $grants = []; - /** - * @var list - */ - private $redirectUris = []; + /** @var list */ + private array $scopes = []; - /** - * @var list - */ - private $grants = []; - - /** - * @var list - */ - private $scopes = []; - - /** - * @var bool - */ - private $active = true; - - /** - * @var bool - */ - private $allowPlainTextPkce = false; + private bool $active = true; + private bool $allowPlainTextPkce = false; /** * @psalm-mutation-free @@ -165,7 +141,7 @@ public function setActive(bool $active): ClientInterface */ public function isConfidential(): bool { - return !empty($this->secret); + return null !== $this->secret && '' !== $this->secret; } /** diff --git a/src/Model/RefreshToken.php b/src/Model/RefreshToken.php index 9a15703e..2f5a00fb 100644 --- a/src/Model/RefreshToken.php +++ b/src/Model/RefreshToken.php @@ -6,30 +6,15 @@ class RefreshToken implements RefreshTokenInterface { - /** - * @var string - */ - private $identifier; - - /** - * @var \DateTimeInterface - */ - private $expiry; - - /** - * @var AccessTokenInterface|null - */ - private $accessToken; - - /** - * @var bool - */ - private $revoked = false; + private string $identifier; + private \DateTimeInterface $expiry; + private ?AccessTokenInterface $accessToken; + private bool $revoked = false; /** * @psalm-mutation-free */ - public function __construct(string $identifier, \DateTimeInterface $expiry, AccessTokenInterface $accessToken = null) + public function __construct(string $identifier, \DateTimeInterface $expiry, ?AccessTokenInterface $accessToken = null) { $this->identifier = $identifier; $this->expiry = $expiry; diff --git a/src/Security/Authenticator/OAuth2Authenticator.php b/src/Security/Authenticator/OAuth2Authenticator.php index 647f0d72..19da045d 100644 --- a/src/Security/Authenticator/OAuth2Authenticator.php +++ b/src/Security/Authenticator/OAuth2Authenticator.php @@ -36,25 +36,10 @@ final class OAuth2Authenticator implements AuthenticatorInterface, Authenticatio */ use ForwardCompatAuthenticatorTrait; - /** - * @var HttpMessageFactoryInterface - */ - private $httpMessageFactory; - - /** - * @var ResourceServer - */ - private $resourceServer; - - /** - * @var UserProviderInterface - */ - private $userProvider; - - /** - * @var string - */ - private $rolePrefix; + private HttpMessageFactoryInterface $httpMessageFactory; + private ResourceServer $resourceServer; + private UserProviderInterface $userProvider; + private string $rolePrefix; public function __construct( HttpMessageFactoryInterface $httpMessageFactory, @@ -73,7 +58,7 @@ public function supports(Request $request): ?bool return str_starts_with($request->headers->get('Authorization', ''), 'Bearer '); } - public function start(Request $request, AuthenticationException $authException = null): Response + public function start(Request $request, ?AuthenticationException $authException = null): Response { return new Response('', 401, ['WWW-Authenticate' => 'Bearer']); } diff --git a/src/Security/Exception/InsufficientScopesException.php b/src/Security/Exception/InsufficientScopesException.php index e1bcf1e7..f3167f31 100644 --- a/src/Security/Exception/InsufficientScopesException.php +++ b/src/Security/Exception/InsufficientScopesException.php @@ -9,7 +9,7 @@ */ class InsufficientScopesException extends OAuth2AuthenticationException { - public static function create(\Throwable $previous = null): self + public static function create(?\Throwable $previous = null): self { return new self('Insufficient scopes.', 403, $previous); } diff --git a/src/Security/Exception/OAuth2AuthenticationException.php b/src/Security/Exception/OAuth2AuthenticationException.php index 2509fe92..d4ee6a44 100644 --- a/src/Security/Exception/OAuth2AuthenticationException.php +++ b/src/Security/Exception/OAuth2AuthenticationException.php @@ -12,12 +12,9 @@ */ class OAuth2AuthenticationException extends AuthenticationException implements HttpExceptionInterface { - /** - * @var int - */ - private $statusCode; + private int $statusCode; - public function __construct(string $message, int $statusCode, \Throwable $previous = null) + public function __construct(string $message, int $statusCode, ?\Throwable $previous = null) { $this->statusCode = $statusCode; diff --git a/src/Security/Exception/OAuth2AuthenticationFailedException.php b/src/Security/Exception/OAuth2AuthenticationFailedException.php index 73e457ca..781575c6 100644 --- a/src/Security/Exception/OAuth2AuthenticationFailedException.php +++ b/src/Security/Exception/OAuth2AuthenticationFailedException.php @@ -9,7 +9,7 @@ */ class OAuth2AuthenticationFailedException extends OAuth2AuthenticationException { - public static function create(string $message, \Throwable $previous = null): self + public static function create(string $message, ?\Throwable $previous = null): self { return new self($message, 401, $previous); } diff --git a/tests/Acceptance/DoctrineCredentialsRevokerTest.php b/tests/Acceptance/DoctrineCredentialsRevokerTest.php index e99baab5..4de2ebf1 100644 --- a/tests/Acceptance/DoctrineCredentialsRevokerTest.php +++ b/tests/Acceptance/DoctrineCredentialsRevokerTest.php @@ -90,7 +90,7 @@ private function buildRefreshToken(string $identifier, string $modify, AccessTok ); } - private function buildAccessToken(string $identifier, string $modify, Client $client, string $userIdentifier = null): AccessToken + private function buildAccessToken(string $identifier, string $modify, Client $client, ?string $userIdentifier = null): AccessToken { return new AccessToken( $identifier, @@ -101,7 +101,7 @@ private function buildAccessToken(string $identifier, string $modify, Client $cl ); } - private function buildAuthCode(string $identifier, string $modify, Client $client, string $userIdentifier = null): AuthorizationCode + private function buildAuthCode(string $identifier, string $modify, Client $client, ?string $userIdentifier = null): AuthorizationCode { return new AuthorizationCode( $identifier,