From ce9686079fb508ea53c5f26e19635730d1bf9668 Mon Sep 17 00:00:00 2001 From: Andreas Schempp Date: Thu, 10 Apr 2025 08:55:46 +0200 Subject: [PATCH] Updated dependencies and build chain --- .github/workflows/ci.yml | 22 ++--------------- composer.json | 24 +++++++++++++++---- config/listeners.yml | 4 ++-- phpstan.neon | 3 +++ src/EventListener/NoPwChangePageWarning.php | 6 ++--- src/EventListener/PasswordChangeListener.php | 4 ++-- src/EventListener/PasswordHistoryListener.php | 8 +++---- src/EventListener/PasswordRegexpListener.php | 16 ++++++------- .../RedirectToPasswordChangePageListener.php | 14 +++++------ src/Validation/ValidationContext.php | 8 +++---- src/Validation/Validator/HaveIBeenPwned.php | 8 +++---- src/Validation/Validator/MaximumLength.php | 6 ++--- src/Validation/Validator/MinimumLength.php | 6 ++--- src/Validation/Validator/PasswordHistory.php | 8 +++---- .../Validator/RequiredCharacters.php | 12 ++++++---- src/Validation/ValidatorManager.php | 3 +++ 16 files changed, 78 insertions(+), 74 deletions(-) create mode 100644 phpstan.neon diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fc89221..ce7790d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,23 +7,5 @@ on: permissions: read-all jobs: - ecs: - name: build-tools - runs-on: ubuntu-latest - steps: - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 8.1 - extensions: dom, fileinfo, filter, gd, hash, intl, json, mbstring, mysqli, pcre, pdo_mysql, zlib - coverage: none - - - name: Checkout - uses: actions/checkout@v3 - - - name: Install the dependencies - run: | - composer install --no-interaction --no-progress - - - name: Run all build-tools to validate code - run: composer run build-tools + ci: + uses: 'terminal42/contao-build-tools/.github/workflows/build-tools.yml@main' diff --git a/composer.json b/composer.json index bea8930..822948e 100644 --- a/composer.json +++ b/composer.json @@ -27,13 +27,19 @@ "forum": "https://community.contao.org" }, "require": { - "php": "^8.1", + "php": "^8.2", "contao/core-bundle": "^4.13 || ^5.0", + "doctrine/dbal": "^3.3", "paragonie/hidden-string": "^1.0", - "symfony/config": "^5.0 || ^6.0", - "symfony/dependency-injection": "^5.0 || ^6.0", - "symfony/http-client": "^5.0 || ^6.0", - "symfony/http-kernel": "^5.0 || ^6.0" + "symfony/config": "^5.0 || ^6.0 || ^7.0", + "symfony/dependency-injection": "^5.0 || ^6.0 || ^7.0", + "symfony/http-client-contracts": "^3", + "symfony/http-foundation": "^5.0 || ^6.0 || ^7.0", + "symfony/http-kernel": "^5.0 || ^6.0 || ^7.0", + "symfony/password-hasher": "^5.0 || ^6.0 || ^7.0", + "symfony/security-core": "^5.0 || ^6.0 || ^7.0", + "symfony/string": "^5.0 || ^6.0 || ^7.0", + "symfony/translation-contracts": "^3" }, "require-dev": { "contao/manager-plugin": "^2.7", @@ -46,5 +52,13 @@ }, "extra": { "contao-manager-plugin": "Terminal42\\PasswordValidationBundle\\ContaoManager\\Plugin" + }, + "config": { + "allow-plugins": { + "contao-components/installer": false, + "php-http/discovery": false, + "contao/manager-plugin": false, + "terminal42/contao-build-tools": true + } } } diff --git a/config/listeners.yml b/config/listeners.yml index bb6566c..b1228b0 100644 --- a/config/listeners.yml +++ b/config/listeners.yml @@ -5,7 +5,7 @@ services: - '@terminal42_password_validation.validator_configuration' - '@request_stack' - '@contao.routing.scope_matcher' - - '@security.helper' + - '@security.authorization_checker' Terminal42\PasswordValidationBundle\EventListener\PasswordHistoryListener: arguments: @@ -25,7 +25,7 @@ services: Terminal42\PasswordValidationBundle\EventListener\RedirectToPasswordChangePageListener: arguments: - '@contao.framework' - - '@security.helper' + - '@security.token_storage' - '@contao.routing.scope_matcher' tags: - kernel.event_listener diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..bb824f6 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,3 @@ +parameters: + ignoreErrors: + - '#no value type specified in iterable type array#' diff --git a/src/EventListener/NoPwChangePageWarning.php b/src/EventListener/NoPwChangePageWarning.php index 0251a25..c0cd6d1 100644 --- a/src/EventListener/NoPwChangePageWarning.php +++ b/src/EventListener/NoPwChangePageWarning.php @@ -17,11 +17,11 @@ use Terminal42\PasswordValidationBundle\Validation\ValidationConfiguration; /** * This class adds a warning if some root pages lack of a configured password-change page. */ -final class NoPwChangePageWarning +final readonly class NoPwChangePageWarning { public function __construct( - private readonly ValidationConfiguration $configuration, - private readonly TranslatorInterface $translator, + private ValidationConfiguration $configuration, + private TranslatorInterface $translator, ) { } diff --git a/src/EventListener/PasswordChangeListener.php b/src/EventListener/PasswordChangeListener.php index 63e616f..0abdc4b 100644 --- a/src/EventListener/PasswordChangeListener.php +++ b/src/EventListener/PasswordChangeListener.php @@ -21,9 +21,9 @@ use Terminal42\PasswordValidationBundle\Validation\ValidationConfiguration; * This listener forces a password change for passwords being too old. */ #[AsHook('postLogin')] -final class PasswordChangeListener +final readonly class PasswordChangeListener { - public function __construct(private readonly ValidationConfiguration $configuration) + public function __construct(private ValidationConfiguration $configuration) { } diff --git a/src/EventListener/PasswordHistoryListener.php b/src/EventListener/PasswordHistoryListener.php index 1d16418..7f5687b 100644 --- a/src/EventListener/PasswordHistoryListener.php +++ b/src/EventListener/PasswordHistoryListener.php @@ -21,12 +21,12 @@ use Terminal42\PasswordValidationBundle\Validation\ValidationConfiguration; /** * This listener adds the new password to the password history. */ -final class PasswordHistoryListener +final readonly class PasswordHistoryListener { public function __construct( - private readonly ValidationConfiguration $configuration, - private readonly PasswordHasherFactoryInterface $encoderFactory, - private readonly Connection $connection, + private ValidationConfiguration $configuration, + private PasswordHasherFactoryInterface $encoderFactory, + private Connection $connection, ) { } diff --git a/src/EventListener/PasswordRegexpListener.php b/src/EventListener/PasswordRegexpListener.php index 79e2e17..cea7540 100644 --- a/src/EventListener/PasswordRegexpListener.php +++ b/src/EventListener/PasswordRegexpListener.php @@ -14,7 +14,7 @@ use Contao\ModuleRegistration; use Contao\Widget; use ParagonIE\HiddenString\HiddenString; use Symfony\Component\HttpFoundation\RequestStack; -use Symfony\Component\Security\Core\Security; +use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; use Terminal42\PasswordValidationBundle\Exception\PasswordValidatorException; use Terminal42\PasswordValidationBundle\Validation\ValidationConfiguration; use Terminal42\PasswordValidationBundle\Validation\ValidationContext; @@ -24,14 +24,14 @@ use Terminal42\PasswordValidationBundle\Validation\ValidatorManager; * This listener validates the password input by providing a regexp. */ #[AsHook('addCustomRegexp')] -final class PasswordRegexpListener +final readonly class PasswordRegexpListener { public function __construct( - private readonly ValidatorManager $validatorManager, - private readonly ValidationConfiguration $configuration, - private readonly RequestStack $requestStack, - private readonly ScopeMatcher $scopeMatcher, - private readonly Security $security, + private ValidatorManager $validatorManager, + private ValidationConfiguration $configuration, + private RequestStack $requestStack, + private ScopeMatcher $scopeMatcher, + private AuthorizationCheckerInterface $authorizationChecker, ) { } @@ -50,7 +50,7 @@ final class PasswordRegexpListener } elseif ($dc instanceof ModuleRegistration) { $userId = null; $userEntity = FrontendUser::class; - } elseif ($request && $this->scopeMatcher->isFrontendRequest($request) && $this->security->isGranted('ROLE_MEMBER')) { + } elseif ($request && $this->scopeMatcher->isFrontendRequest($request) && $this->authorizationChecker->isGranted('ROLE_MEMBER')) { $userId = (int) FrontendUser::getInstance()->id; $userEntity = FrontendUser::class; } elseif ( diff --git a/src/EventListener/RedirectToPasswordChangePageListener.php b/src/EventListener/RedirectToPasswordChangePageListener.php index 1e1fc52..499bcb3 100644 --- a/src/EventListener/RedirectToPasswordChangePageListener.php +++ b/src/EventListener/RedirectToPasswordChangePageListener.php @@ -11,14 +11,14 @@ use Contao\CoreBundle\Routing\ScopeMatcher; use Contao\FrontendUser; use Contao\PageModel; use Symfony\Component\HttpKernel\Event\RequestEvent; -use Symfony\Component\Security\Core\Security; +use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -final class RedirectToPasswordChangePageListener +final readonly class RedirectToPasswordChangePageListener { public function __construct( - private readonly ContaoFramework $framework, - private readonly Security $security, - private readonly ScopeMatcher $scopeMatcher, + private ContaoFramework $framework, + private TokenStorageInterface $tokenStorage, + private ScopeMatcher $scopeMatcher, ) { } @@ -29,7 +29,7 @@ final class RedirectToPasswordChangePageListener } $request = $event->getRequest(); - $user = $this->security->getUser(); + $user = $this->tokenStorage->getToken()?->getUser(); $page = $request->attributes->get('pageModel'); if (!$page instanceof PageModel || !$user instanceof FrontendUser || !$user->pwChange) { @@ -38,7 +38,7 @@ final class RedirectToPasswordChangePageListener /** @var PageModel $adapter */ $adapter = $this->framework->getAdapter(PageModel::class); - $rootPage = $adapter->findByPk($page->rootId); + $rootPage = $adapter->findById($page->rootId); // Search for password-change page $pwChangePage = $adapter->findPublishedById($rootPage->pwChangePage ?? 0); diff --git a/src/Validation/ValidationContext.php b/src/Validation/ValidationContext.php index b00c873..68b44d6 100644 --- a/src/Validation/ValidationContext.php +++ b/src/Validation/ValidationContext.php @@ -19,12 +19,12 @@ use ParagonIE\HiddenString\HiddenString; /** * This class holds useful information (e.g. the password to validate) for the validator. */ -final class ValidationContext +final readonly class ValidationContext { public function __construct( - private readonly string $userEntity, - private readonly int|null $userId, - private readonly HiddenString $password, + private string $userEntity, + private int|null $userId, + private HiddenString $password, ) { } diff --git a/src/Validation/Validator/HaveIBeenPwned.php b/src/Validation/Validator/HaveIBeenPwned.php index 5f11276..bd3d002 100644 --- a/src/Validation/Validator/HaveIBeenPwned.php +++ b/src/Validation/Validator/HaveIBeenPwned.php @@ -12,12 +12,12 @@ use Terminal42\PasswordValidationBundle\Validation\PasswordValidatorInterface; use Terminal42\PasswordValidationBundle\Validation\ValidationConfiguration; use Terminal42\PasswordValidationBundle\Validation\ValidationContext; -final class HaveIBeenPwned implements PasswordValidatorInterface +final readonly class HaveIBeenPwned implements PasswordValidatorInterface { public function __construct( - private readonly ValidationConfiguration $configuration, - private readonly HttpClientInterface $client, - private readonly TranslatorInterface $translator, + private ValidationConfiguration $configuration, + private HttpClientInterface $client, + private TranslatorInterface $translator, ) { } diff --git a/src/Validation/Validator/MaximumLength.php b/src/Validation/Validator/MaximumLength.php index faab14b..db606cd 100644 --- a/src/Validation/Validator/MaximumLength.php +++ b/src/Validation/Validator/MaximumLength.php @@ -10,11 +10,11 @@ use Terminal42\PasswordValidationBundle\Validation\PasswordValidatorInterface; use Terminal42\PasswordValidationBundle\Validation\ValidationConfiguration; use Terminal42\PasswordValidationBundle\Validation\ValidationContext; -final class MaximumLength implements PasswordValidatorInterface +final readonly class MaximumLength implements PasswordValidatorInterface { public function __construct( - private readonly ValidationConfiguration $configuration, - private readonly TranslatorInterface $translator, + private ValidationConfiguration $configuration, + private TranslatorInterface $translator, ) { } diff --git a/src/Validation/Validator/MinimumLength.php b/src/Validation/Validator/MinimumLength.php index 1e13e54..c67acb4 100644 --- a/src/Validation/Validator/MinimumLength.php +++ b/src/Validation/Validator/MinimumLength.php @@ -10,11 +10,11 @@ use Terminal42\PasswordValidationBundle\Validation\PasswordValidatorInterface; use Terminal42\PasswordValidationBundle\Validation\ValidationConfiguration; use Terminal42\PasswordValidationBundle\Validation\ValidationContext; -final class MinimumLength implements PasswordValidatorInterface +final readonly class MinimumLength implements PasswordValidatorInterface { public function __construct( - private readonly ValidationConfiguration $configuration, - private readonly TranslatorInterface $translator, + private ValidationConfiguration $configuration, + private TranslatorInterface $translator, ) { } diff --git a/src/Validation/Validator/PasswordHistory.php b/src/Validation/Validator/PasswordHistory.php index b8e3a9c..b0e40c8 100644 --- a/src/Validation/Validator/PasswordHistory.php +++ b/src/Validation/Validator/PasswordHistory.php @@ -13,12 +13,12 @@ use Terminal42\PasswordValidationBundle\Validation\PasswordValidatorInterface; use Terminal42\PasswordValidationBundle\Validation\ValidationConfiguration; use Terminal42\PasswordValidationBundle\Validation\ValidationContext; -final class PasswordHistory implements PasswordValidatorInterface +final readonly class PasswordHistory implements PasswordValidatorInterface { public function __construct( - private readonly ValidationConfiguration $configuration, - private readonly PasswordHasherFactoryInterface $encoderFactory, - private readonly TranslatorInterface $translator, + private ValidationConfiguration $configuration, + private PasswordHasherFactoryInterface $encoderFactory, + private TranslatorInterface $translator, ) { } diff --git a/src/Validation/Validator/RequiredCharacters.php b/src/Validation/Validator/RequiredCharacters.php index 050677d..25c8cc3 100644 --- a/src/Validation/Validator/RequiredCharacters.php +++ b/src/Validation/Validator/RequiredCharacters.php @@ -18,11 +18,13 @@ use Terminal42\PasswordValidationBundle\Validation\PasswordValidatorInterface; use Terminal42\PasswordValidationBundle\Validation\ValidationConfiguration; use Terminal42\PasswordValidationBundle\Validation\ValidationContext; -final class RequiredCharacters implements PasswordValidatorInterface +use function Symfony\Component\String\s; + +final readonly class RequiredCharacters implements PasswordValidatorInterface { public function __construct( - private readonly ValidationConfiguration $configuration, - private readonly TranslatorInterface $translator, + private ValidationConfiguration $configuration, + private TranslatorInterface $translator, ) { } @@ -91,12 +93,12 @@ final class RequiredCharacters implements PasswordValidatorInterface { switch ($category) { case 'lowercase': - $uppercase = mb_strtoupper($string); + $uppercase = s($string)->upper()->toString(); return \strlen($uppercase) - similar_text($string, $uppercase); case 'uppercase': - $lowercase = mb_strtolower($string); + $lowercase = s($string)->lower()->toString(); return \strlen($lowercase) - similar_text($string, $lowercase); diff --git a/src/Validation/ValidatorManager.php b/src/Validation/ValidatorManager.php index 4556154..5575692 100644 --- a/src/Validation/ValidatorManager.php +++ b/src/Validation/ValidatorManager.php @@ -14,6 +14,9 @@ final class ValidatorManager */ private array $validators; + /** + * @param iterable $validators + */ public function __construct(iterable $validators) { $this->validators = $validators instanceof \Traversable ? iterator_to_array($validators) : $validators;