diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a0a6b733..8c9b466e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,6 +5,8 @@ on: branches: - 3.x - 3.next + - 4.x + - 5.x pull_request: branches: - '*' @@ -15,9 +17,9 @@ permissions: jobs: testsuite: - uses: cakephp/.github/.github/workflows/testsuite-without-db.yml@5.x + uses: cakephp/.github/.github/workflows/testsuite-without-db.yml@6.x secrets: inherit cs-stan: - uses: cakephp/.github/.github/workflows/cs-stan.yml@5.x + uses: cakephp/.github/.github/workflows/cs-stan.yml@6.x secrets: inherit diff --git a/.phive/phars.xml b/.phive/phars.xml index 848f478f..12f581a2 100644 --- a/.phive/phars.xml +++ b/.phive/phars.xml @@ -1,4 +1,4 @@ - + diff --git a/composer.json b/composer.json index 07068aa3..0a4e0454 100644 --- a/composer.json +++ b/composer.json @@ -20,12 +20,12 @@ "issues": "https://github.com/cakephp/authentication/issues", "forum": "https://discourse.cakephp.org/", "source": "https://github.com/cakephp/authentication", - "docs": "https://book.cakephp.org/authentication/4/en/" + "docs": "https://book.cakephp.org/authentication/5/" }, "require": { - "php": ">=8.1", - "cakephp/http": "^5.0", - "cakephp/utility": "^5.0", + "php": ">=8.4", + "cakephp/http": "^6.0", + "cakephp/utility": "^6.0", "laminas/laminas-diactoros": "^3.0", "psr/http-client": "^1.0", "psr/http-message": "^1.1 || ^2.0", @@ -33,10 +33,10 @@ "psr/http-server-middleware": "^1.0" }, "require-dev": { - "cakephp/cakephp": "^5.1.0", - "cakephp/cakephp-codesniffer": "^5.0", + "cakephp/cakephp": "^6.0", + "cakephp/cakephp-codesniffer": "^6.0", "firebase/php-jwt": "^7.0", - "phpunit/phpunit": "^10.5.58 || ^11.5.3 || ^12.4 || ^13.0" + "phpunit/phpunit": "^12.4 || ^13.0" }, "suggest": { "ext-ldap": "Make sure this php extension is installed and enabled on your system if you want to use the built-in LDAP adapter for \"LdapIdentifier\".", @@ -75,10 +75,12 @@ "stan": "@phpstan", "stan-baseline": "tools/phpstan --generate-baseline", "stan-setup": "phive install", - "rector-setup": "cp composer.json composer.backup && composer require --dev rector/rector:\"~2.3.1\" && mv composer.backup composer.json", + "rector-setup": "cp composer.json composer.backup && composer require --dev rector/rector:\"~2.6.0\" && mv composer.backup composer.json", "rector-check": "vendor/bin/rector process --dry-run", "rector-fix": "vendor/bin/rector process", "test": "phpunit", "test-coverage": "phpunit --coverage-clover=clover.xml" - } + }, + "minimum-stability": "dev", + "prefer-stable": true } diff --git a/docs/.vitepress/config.js b/docs/.vitepress/config.js index 8f62cd88..204628ff 100644 --- a/docs/.vitepress/config.js +++ b/docs/.vitepress/config.js @@ -5,9 +5,10 @@ const require = createRequire(import.meta.url); const toc_en = require("./toc_en.json"); const versions = { - text: "4.x", + text: "5.x", items: [ - { text: "4.x (current)", link: "https://book.cakephp.org/authentication/4/", target: '_self' }, + { text: "5.x (current)", link: "https://book.cakephp.org/authentication/5/", target: '_self' }, + { text: "4.x", link: "https://book.cakephp.org/authentication/4/", target: '_self' }, { text: "3.x", link: "https://book.cakephp.org/authentication/3/en/", target: '_self' }, { text: "2.x", link: "https://book.cakephp.org/authentication/2/en/", target: '_self' }, ], @@ -19,12 +20,12 @@ export default { srcDir: 'en', title: 'Authentication plugin', description: 'Authentication - CakePHP Authentication Plugin Documentation', - base: "/authentication/4/", + base: "/authentication/5/", rewrites: { "en/:slug*": ":slug*", }, sitemap: { - hostname: "https://book.cakephp.org/authentication/4/", + hostname: "https://book.cakephp.org/authentication/5/", }, themeConfig: { siteTitle: false, @@ -33,7 +34,7 @@ export default { { icon: "github", link: "https://github.com/cakephp/authentication" }, ], editLink: { - pattern: "https://github.com/cakephp/authentication/edit/4.x/docs/:path", + pattern: "https://github.com/cakephp/authentication/edit/5.x/docs/:path", text: "Edit this page on GitHub", }, sidebar: toc_en, diff --git a/docs/.vitepress/toc_en.json b/docs/.vitepress/toc_en.json index fe057a01..6395b4af 100644 --- a/docs/.vitepress/toc_en.json +++ b/docs/.vitepress/toc_en.json @@ -42,7 +42,8 @@ "collapsed": true, "items": [ { "text": "Upgrading from 2.x to 3.x", "link": "/upgrade-2-to-3" }, - { "text": "Upgrading from 3.x to 4.x", "link": "/upgrade-3-to-4" } + { "text": "Upgrading from 3.x to 4.x", "link": "/upgrade-3-to-4" }, + { "text": "Upgrading from 4.x to 5.x", "link": "/upgrade-4-to-5" } ] } ] diff --git a/docs/en/authenticators.md b/docs/en/authenticators.md index 88707aa1..ef7472c9 100644 --- a/docs/en/authenticators.md +++ b/docs/en/authenticators.md @@ -356,7 +356,7 @@ Configuration options: - **samesite**: String/null The value for the same site attribute. The defaults for the various options besides `cookie.name` will be those - set for the `Cake\Http\Cookie\Cookie` class. See [Cookie::setDefaults()](https://api.cakephp.org/5/class-Cake.Http.Cookie.Cookie.html#setDefaults) + set for the `Cake\Http\Cookie\Cookie` class. See [Cookie::setDefaults()](https://api.cakephp.org/6.0/class-Cake.Http.Cookie.Cookie.html#setDefaults) for the default values. - **fields**: Array that maps `username` and `password` to the @@ -468,7 +468,7 @@ There is only one event that is fired by authentication: `Authentication.afterIdentify`. If you don’t know what events are and how to use them [check the -documentation](https://book.cakephp.org/5/en/core-libraries/events.html). +documentation](https://book.cakephp.org/6/en/core-libraries/events.html). The `Authentication.afterIdentify` event is fired by the `AuthenticationComponent` after an identity was successfully diff --git a/docs/en/contents.md b/docs/en/contents.md index adeb1ab8..af8a118a 100644 --- a/docs/en/contents.md +++ b/docs/en/contents.md @@ -17,3 +17,4 @@ - [Migration from the AuthComponent](migration-from-the-authcomponent) - [Upgrading from 2.x to 3.x](upgrade-2-to-3) - [Upgrading from 3.x to 4.x](upgrade-3-to-4) +- [Upgrading from 4.x to 5.x](upgrade-4-to-5) diff --git a/docs/en/identifiers.md b/docs/en/identifiers.md index ab150eac..8fe6f1b9 100644 --- a/docs/en/identifiers.md +++ b/docs/en/identifiers.md @@ -168,7 +168,7 @@ Configuration options: - **userModel**: The user model identities are located in. Default is `Users`. - **finder**: The finder to use with the model. Default is `all`. - You can read more about model finders [here](https://book.cakephp.org/5/en/orm/retrieving-data-and-resultsets.html#custom-finder-methods). + You can read more about model finders [here](https://book.cakephp.org/6/en/orm/retrieving-data-and-resultsets.html#custom-finder-methods). In order to use ORM resolver you must require `cakephp/orm` in your `composer.json` file (if you are not already using the full CakePHP framework). diff --git a/docs/en/index.md b/docs/en/index.md index 48e61278..22e58db4 100644 --- a/docs/en/index.md +++ b/docs/en/index.md @@ -7,7 +7,7 @@ Project's ROOT directory (where the **composer.json** file is located) php composer.phar require cakephp/authentication ``` -Version 4 of the Authentication Plugin is compatible with CakePHP 5. +Version 5 of the Authentication Plugin is compatible with CakePHP 6. Load the plugin using the following command: @@ -17,7 +17,7 @@ bin/cake plugin load Authentication ## Getting Started -The authentication plugin integrates with your application as a [middleware](https://book.cakephp.org/5/en/controllers/middleware.html). It can also +The authentication plugin integrates with your application as a [middleware](https://book.cakephp.org/6/en/controllers/middleware.html). It can also be used as a component to make unauthenticated access simpler. First, let's apply the middleware. In **src/Application.php**, add the following to the class imports: @@ -157,7 +157,7 @@ $this->Authentication->allowUnauthenticated(['view', 'index']); ## Building a Login Action Once you have the middleware applied to your application you'll need a way for -users to login. Please ensure your database has been created with the Users table structure used in the [CMS tutorial](https://book.cakephp.org/5/en/tutorials-and-examples/cms/database.html). First generate a Users model and controller with bake: +users to login. Please ensure your database has been created with the Users table structure used in the [CMS tutorial](https://book.cakephp.org/6/en/tutorials-and-examples/cms/database.html). First generate a Users model and controller with bake: ```bash bin/cake bake model Users diff --git a/docs/en/upgrade-4-to-5.md b/docs/en/upgrade-4-to-5.md new file mode 100644 index 00000000..e065decc --- /dev/null +++ b/docs/en/upgrade-4-to-5.md @@ -0,0 +1,197 @@ +# Upgrade Guide 4.x to 5.x + +Version 5.0 of the Authentication plugin adds support for CakePHP 6. +Application code that only uses the public API rarely needs to change, but +the plugin's classes follow the CakePHP 6 convention changes, so custom +subclasses need to be updated. + +## Requirements + +Version 5.x requires: + +- PHP 8.4 or higher +- CakePHP 6.x, provided by `cakephp/http` and `cakephp/utility` 6.x +- PHPUnit 12.4 or higher when you run the plugin's tests + +```bash +composer require cakephp/authentication:^5.0 +``` + +Upgrade your application to CakePHP 6 first by following the +[CakePHP 6.0 Upgrade Guide](https://book.cakephp.org/6/en/appendices/6-0-upgrade-guide.html), +then install version 5 of this plugin. + +## Breaking Changes + +### Leading Underscore Removed From Properties + +Following CakePHP 6, protected properties no longer start with an underscore. +Update any custom subclass that reads or writes these properties. + +| Old (4.x) | New (5.x) | +| --------- | --------- | +| `$_defaultConfig` | `$defaultConfig` | +| `$_defaultOptions` | `$defaultOptions` | +| `$_identifier` | `$identifier` | +| `$_authentication` | `$authentication` | +| `$_authenticators` | `$authenticators` | +| `$_successfulAuthenticator` | `$successfulAuthenticator` | +| `$_result` | `$result` | +| `$_identity` | `$identity` | +| `$_passwordHasher` | `$passwordHasher` | +| `$_needsPasswordRehash` | `$needsPasswordRehash` | +| `$_hashers` | `$hashers` | +| `$_errors` | `$errors` | +| `$_data` | `$data` | +| `$_status` | `$status` | +| `$_connection` | `$connection` | +| `$_ldap` | `$ldap` | +| `$_loaded` | `$loaded` | + +`$defaultConfig` is declared by the authenticators, identifiers, password +hashers, URL checkers, `AbstractCollection`, `AuthenticationService`, +`AuthenticationComponent`, `Identity` and `IdentityHelper`. The `$config` +property that comes from CakePHP's `InstanceConfigTrait` lost its underscore as +well. + +**Before (4.x):** + +```php +class CustomAuthenticator extends AbstractAuthenticator +{ + protected array $_defaultConfig = [ + 'fields' => ['username' => 'email'], + ]; + + public function example(): void + { + $fields = $this->_defaultConfig['fields']; + } +} +``` + +**After (5.x):** + +```php +class CustomAuthenticator extends AbstractAuthenticator +{ + protected array $defaultConfig = [ + 'fields' => ['username' => 'email'], + ]; + + public function example(): void + { + $fields = $this->defaultConfig['fields']; + } +} +``` + +### Leading Underscore Removed From Methods + +The same rename applies to the plugin's protected methods. + +| Old (4.x) | New (5.x) | Class | +| --------- | --------- | ----- | +| `$_authenticateLegacyToken()` | `authenticateLegacyToken()` | `CookieAuthenticator` | +| `$_authenticateToken()` | `authenticateToken()` | `CookieAuthenticator` | +| `$_bindUser()` | `bindUser()` | `LdapIdentifier` | +| `$_buildLdapObject()` | `buildLdapObject()` | `LdapIdentifier` | +| `$_buildLoginUrlErrorResult()` | `buildLoginUrlErrorResult()` | `EnvironmentAuthenticator`, `FormAuthenticator` | +| `$_checkLdapConfig()` | `checkLdapConfig()` | `LdapIdentifier` | +| `$_checkPassword()` | `checkPassword()` | `PasswordIdentifier` | +| `$_checkSingleUrl()` | `checkSingleUrl()` | `MultiUrlChecker` | +| `$_checkUrl()` | `checkUrl()` | `UrlCheckerTrait` | +| `$_connectLdap()` | `connectLdap()` | `LdapIdentifier` | +| `$_create()` | `create()` | `AuthenticatorCollection` | +| `$_createCookie()` | `createCookie()` | `CookieAuthenticator` | +| `$_createLegacyPlainToken()` | `createLegacyPlainToken()` | `CookieAuthenticator` | +| `$_createToken()` | `createToken()` | `CookieAuthenticator` | +| `$_expiryTimestamp()` | `expiryTimestamp()` | `CookieAuthenticator` | +| `$_findIdentity()` | `findIdentity()` | `PasswordIdentifier` | +| `$_getChecker()` | `getChecker()` | `StringUrlChecker` | +| `$_getData()` | `getData()` | `FormAuthenticator` | +| `$_getUrlFromRequest()` | `getUrlFromRequest()` | `DefaultUrlChecker`, `StringUrlChecker` | +| `$_handleLdapError()` | `handleLdapError()` | `LdapIdentifier` | +| `$_hmacKey()` | `hmacKey()` | `CookieAuthenticator` | +| `$_isSingleRoute()` | `isSingleRoute()` | `MultiUrlChecker` | +| `$_legacyHashWithinLimits()` | `legacyHashWithinLimits()` | `CookieAuthenticator` | +| `$_mergeDefaultOptions()` | `mergeDefaultOptions()` | `DefaultUrlChecker`, `MultiUrlChecker`, `StringUrlChecker` | +| `$_resolveClassName()` | `resolveClassName()` | `AuthenticatorCollection` | +| `$_setErrorHandler()` | `setErrorHandler()` | `ExtensionAdapter` | +| `$_throwMissingClassError()` | `throwMissingClassError()` | `AuthenticatorCollection` | +| `$_unsetErrorHandler()` | `unsetErrorHandler()` | `ExtensionAdapter` | + +The [cakephp/upgrade](https://github.com/cakephp/upgrade) tool knows about the +CakePHP 6 renames and can apply most of them for you. + +### Fluent Methods Now Return `static` + +These methods now declare a `static` return type. If you override any of them, +add the same return type to your override: + +- `AuthenticationComponent::allowUnauthenticated()` +- `AuthenticationComponent::addUnauthenticatedActions()` +- `AuthenticationComponent::setIdentity()` +- `AuthenticationComponent::replaceIdentity()` +- `AuthenticationComponent::impersonate()` +- `AuthenticationComponent::stopImpersonating()` +- `AbstractAuthenticator::setIdentifier()` +- `PasswordHasherTrait::setPasswordHasher()` +- `ResolverAwareTrait::setResolver()` + +**Before (4.x):** + +```php +class CustomComponent extends AuthenticationComponent +{ + public function allowUnauthenticated(array $actions) + { + return parent::allowUnauthenticated($actions); + } +} +``` + +**After (5.x):** + +```php +class CustomComponent extends AuthenticationComponent +{ + public function allowUnauthenticated(array $actions): static + { + return parent::allowUnauthenticated($actions); + } +} +``` + +### Constructor Changes + +- The third argument of `Result::__construct()` was renamed from `$messages` + to `$errors`. Named arguments such as `messages:` must be updated. +- The second argument of `AuthenticationMiddleware::__construct()` is typed as + `Cake\Container\ContainerInterface` instead of `Cake\Core\ContainerInterface`. +- `AbstractAuthenticator`, `AuthenticationMiddleware`, `AuthenticationRequiredException`, + `Identity` and `Result` use constructor promoted properties now. Subclasses + that override these constructors should call `parent::__construct()` with the + same arguments as before. + +## Migration Tips + +1. **Upgrade CakePHP first**: Finish the + [CakePHP 6.0 Upgrade Guide](https://book.cakephp.org/6/en/appendices/6-0-upgrade-guide.html) + and resolve all deprecation warnings while you are still on CakePHP 5. + +2. **Search and replace** the renamed members in your custom authenticators, + identifiers, password hashers, URL checkers and components: + + - `$_defaultConfig` → `$defaultConfig` + - `$_defaultOptions` → `$defaultOptions` + - `$_identifier` → `$identifier` + - `$_config` → `$config` + - `$this->_checkUrl(` → `$this->checkUrl(` + - Any other `$_method()` or `$_property` of the plugin's classes + +3. **Add return types** to overridden fluent methods so they match the new + `static` return types. + +4. **Run your test suite** with the new dependencies to find remaining + references to the old names. diff --git a/phpcs.xml b/phpcs.xml index 9666feee..2c26cd67 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -5,7 +5,7 @@ src/ tests/ - + diff --git a/readme.md b/readme.md index aba6a8cd..eb150523 100644 --- a/readme.md +++ b/readme.md @@ -8,7 +8,7 @@ [PSR7](https://www.php-fig.org/psr/psr-7/) Middleware authentication stack for the CakePHP framework. -Don't know what middleware is? [Check the CakePHP documentation](https://book.cakephp.org/5/en/controllers/middleware.html) and additionally [read this.](https://philsturgeon.uk/php/2016/05/31/why-care-about-php-middleware/) +Don't know what middleware is? [Check the CakePHP documentation](https://book.cakephp.org/6/en/controllers/middleware.html) and additionally [read this.](https://philsturgeon.uk/php/2016/05/31/why-care-about-php-middleware/) ## Authentication, not Authorization @@ -33,7 +33,7 @@ bin/cake plugin load Authentication ## Documentation -Documentation for this plugin can be found in the [CakePHP Cookbook](https://book.cakephp.org/authentication/4/). +Documentation for this plugin can be found in the [CakePHP Cookbook](https://book.cakephp.org/authentication/5/). ## IDE compatibility improvements diff --git a/rector.php b/rector.php index a93e7edc..c3ee10fe 100644 --- a/rector.php +++ b/rector.php @@ -2,25 +2,102 @@ declare(strict_types=1); use Rector\Caching\ValueObject\Storage\FileCacheStorage; +use Rector\CodeQuality\Rector\BooleanNot\NegatedAndsToPositiveOrsRector; +use Rector\CodeQuality\Rector\Catch_\ThrowWithPreviousExceptionRector; +use Rector\CodeQuality\Rector\Class_\CompleteDynamicPropertiesRector; +use Rector\CodeQuality\Rector\ClassMethod\ExplicitReturnNullRector; +use Rector\CodeQuality\Rector\ClassMethod\OptionalParametersAfterRequiredRector; +use Rector\CodeQuality\Rector\Equal\UseIdenticalOverEqualWithSameTypeRector; +use Rector\CodeQuality\Rector\Foreach_\ForeachToInArrayRector; use Rector\CodeQuality\Rector\FuncCall\CompactToVariablesRector; -use Rector\CodeQuality\Rector\If_\ExplicitBoolCompareRector; -use Rector\CodingStyle\Rector\Assign\SplitDoubleAssignRector; +use Rector\CodeQuality\Rector\Identical\FlipTypeControlToUseExclusiveTypeRector; +use Rector\CodeQuality\Rector\If_\ConsecutiveNullCompareReturnsToNullCoalesceQueueRector; +use Rector\CodeQuality\Rector\If_\SimplifyIfReturnBoolRector; +use Rector\CodeQuality\Rector\Include_\AbsolutizeRequireAndIncludePathRector; +use Rector\CodeQuality\Rector\Isset_\IssetOnPropertyObjectToPropertyExistsRector; +use Rector\CodeQuality\Rector\Property\FixClassCaseSensitivityVarDocblockRector; use Rector\CodingStyle\Rector\Catch_\CatchExceptionNameMatchingTypeRector; +use Rector\CodingStyle\Rector\ClassLike\NewlineBetweenClassLikeStmtsRector; +use Rector\CodingStyle\Rector\ClassMethod\MakeInheritedMethodVisibilitySameAsParentRector; +use Rector\CodingStyle\Rector\ClassMethod\NewlineBeforeNewAssignSetRector; +use Rector\CodingStyle\Rector\FuncCall\FunctionFirstClassCallableRector; +use Rector\CodingStyle\Rector\FuncCall\StrictArraySearchRector; +use Rector\CodingStyle\Rector\FuncCall\VersionCompareFuncCallToConstantRector; use Rector\CodingStyle\Rector\Stmt\NewlineAfterStatementRector; +use Rector\CodingStyle\Rector\String_\UseClassKeywordForClassNameResolutionRector; use Rector\Config\RectorConfig; +use Rector\DeadCode\Rector\Assign\RemoveDoubleAssignRector; +use Rector\DeadCode\Rector\Assign\RemoveUnusedVariableAssignRector; +use Rector\DeadCode\Rector\Cast\RecastingRemovalRector; +use Rector\DeadCode\Rector\ClassMethod\RemoveDuplicatedReturnSelfDocblockRector; +use Rector\DeadCode\Rector\ClassMethod\RemoveEmptyClassMethodRector; +use Rector\DeadCode\Rector\ClassMethod\RemoveMixedDocblockOverruledByNativeTypeRector; +use Rector\DeadCode\Rector\ClassMethod\RemoveNullTagValueNodeRector; +use Rector\DeadCode\Rector\ClassMethod\RemoveParentDelegatingClassMethodRector; +use Rector\DeadCode\Rector\ClassMethod\RemoveReturnTagIncompatibleWithNativeTypeRector; +use Rector\DeadCode\Rector\ClassMethod\RemoveUnusedConstructorParamRector; +use Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector; +use Rector\DeadCode\Rector\ClassMethod\RemoveUselessParamTagRector; use Rector\DeadCode\Rector\ClassMethod\RemoveUselessReturnTagRector; +use Rector\DeadCode\Rector\ClassMethod\RemoveUselessUnionReturnDocblockRector; +use Rector\DeadCode\Rector\ConstFetch\RemovePhpVersionIdCheckRector; +use Rector\DeadCode\Rector\Expression\RemoveDeadStmtRector; +use Rector\DeadCode\Rector\For_\RemoveDeadIfForeachForRector; +use Rector\DeadCode\Rector\For_\RemoveDeadLoopRector; +use Rector\DeadCode\Rector\If_\RemoveAlwaysTrueIfConditionRector; +use Rector\DeadCode\Rector\If_\RemoveDeadInstanceOfRector; +use Rector\DeadCode\Rector\If_\UnwrapFutureCompatibleIfPhpVersionRector; +use Rector\DeadCode\Rector\MethodCall\RemoveNullArgOnNullDefaultParamRector; +use Rector\DeadCode\Rector\Node\RemoveNonExistingVarAnnotationRector; +use Rector\DeadCode\Rector\Property\RemoveDefaultValueFromAssignedPropertyRector; +use Rector\DeadCode\Rector\Property\RemoveUselessVarTagRector; +use Rector\DeadCode\Rector\StmtsAwareInterface\RemoveDeadInstanceOfAssertRector; +use Rector\DeadCode\Rector\Ternary\RemoveUselessTernaryRector; +use Rector\Php55\Rector\String_\StringClassNameToClassConstantRector; +use Rector\Php56\Rector\FuncCall\PowToExpRector; +use Rector\Php73\Rector\FuncCall\ArrayKeyFirstLastRector; +use Rector\Php73\Rector\FuncCall\SetCookieRector; +use Rector\Php73\Rector\FuncCall\StringifyStrNeedlesRector; +use Rector\Php73\Rector\String_\SensitiveHereNowDocRector; use Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector; -use Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector; +use Rector\Php74\Rector\Property\RestoreDefaultNullToNullableTypePropertyRector; +use Rector\Php80\Rector\FuncCall\ClassOnObjectRector; +use Rector\Php80\Rector\NotIdentical\MbStrContainsRector; +use Rector\Php81\Rector\Property\ReadOnlyPropertyRector; use Rector\Set\ValueObject\SetList; +use Rector\TypeDeclaration\Rector\ArrowFunction\AddArrowFunctionReturnTypeRector; +use Rector\TypeDeclaration\Rector\BooleanAnd\BinaryOpNullableToInstanceofRector; use Rector\TypeDeclaration\Rector\Class_\TypedPropertyFromCreateMockAssignRector; +use Rector\TypeDeclaration\Rector\ClassMethod\AddParamStringTypeFromSprintfUseRector; +use Rector\TypeDeclaration\Rector\ClassMethod\AddParamTypeBasedOnPHPUnitDataProviderRector; +use Rector\TypeDeclaration\Rector\ClassMethod\AddVoidReturnTypeWhereNoReturnRector; +use Rector\TypeDeclaration\Rector\ClassMethod\ArrayParamTypeByMethodCallTypeRector; +use Rector\TypeDeclaration\Rector\ClassMethod\BoolReturnTypeFromBooleanConstReturnsRector; +use Rector\TypeDeclaration\Rector\ClassMethod\ParamTypeByMethodCallTypeRector; +use Rector\TypeDeclaration\Rector\ClassMethod\ReturnNeverTypeRector; +use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromMockObjectRector; use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictFluentReturnRector; +use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedCallRector; +use Rector\TypeDeclaration\Rector\ClassMethod\ReturnUnionTypeRector; +use Rector\TypeDeclaration\Rector\ClassMethod\ScalarParamTypeByMethodCallTypeRector; +use Rector\TypeDeclaration\Rector\ClassMethod\StrictArrayParamDimFetchRector; +use Rector\TypeDeclaration\Rector\Closure\AddClosureNeverReturnTypeRector; +use Rector\TypeDeclaration\Rector\Closure\ClosureReturnTypeFromAssertInstanceOfRector; +use Rector\TypeDeclaration\Rector\Closure\ClosureReturnTypeRector; +use Rector\TypeDeclaration\Rector\FunctionLike\AddClosureParamTypeForArrayMapRector; +use Rector\TypeDeclaration\Rector\FunctionLike\AddClosureParamTypeFromVariableCallRector; +use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector; +use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromStrictConstructorRector; +use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromStrictSetUpRector; +use Rector\TypeDeclaration\Rector\StmtsAwareInterface\SafeDeclareStrictTypesRector; +use Rector\TypeDeclaration\Rector\While_\WhileNullableToInstanceofRector; $cacheDir = getenv('RECTOR_CACHE_DIR') ?: sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'rector'; return RectorConfig::configure() ->withPaths([ __DIR__ . '/src', - __DIR__ . '/tests', + __DIR__ . '/tests/TestCase', ]) ->withCache( @@ -35,20 +112,108 @@ SetList::CODE_QUALITY, SetList::CODING_STYLE, SetList::DEAD_CODE, - SetList::EARLY_RETURN, - SetList::INSTANCEOF, SetList::TYPE_DECLARATION, ]) ->withSkip([ - ClassPropertyAssignToConstructorPromotionRector::class, + ThrowWithPreviousExceptionRector::class, + ExplicitReturnNullRector::class, + OptionalParametersAfterRequiredRector::class, + CompleteDynamicPropertiesRector::class, + ForeachToInArrayRector::class, + CompactToVariablesRector::class, + FlipTypeControlToUseExclusiveTypeRector::class, + ConsecutiveNullCompareReturnsToNullCoalesceQueueRector::class, + SimplifyIfReturnBoolRector::class, + AbsolutizeRequireAndIncludePathRector::class, + IssetOnPropertyObjectToPropertyExistsRector::class, CatchExceptionNameMatchingTypeRector::class, - ClosureToArrowFunctionRector::class, + CatchExceptionNameMatchingTypeRector::class, + MakeInheritedMethodVisibilitySameAsParentRector::class, + NewlineBeforeNewAssignSetRector::class, + StrictArraySearchRector::class, + VersionCompareFuncCallToConstantRector::class, + FunctionFirstClassCallableRector::class, + NewlineAfterStatementRector::class, + UseClassKeywordForClassNameResolutionRector::class, + RemoveDoubleAssignRector::class, + RemoveUnusedVariableAssignRector::class, + RecastingRemovalRector::class, + RemoveEmptyClassMethodRector::class, + RemoveNullTagValueNodeRector::class, + RemoveUnusedConstructorParamRector::class, + RemoveUnusedPrivateMethodRector::class, + RemoveUselessParamTagRector::class, RemoveUselessReturnTagRector::class, - CompactToVariablesRector::class, + RemovePhpVersionIdCheckRector::class, + RemoveDeadStmtRector::class, + RemoveDeadIfForeachForRector::class, + RemoveDeadLoopRector::class, + RemoveAlwaysTrueIfConditionRector::class, + RemoveDeadInstanceOfRector::class, + UnwrapFutureCompatibleIfPhpVersionRector::class, + RemoveNullArgOnNullDefaultParamRector::class, + RemoveNonExistingVarAnnotationRector::class, + RemoveUselessVarTagRector::class, + PowToExpRector::class, + ArrayKeyFirstLastRector::class, + SetCookieRector::class, + StringifyStrNeedlesRector::class, + SensitiveHereNowDocRector::class, + ClosureToArrowFunctionRector::class, + ReadOnlyPropertyRector::class, + AddArrowFunctionReturnTypeRector::class, + BinaryOpNullableToInstanceofRector::class, + NewlineBetweenClassLikeStmtsRector::class, + AddParamStringTypeFromSprintfUseRector::class, + AddParamTypeBasedOnPHPUnitDataProviderRector::class, + AddVoidReturnTypeWhereNoReturnRector::class, + BoolReturnTypeFromBooleanConstReturnsRector::class, + ParamTypeByMethodCallTypeRector::class, + ReturnNeverTypeRector::class, + ReturnTypeFromMockObjectRector::class, ReturnTypeFromStrictFluentReturnRector::class, - SplitDoubleAssignRector::class, - NewlineAfterStatementRector::class, - ExplicitBoolCompareRector::class, + ReturnTypeFromStrictTypedCallRector::class, + ReturnUnionTypeRector::class, + StrictArrayParamDimFetchRector::class, TypedPropertyFromCreateMockAssignRector::class, + AddClosureNeverReturnTypeRector::class, + ClosureReturnTypeRector::class, + TypedPropertyFromAssignsRector::class, + TypedPropertyFromStrictConstructorRector::class, + TypedPropertyFromStrictSetUpRector::class, + WhileNullableToInstanceofRector::class, + RestoreDefaultNullToNullableTypePropertyRector::class, + + // Manual - only appliable for part of the code + UseIdenticalOverEqualWithSameTypeRector::class, + RemoveDeadStmtRector::class, + StringClassNameToClassConstantRector::class, + ArrayKeyFirstLastRector::class, + ClassOnObjectRector::class, + + // Newly aggressive in rector 2.4 - keep the bump behavior-neutral: + // adds declare(strict_types=1) to test fixtures/config (out of scope here), + SafeDeclareStrictTypesRector::class, + // and rewrites `$x ?: []` in ways that can change behavior on undefined/empty values. + RemoveUselessTernaryRector::class, + + // New in rector 2.5 - skipped to keep the version bump behavior-neutral. + // Together these touch ~226 files, mostly docblock removal. Whether to apply + // them is a separate decision from getting CI green again. + NegatedAndsToPositiveOrsRector::class, + FixClassCaseSensitivityVarDocblockRector::class, + RemoveDuplicatedReturnSelfDocblockRector::class, + RemoveMixedDocblockOverruledByNativeTypeRector::class, + RemoveParentDelegatingClassMethodRector::class, + RemoveReturnTagIncompatibleWithNativeTypeRector::class, + RemoveUselessUnionReturnDocblockRector::class, + RemoveDefaultValueFromAssignedPropertyRector::class, + RemoveDeadInstanceOfAssertRector::class, + MbStrContainsRector::class, + ArrayParamTypeByMethodCallTypeRector::class, + ScalarParamTypeByMethodCallTypeRector::class, + ClosureReturnTypeFromAssertInstanceOfRector::class, + AddClosureParamTypeForArrayMapRector::class, + AddClosureParamTypeFromVariableCallRector::class, ]); diff --git a/src/AbstractCollection.php b/src/AbstractCollection.php index 3e9a009c..82ac8406 100644 --- a/src/AbstractCollection.php +++ b/src/AbstractCollection.php @@ -32,7 +32,7 @@ abstract class AbstractCollection extends ObjectRegistry * * @var array */ - protected array $_defaultConfig = []; + protected array $defaultConfig = []; /** * Constructor @@ -60,6 +60,6 @@ public function __construct(array $config = []) */ public function isEmpty(): bool { - return $this->_loaded === []; + return $this->loaded === []; } } diff --git a/src/AuthenticationService.php b/src/AuthenticationService.php index 11476f8f..6a376f19 100644 --- a/src/AuthenticationService.php +++ b/src/AuthenticationService.php @@ -42,17 +42,17 @@ class AuthenticationService implements AuthenticationServiceInterface, Impersona /** * Authenticator collection */ - protected ?AuthenticatorCollection $_authenticators = null; + protected ?AuthenticatorCollection $authenticators = null; /** * Authenticator that successfully authenticated the identity. */ - protected ?AuthenticatorInterface $_successfulAuthenticator = null; + protected ?AuthenticatorInterface $successfulAuthenticator = null; /** * Result of the last authenticate() call. */ - protected ?ResultInterface $_result = null; + protected ?ResultInterface $result = null; /** * Default configuration @@ -93,7 +93,7 @@ class AuthenticationService implements AuthenticationServiceInterface, Impersona * * @var array */ - protected array $_defaultConfig = [ + protected array $defaultConfig = [ 'authenticators' => [], 'identityClass' => Identity::class, 'identityAttribute' => 'identity', @@ -124,12 +124,12 @@ public function __construct(array $config = []) */ public function authenticators(): AuthenticatorCollection { - if (!$this->_authenticators instanceof AuthenticatorCollection) { + if (!$this->authenticators instanceof AuthenticatorCollection) { $authenticators = $this->getConfig('authenticators'); - $this->_authenticators = new AuthenticatorCollection($authenticators); + $this->authenticators = new AuthenticatorCollection($authenticators); } - return $this->_authenticators; + return $this->authenticators; } /** @@ -159,9 +159,9 @@ public function authenticate(ServerRequestInterface $request): ResultInterface foreach ($this->authenticators() as $authenticator) { $result = $authenticator->authenticate($request); if ($result->isValid()) { - $this->_successfulAuthenticator = $authenticator; + $this->successfulAuthenticator = $authenticator; - return $this->_result = $result; + return $this->result = $result; } if ($authenticator instanceof StatelessInterface) { @@ -175,9 +175,9 @@ public function authenticate(ServerRequestInterface $request): ResultInterface ); } - $this->_successfulAuthenticator = null; + $this->successfulAuthenticator = null; - return $this->_result = $result; + return $this->result = $result; } /** @@ -200,7 +200,7 @@ public function clearIdentity(ServerRequestInterface $request, ResponseInterface ['request' => $request, 'response' => $response] = $result; } } - $this->_successfulAuthenticator = null; + $this->successfulAuthenticator = null; return [ 'request' => $request->withoutAttribute($this->getConfig('identityAttribute')), @@ -244,7 +244,7 @@ public function persistIdentity( */ public function getAuthenticationProvider(): ?AuthenticatorInterface { - return $this->_successfulAuthenticator; + return $this->successfulAuthenticator; } /** @@ -254,12 +254,12 @@ public function getAuthenticationProvider(): ?AuthenticatorInterface */ public function getIdentificationProvider(): ?IdentifierInterface { - if (!$this->_successfulAuthenticator instanceof AuthenticatorInterface) { + if (!$this->successfulAuthenticator instanceof AuthenticatorInterface) { return null; } try { - return $this->_successfulAuthenticator->getIdentifier(); + return $this->successfulAuthenticator->getIdentifier(); } catch (MissingIdentifierException) { // Authenticators may operate without an identifier (e.g. session // based authentication with `identify` disabled), in which case @@ -277,7 +277,7 @@ public function getIdentificationProvider(): ?IdentifierInterface */ public function getResult(): ?ResultInterface { - return $this->_result; + return $this->result; } /** @@ -287,12 +287,12 @@ public function getResult(): ?ResultInterface */ public function getIdentity(): ?IdentityInterface { - if (!$this->_result instanceof ResultInterface) { + if (!$this->result instanceof ResultInterface) { return null; } - $identityData = $this->_result->getData(); - if (!$this->_result->isValid() || $identityData === null) { + $identityData = $this->result->getData(); + if (!$this->result->isValid() || $identityData === null) { return null; } @@ -548,9 +548,10 @@ protected function getImpersonationProvider(): ImpersonationInterface } if (!($provider instanceof ImpersonationInterface)) { $className = $provider::class; - throw new InvalidArgumentException( - sprintf('The %s Provider must implement ImpersonationInterface in order to use impersonation.', $className), - ); + throw new InvalidArgumentException(sprintf( + 'The %s Provider must implement ImpersonationInterface in order to use impersonation.', + $className, + )); } return $provider; diff --git a/src/Authenticator/AbstractAuthenticator.php b/src/Authenticator/AbstractAuthenticator.php index 8fec2c86..5413374c 100644 --- a/src/Authenticator/AbstractAuthenticator.php +++ b/src/Authenticator/AbstractAuthenticator.php @@ -31,27 +31,21 @@ abstract class AbstractAuthenticator implements AuthenticatorInterface * * @var array */ - protected array $_defaultConfig = [ + protected array $defaultConfig = [ 'fields' => [ PasswordIdentifier::CREDENTIAL_USERNAME => 'username', PasswordIdentifier::CREDENTIAL_PASSWORD => 'password', ], ]; - /** - * Identifier instance. - */ - protected ?IdentifierInterface $_identifier = null; - /** * Constructor * * @param \Authentication\Identifier\IdentifierInterface|null $identifier Identifier instance. * @param array $config Configuration settings. */ - public function __construct(?IdentifierInterface $identifier = null, array $config = []) + public function __construct(protected ?IdentifierInterface $identifier = null, array $config = []) { - $this->_identifier = $identifier; $this->setConfig($config); } @@ -66,7 +60,7 @@ public function __construct(?IdentifierInterface $identifier = null, array $conf */ public function getIdentifier(): IdentifierInterface { - if (!$this->_identifier instanceof IdentifierInterface) { + if (!$this->identifier instanceof IdentifierInterface) { throw new MissingIdentifierException( sprintf( 'Identifier is required for `%s`. Please provide an identifier instance.', @@ -75,7 +69,7 @@ public function getIdentifier(): IdentifierInterface ); } - return $this->_identifier; + return $this->identifier; } /** @@ -84,9 +78,9 @@ public function getIdentifier(): IdentifierInterface * @param \Authentication\Identifier\IdentifierInterface $identifier IdentifierInterface instance. * @return $this */ - public function setIdentifier(IdentifierInterface $identifier) + public function setIdentifier(IdentifierInterface $identifier): static { - $this->_identifier = $identifier; + $this->identifier = $identifier; return $this; } diff --git a/src/Authenticator/AuthenticationRequiredException.php b/src/Authenticator/AuthenticationRequiredException.php index 78d1aabd..d895887f 100644 --- a/src/Authenticator/AuthenticationRequiredException.php +++ b/src/Authenticator/AuthenticationRequiredException.php @@ -27,13 +27,6 @@ */ class AuthenticationRequiredException extends HttpException { - /** - * @var array|string> - */ - protected array $headers = []; - - protected string $body = ''; - /** * Constructor * @@ -41,11 +34,9 @@ class AuthenticationRequiredException extends HttpException * @param string $body The response body that should be sent in the challenge response. * @param int $code The exception code that will be used as a HTTP status code */ - public function __construct(array $headers, string $body = '', int $code = 401) + public function __construct(protected array $headers, protected string $body = '', int $code = 401) { parent::__construct(__d('authentication', 'Authentication is required to continue'), $code); - $this->headers = $headers; - $this->body = $body; } /** diff --git a/src/Authenticator/AuthenticatorCollection.php b/src/Authenticator/AuthenticatorCollection.php index 461a6600..01c06f19 100644 --- a/src/Authenticator/AuthenticatorCollection.php +++ b/src/Authenticator/AuthenticatorCollection.php @@ -35,7 +35,7 @@ class AuthenticatorCollection extends AbstractCollection * @return \Authentication\Authenticator\AuthenticatorInterface * @throws \RuntimeException */ - protected function _create(object|string $class, string $alias, array $config): AuthenticatorInterface + protected function create(object|string $class, string $alias, array $config): AuthenticatorInterface { if (is_string($class)) { $identifier = null; @@ -55,7 +55,7 @@ protected function _create(object|string $class, string $alias, array $config): * @param string $class Class name to be resolved. * @return class-string<\Authentication\Authenticator\AuthenticatorInterface>|null */ - protected function _resolveClassName(string $class): ?string + protected function resolveClassName(string $class): ?string { /** @var class-string<\Authentication\Authenticator\AuthenticatorInterface>|null */ return App::className($class, 'Authenticator', 'Authenticator'); @@ -67,7 +67,7 @@ protected function _resolveClassName(string $class): ?string * @return void * @throws \RuntimeException */ - protected function _throwMissingClassError(string $class, ?string $plugin): void + protected function throwMissingClassError(string $class, ?string $plugin): void { if ($plugin) { $class = $plugin . '.' . $class; diff --git a/src/Authenticator/CookieAuthenticator.php b/src/Authenticator/CookieAuthenticator.php index 74271071..5a463dcf 100644 --- a/src/Authenticator/CookieAuthenticator.php +++ b/src/Authenticator/CookieAuthenticator.php @@ -49,7 +49,7 @@ class CookieAuthenticator extends AbstractAuthenticator implements PersistenceIn /** * @inheritDoc */ - protected array $_defaultConfig = [ + protected array $defaultConfig = [ 'loginUrl' => null, 'urlChecker' => 'Authentication.Default', 'rememberMeField' => 'remember_me', @@ -94,15 +94,15 @@ class CookieAuthenticator extends AbstractAuthenticator implements PersistenceIn */ public function getIdentifier(): IdentifierInterface { - if (!$this->_identifier instanceof IdentifierInterface) { + if (!$this->identifier instanceof IdentifierInterface) { $identifierConfig = []; if ($this->getConfig('fields')) { $identifierConfig['fields'] = $this->getConfig('fields'); } - $this->_identifier = IdentifierFactory::create('Authentication.Password', $identifierConfig); + $this->identifier = IdentifierFactory::create('Authentication.Password', $identifierConfig); } - return $this->_identifier; + return $this->identifier; } /** @@ -129,11 +129,11 @@ public function authenticate(ServerRequestInterface $request): ResultInterface } if (count($token) === 3) { - return $this->_authenticateToken($token); + return $this->authenticateToken($token); } if (count($token) === 2 && $this->getConfig('legacyTokens')) { - return $this->_authenticateLegacyToken($token); + return $this->authenticateLegacyToken($token); } return new Result(null, Result::FAILURE_CREDENTIALS_INVALID, [ @@ -151,7 +151,7 @@ public function authenticate(ServerRequestInterface $request): ResultInterface * @param array $token The decoded token parts. * @return \Authentication\Authenticator\ResultInterface */ - protected function _authenticateToken(array $token): ResultInterface + protected function authenticateToken(array $token): ResultInterface { [$username, $expires, $tokenHash] = $token; if (!is_string($username) || !is_numeric($expires) || !is_string($tokenHash)) { @@ -177,7 +177,7 @@ protected function _authenticateToken(array $token): ResultInterface $passwordField = $this->getConfig('fields.password'); $plain = $identity[$usernameField] . $identity[$passwordField] . $expires; - if (!hash_equals(hash_hmac('sha256', $plain, $this->_hmacKey()), $tokenHash)) { + if (!hash_equals(hash_hmac('sha256', $plain, $this->hmacKey()), $tokenHash)) { return new Result(null, Result::FAILURE_CREDENTIALS_INVALID, [ 'Cookie token does not match', ]); @@ -198,7 +198,7 @@ protected function _authenticateToken(array $token): ResultInterface * @param array $token The decoded token parts. * @return \Authentication\Authenticator\ResultInterface */ - protected function _authenticateLegacyToken(array $token): ResultInterface + protected function authenticateLegacyToken(array $token): ResultInterface { [$username, $tokenHash] = $token; if (!is_string($username) || !is_string($tokenHash)) { @@ -208,7 +208,7 @@ protected function _authenticateLegacyToken(array $token): ResultInterface } $info = password_get_info($tokenHash); - if ($info['algoName'] === 'unknown' || !$this->_legacyHashWithinLimits($info)) { + if ($info['algoName'] === 'unknown' || !$this->legacyHashWithinLimits($info)) { return new Result(null, Result::FAILURE_CREDENTIALS_INVALID, [ 'Cookie token is invalid.', ]); @@ -220,7 +220,7 @@ protected function _authenticateLegacyToken(array $token): ResultInterface return new Result(null, Result::FAILURE_IDENTITY_NOT_FOUND, $identifier->getErrors()); } - $plain = $this->_createLegacyPlainToken($identity); + $plain = $this->createLegacyPlainToken($identity); if (!$this->getPasswordHasher()->check($plain, $tokenHash)) { return new Result(null, Result::FAILURE_CREDENTIALS_INVALID, [ 'Cookie token does not match', @@ -242,7 +242,7 @@ protected function _authenticateLegacyToken(array $token): ResultInterface * @param array $info Result of password_get_info() for the token hash. * @return bool */ - protected function _legacyHashWithinLimits(array $info): bool + protected function legacyHashWithinLimits(array $info): bool { $limits = $this->getConfig('legacyHashLimits'); $options = $info['options'] ?? []; @@ -267,7 +267,7 @@ protected function _legacyHashWithinLimits(array $info): bool * @param \ArrayAccess|array $identity Identity data. * @return string */ - protected function _createLegacyPlainToken(ArrayAccess|array $identity): string + protected function createLegacyPlainToken(ArrayAccess|array $identity): string { $usernameField = $this->getConfig('fields.username'); $passwordField = $this->getConfig('fields.password'); @@ -304,11 +304,11 @@ protected function _createLegacyPlainToken(ArrayAccess|array $identity): string */ public function getPasswordHasher(): PasswordHasherInterface { - if (!$this->_passwordHasher instanceof PasswordHasherInterface) { - $this->_passwordHasher = PasswordHasherFactory::build($this->getConfig('passwordHasher')); + if (!$this->passwordHasher instanceof PasswordHasherInterface) { + $this->passwordHasher = PasswordHasherFactory::build($this->getConfig('passwordHasher')); } - return $this->_passwordHasher; + return $this->passwordHasher; } /** @@ -322,15 +322,15 @@ public function persistIdentity( $field = $this->getConfig('rememberMeField'); $bodyData = $request->getParsedBody(); - if (!$this->_checkUrl($request) || !is_array($bodyData) || empty($bodyData[$field])) { + if (!$this->checkUrl($request) || !is_array($bodyData) || empty($bodyData[$field])) { return [ 'request' => $request, 'response' => $response, ]; } - $value = $this->_createToken($identity); - $cookie = $this->_createCookie($value); + $value = $this->createToken($identity); + $cookie = $this->createCookie($value); return [ 'request' => $request, @@ -348,7 +348,7 @@ public function persistIdentity( * @return string * @throws \JsonException */ - protected function _createToken(ArrayAccess|array $identity): string + protected function createToken(ArrayAccess|array $identity): string { $usernameField = $this->getConfig('fields.username'); $passwordField = $this->getConfig('fields.password'); @@ -359,9 +359,9 @@ protected function _createToken(ArrayAccess|array $identity): string ); } - $expires = $this->_expiryTimestamp(); + $expires = $this->expiryTimestamp(); $plain = $identity[$usernameField] . $identity[$passwordField] . $expires; - $hash = hash_hmac('sha256', $plain, $this->_hmacKey()); + $hash = hash_hmac('sha256', $plain, $this->hmacKey()); return json_encode([$identity[$usernameField], $expires, $hash], JSON_THROW_ON_ERROR); } @@ -375,7 +375,7 @@ protected function _createToken(ArrayAccess|array $identity): string * * @return string */ - protected function _hmacKey(): string + protected function hmacKey(): string { $salt = $this->getConfig('salt'); if (is_string($salt)) { @@ -398,7 +398,7 @@ protected function _hmacKey(): string * * @return int Timestamp the token will expire at. */ - protected function _expiryTimestamp(): int + protected function expiryTimestamp(): int { $expires = $this->getConfig('cookie.expires'); if ($expires instanceof DateTimeInterface) { @@ -422,7 +422,7 @@ protected function _expiryTimestamp(): int */ public function clearIdentity(ServerRequestInterface $request, ResponseInterface $response): array { - $cookie = $this->_createCookie('')->withExpired(); + $cookie = $this->createCookie('')->withExpired(); return [ 'request' => $request, @@ -436,7 +436,7 @@ public function clearIdentity(ServerRequestInterface $request, ResponseInterface * @param mixed $value Cookie value. * @return \Cake\Http\Cookie\CookieInterface */ - protected function _createCookie(mixed $value): CookieInterface + protected function createCookie(mixed $value): CookieInterface { $options = $this->getConfig('cookie'); $name = $options['name']; diff --git a/src/Authenticator/EnvironmentAuthenticator.php b/src/Authenticator/EnvironmentAuthenticator.php index 14b4db92..1809bfd6 100644 --- a/src/Authenticator/EnvironmentAuthenticator.php +++ b/src/Authenticator/EnvironmentAuthenticator.php @@ -40,7 +40,7 @@ class EnvironmentAuthenticator extends AbstractAuthenticator * * @var array */ - protected array $_defaultConfig = [ + protected array $defaultConfig = [ 'loginUrl' => null, 'urlChecker' => 'Authentication.Default', 'fields' => [], @@ -68,7 +68,7 @@ public function __construct(?IdentifierInterface $identifier, array $config = [] */ protected function _getData(ServerRequestInterface $request): ?array { - $fields = $this->_config['fields']; + $fields = $this->config['fields']; $params = $request->getServerParams(); $data = []; @@ -96,7 +96,7 @@ protected function _getData(ServerRequestInterface $request): ?array */ protected function _getOptionalData(ServerRequestInterface $request): array { - $fields = $this->_config['optionalFields']; + $fields = $this->config['optionalFields']; $params = $request->getServerParams(); $data = []; @@ -115,7 +115,7 @@ protected function _getOptionalData(ServerRequestInterface $request): array * @param \Psr\Http\Message\ServerRequestInterface $request The request that contains login information. * @return \Authentication\Authenticator\ResultInterface */ - protected function _buildLoginUrlErrorResult(ServerRequestInterface $request): ResultInterface + protected function buildLoginUrlErrorResult(ServerRequestInterface $request): ResultInterface { $uri = $request->getUri(); $base = $request->getAttribute('base'); @@ -152,8 +152,8 @@ protected function _buildLoginUrlErrorResult(ServerRequestInterface $request): R */ public function authenticate(ServerRequestInterface $request): ResultInterface { - if (!$this->_checkUrl($request)) { - return $this->_buildLoginUrlErrorResult($request); + if (!$this->checkUrl($request)) { + return $this->buildLoginUrlErrorResult($request); } $data = $this->_getData($request); if (!$data) { diff --git a/src/Authenticator/FormAuthenticator.php b/src/Authenticator/FormAuthenticator.php index eb0960af..024649cd 100644 --- a/src/Authenticator/FormAuthenticator.php +++ b/src/Authenticator/FormAuthenticator.php @@ -40,7 +40,7 @@ class FormAuthenticator extends AbstractAuthenticator * * @var array */ - protected array $_defaultConfig = [ + protected array $defaultConfig = [ 'loginUrl' => null, 'urlChecker' => null, 'fields' => [ @@ -58,15 +58,15 @@ class FormAuthenticator extends AbstractAuthenticator */ public function getIdentifier(): IdentifierInterface { - if (!$this->_identifier instanceof IdentifierInterface) { + if (!$this->identifier instanceof IdentifierInterface) { $identifierConfig = []; if ($this->getConfig('fields')) { $identifierConfig['fields'] = $this->getConfig('fields'); } - $this->_identifier = IdentifierFactory::create('Authentication.Password', $identifierConfig); + $this->identifier = IdentifierFactory::create('Authentication.Password', $identifierConfig); } - return $this->_identifier; + return $this->identifier; } /** @@ -75,9 +75,9 @@ public function getIdentifier(): IdentifierInterface * @param \Psr\Http\Message\ServerRequestInterface $request The request that contains login information. * @return array|null Username and password retrieved from a request body. */ - protected function _getData(ServerRequestInterface $request): ?array + protected function getData(ServerRequestInterface $request): ?array { - $fields = $this->_config['fields']; + $fields = $this->config['fields']; /** @var array $body */ $body = $request->getParsedBody(); @@ -104,7 +104,7 @@ protected function _getData(ServerRequestInterface $request): ?array * @param \Psr\Http\Message\ServerRequestInterface $request The request that contains login information. * @return \Authentication\Authenticator\ResultInterface */ - protected function _buildLoginUrlErrorResult(ServerRequestInterface $request): ResultInterface + protected function buildLoginUrlErrorResult(ServerRequestInterface $request): ResultInterface { $uri = $request->getUri(); $base = $request->getAttribute('base'); @@ -146,11 +146,11 @@ protected function _buildLoginUrlErrorResult(ServerRequestInterface $request): R */ public function authenticate(ServerRequestInterface $request): ResultInterface { - if (!$this->_checkUrl($request)) { - return $this->_buildLoginUrlErrorResult($request); + if (!$this->checkUrl($request)) { + return $this->buildLoginUrlErrorResult($request); } - $data = $this->_getData($request); + $data = $this->getData($request); if ($data === null) { return new Result(null, Result::FAILURE_CREDENTIALS_MISSING, [ 'Login credentials not found', diff --git a/src/Authenticator/HttpBasicAuthenticator.php b/src/Authenticator/HttpBasicAuthenticator.php index af53cdcf..335930d3 100644 --- a/src/Authenticator/HttpBasicAuthenticator.php +++ b/src/Authenticator/HttpBasicAuthenticator.php @@ -35,7 +35,7 @@ class HttpBasicAuthenticator extends AbstractAuthenticator implements StatelessI * * @var array */ - protected array $_defaultConfig = [ + protected array $defaultConfig = [ 'fields' => [ PasswordIdentifier::CREDENTIAL_USERNAME => 'username', PasswordIdentifier::CREDENTIAL_PASSWORD => 'password', @@ -52,15 +52,15 @@ class HttpBasicAuthenticator extends AbstractAuthenticator implements StatelessI */ public function getIdentifier(): IdentifierInterface { - if (!$this->_identifier instanceof IdentifierInterface) { + if (!$this->identifier instanceof IdentifierInterface) { $identifierConfig = []; if ($this->getConfig('fields')) { $identifierConfig['fields'] = $this->getConfig('fields'); } - $this->_identifier = IdentifierFactory::create('Authentication.Password', $identifierConfig); + $this->identifier = IdentifierFactory::create('Authentication.Password', $identifierConfig); } - return $this->_identifier; + return $this->identifier; } /** diff --git a/src/Authenticator/HttpDigestAuthenticator.php b/src/Authenticator/HttpDigestAuthenticator.php index f70d5328..64899c91 100644 --- a/src/Authenticator/HttpDigestAuthenticator.php +++ b/src/Authenticator/HttpDigestAuthenticator.php @@ -106,13 +106,11 @@ public function authenticate(ServerRequestInterface $request): ResultInterface return new Result(null, Result::FAILURE_CREDENTIALS_INVALID); } - $field = $this->_config['fields'][PasswordIdentifier::CREDENTIAL_PASSWORD]; + $field = $this->config['fields'][PasswordIdentifier::CREDENTIAL_PASSWORD]; $password = $user[$field]; $server = $request->getServerParams(); - if (!isset($server['ORIGINAL_REQUEST_METHOD'])) { - $server['ORIGINAL_REQUEST_METHOD'] = $server['REQUEST_METHOD']; - } + $server['ORIGINAL_REQUEST_METHOD'] ??= $server['REQUEST_METHOD']; $hash = $this->generateResponseHash($digest, $password, $server['ORIGINAL_REQUEST_METHOD']); if (hash_equals($hash, $digest['response'])) { @@ -156,7 +154,8 @@ public function parseAuthData(string $digest): ?array if (str_starts_with($digest, 'Digest ')) { $digest = substr($digest, 7); } - $keys = $match = []; + $keys = []; + $match = []; $req = ['nonce' => 1, 'nc' => 1, 'cnonce' => 1, 'qop' => 1, 'username' => 1, 'uri' => 1, 'response' => 1]; preg_match_all('/(\w+)=([\'"]?)([a-zA-Z0-9\:\#\%\?\&@=\.\/_-]+)\2/', $digest, $match, PREG_SET_ORDER); @@ -165,7 +164,7 @@ public function parseAuthData(string $digest): ?array unset($req[$i[1]]); } - if (!$req) { + if ($req === []) { return $keys; } @@ -211,13 +210,13 @@ public static function password(string $username, string $password, string $real protected function loginHeaders(ServerRequestInterface $request): array { $server = $request->getServerParams(); - $realm = $this->_config['realm'] ?: $server['SERVER_NAME']; + $realm = $this->config['realm'] ?: $server['SERVER_NAME']; $options = [ 'realm' => $realm, - 'qop' => $this->_config['qop'], + 'qop' => $this->config['qop'], 'nonce' => $this->generateNonce(), - 'opaque' => $this->_config['opaque'] ?: md5((string)$realm), + 'opaque' => $this->config['opaque'] ?: md5((string)$realm), ]; $digest = $this->_getDigest($request); diff --git a/src/Authenticator/JwtAuthenticator.php b/src/Authenticator/JwtAuthenticator.php index b96b3f4f..121d2f46 100644 --- a/src/Authenticator/JwtAuthenticator.php +++ b/src/Authenticator/JwtAuthenticator.php @@ -34,7 +34,7 @@ class JwtAuthenticator extends TokenAuthenticator /** * @inheritDoc */ - protected array $_defaultConfig = [ + protected array $defaultConfig = [ 'header' => 'Authorization', 'queryParam' => 'token', 'tokenPrefix' => 'bearer', @@ -57,7 +57,7 @@ public function __construct(?IdentifierInterface $identifier, array $config = [] { parent::__construct($identifier, $config); - if (empty($this->_config['secretKey'])) { + if (empty($this->config['secretKey'])) { if (!class_exists(Security::class)) { throw new RuntimeException('You must set the `secretKey` config key for JWT authentication.'); } @@ -74,7 +74,7 @@ public function __construct(?IdentifierInterface $identifier, array $config = [] */ public function getIdentifier(): IdentifierInterface { - return $this->_identifier ??= IdentifierFactory::create('Authentication.JwtSubject'); + return $this->identifier ??= IdentifierFactory::create('Authentication.JwtSubject'); } /** diff --git a/src/Authenticator/PrimaryKeySessionAuthenticator.php b/src/Authenticator/PrimaryKeySessionAuthenticator.php index 78614ae2..89403148 100644 --- a/src/Authenticator/PrimaryKeySessionAuthenticator.php +++ b/src/Authenticator/PrimaryKeySessionAuthenticator.php @@ -49,7 +49,7 @@ class PrimaryKeySessionAuthenticator extends SessionAuthenticator * * @var array */ - protected array $_defaultConfig = [ + protected array $defaultConfig = [ 'fields' => [], 'sessionKey' => 'Auth', 'impersonateSessionKey' => 'AuthImpersonate', @@ -68,15 +68,15 @@ class PrimaryKeySessionAuthenticator extends SessionAuthenticator */ public function getIdentifier(): IdentifierInterface { - if (!$this->_identifier instanceof IdentifierInterface) { - $this->_identifier = IdentifierFactory::create([ + if (!$this->identifier instanceof IdentifierInterface) { + $this->identifier = IdentifierFactory::create([ 'className' => 'Authentication.Token', 'tokenField' => $this->getConfig('idField'), 'dataField' => $this->getConfig('identifierKey'), ]); } - return $this->_identifier; + return $this->identifier; } /** diff --git a/src/Authenticator/Result.php b/src/Authenticator/Result.php index 02e029c9..1458e407 100644 --- a/src/Authenticator/Result.php +++ b/src/Authenticator/Result.php @@ -24,40 +24,22 @@ */ class Result implements ResultInterface { - /** - * Authentication result status - */ - protected string $_status; - - /** - * The identity data used in the authentication attempt - */ - protected ArrayAccess|array|null $_data = null; - - /** - * An array of string reasons why the authentication attempt was unsuccessful - * - * If authentication was successful, this should be an empty array. - */ - protected array $_errors = []; - /** * Sets the result status, identity, and failure messages * * @param \ArrayAccess|array|null $data The identity data * @param string $status Status constant equivalent. - * @param array $messages Messages. + * @param array $errors Messages. * @throws \InvalidArgumentException When invalid identity data is passed. */ - public function __construct(ArrayAccess|array|null $data, string $status, array $messages = []) - { + public function __construct( + protected ArrayAccess|array|null $data, + protected string $status, + protected array $errors = [], + ) { if ($status === self::SUCCESS && empty($data)) { throw new InvalidArgumentException('Identity data can not be empty with status success.'); } - - $this->_status = $status; - $this->_data = $data; - $this->_errors = $messages; } /** @@ -67,7 +49,7 @@ public function __construct(ArrayAccess|array|null $data, string $status, array */ public function isValid(): bool { - return $this->_status === ResultInterface::SUCCESS; + return $this->status === ResultInterface::SUCCESS; } /** @@ -77,7 +59,7 @@ public function isValid(): bool */ public function getStatus(): string { - return $this->_status; + return $this->status; } /** @@ -87,7 +69,7 @@ public function getStatus(): string */ public function getData(): ArrayAccess|array|null { - return $this->_data; + return $this->data; } /** @@ -99,6 +81,6 @@ public function getData(): ArrayAccess|array|null */ public function getErrors(): array { - return $this->_errors; + return $this->errors; } } diff --git a/src/Authenticator/SessionAuthenticator.php b/src/Authenticator/SessionAuthenticator.php index 86346f37..a900b647 100644 --- a/src/Authenticator/SessionAuthenticator.php +++ b/src/Authenticator/SessionAuthenticator.php @@ -34,7 +34,7 @@ class SessionAuthenticator extends AbstractAuthenticator implements PersistenceI * * @var array */ - protected array $_defaultConfig = [ + protected array $defaultConfig = [ 'fields' => [], 'sessionKey' => 'Auth', 'impersonateSessionKey' => 'AuthImpersonate', diff --git a/src/Authenticator/TokenAuthenticator.php b/src/Authenticator/TokenAuthenticator.php index b2afbc36..f47fa30c 100644 --- a/src/Authenticator/TokenAuthenticator.php +++ b/src/Authenticator/TokenAuthenticator.php @@ -31,7 +31,7 @@ class TokenAuthenticator extends AbstractAuthenticator implements StatelessInter /** * @inheritDoc */ - protected array $_defaultConfig = [ + protected array $defaultConfig = [ 'header' => null, 'queryParam' => null, 'tokenPrefix' => null, @@ -46,7 +46,7 @@ class TokenAuthenticator extends AbstractAuthenticator implements StatelessInter */ public function getIdentifier(): IdentifierInterface { - return $this->_identifier ??= IdentifierFactory::create('Authentication.Token'); + return $this->identifier ??= IdentifierFactory::create('Authentication.Token'); } /** diff --git a/src/Controller/Component/AuthenticationComponent.php b/src/Controller/Component/AuthenticationComponent.php index 71aec025..816db71a 100644 --- a/src/Controller/Component/AuthenticationComponent.php +++ b/src/Controller/Component/AuthenticationComponent.php @@ -39,14 +39,9 @@ /** * Controller Component for interacting with Authentication. - * - * @implements \Cake\Event\EventDispatcherInterface<\Cake\Controller\Controller> */ class AuthenticationComponent extends Component implements EventDispatcherInterface { - /** - * @use \Cake\Event\EventDispatcherTrait<\Cake\Controller\Controller> - */ use EventDispatcherTrait; /** @@ -60,7 +55,7 @@ class AuthenticationComponent extends Component implements EventDispatcherInterf * * @var array */ - protected array $_defaultConfig = [ + protected array $defaultConfig = [ 'logoutRedirect' => false, 'requireIdentity' => true, 'identityAttribute' => 'identity', @@ -78,7 +73,7 @@ class AuthenticationComponent extends Component implements EventDispatcherInterf /** * Authentication service instance. */ - protected ?AuthenticationServiceInterface $_authentication = null; + protected ?AuthenticationServiceInterface $authentication = null; /** * Initialize component. @@ -141,8 +136,8 @@ public function startup(): void */ public function getAuthenticationService(): AuthenticationServiceInterface { - if ($this->_authentication instanceof AuthenticationServiceInterface) { - return $this->_authentication; + if ($this->authentication instanceof AuthenticationServiceInterface) { + return $this->authentication; } $controller = $this->getController(); @@ -158,7 +153,7 @@ public function getAuthenticationService(): AuthenticationServiceInterface throw new Exception('Authentication service does not implement ' . AuthenticationServiceInterface::class); } - $this->_authentication = $service; + $this->authentication = $service; return $service; } @@ -210,7 +205,7 @@ public function disableIdentityCheck(): void * @param array $actions The action list. * @return $this */ - public function allowUnauthenticated(array $actions) + public function allowUnauthenticated(array $actions): static { $this->unauthenticatedActions = $actions; @@ -223,7 +218,7 @@ public function allowUnauthenticated(array $actions) * @param array $actions The action or actions to append. * @return $this */ - public function addUnauthenticatedActions(array $actions) + public function addUnauthenticatedActions(array $actions): static { $this->unauthenticatedActions = array_merge($this->unauthenticatedActions, $actions); $this->unauthenticatedActions = array_values(array_unique($this->unauthenticatedActions)); @@ -302,7 +297,7 @@ public function getIdentityData(string $path): mixed * @param \ArrayAccess|array $identity Identity data to persist. * @return $this */ - public function setIdentity(ArrayAccess|array $identity) + public function setIdentity(ArrayAccess|array $identity): static { $controller = $this->getController(); $service = $this->getAuthenticationService(); @@ -337,7 +332,7 @@ public function setIdentity(ArrayAccess|array $identity) * @param \ArrayAccess|array $identity Identity data or an identity object. * @return $this */ - public function replaceIdentity(ArrayAccess|array $identity) + public function replaceIdentity(ArrayAccess|array $identity): static { $controller = $this->getController(); $service = $this->getAuthenticationService(); @@ -442,7 +437,7 @@ public function implementedEvents(): array * @throws \Exception * @see https://book.cakephp.org/authentication/3/en/impersonation.html */ - public function impersonate(ArrayAccess $impersonated) + public function impersonate(ArrayAccess $impersonated): static { $service = $this->getImpersonationAuthenticationService(); @@ -480,7 +475,7 @@ public function impersonate(ArrayAccess $impersonated) * @throws \Exception * @see https://book.cakephp.org/authentication/3/en/impersonation.html */ - public function stopImpersonating() + public function stopImpersonating(): static { $service = $this->getImpersonationAuthenticationService(); diff --git a/src/Identifier/AbstractIdentifier.php b/src/Identifier/AbstractIdentifier.php index dccdb4bb..b2f71caa 100644 --- a/src/Identifier/AbstractIdentifier.php +++ b/src/Identifier/AbstractIdentifier.php @@ -27,14 +27,14 @@ abstract class AbstractIdentifier implements IdentifierInterface * * @var array */ - protected array $_defaultConfig = []; + protected array $defaultConfig = []; /** * Errors * * @var array */ - protected array $_errors = []; + protected array $errors = []; /** * Constructor @@ -53,6 +53,6 @@ public function __construct(array $config = []) */ public function getErrors(): array { - return $this->_errors; + return $this->errors; } } diff --git a/src/Identifier/CallbackIdentifier.php b/src/Identifier/CallbackIdentifier.php index d795696e..fe418f88 100644 --- a/src/Identifier/CallbackIdentifier.php +++ b/src/Identifier/CallbackIdentifier.php @@ -31,7 +31,7 @@ class CallbackIdentifier extends AbstractIdentifier * * @var array */ - protected array $_defaultConfig = [ + protected array $defaultConfig = [ 'callback' => null, ]; @@ -72,7 +72,7 @@ public function identify(array $credentials): ArrayAccess|array|null $result = $callback($credentials); if ($result instanceof Result) { - $this->_errors = $result->getErrors(); + $this->errors = $result->getErrors(); return $result->getData(); } diff --git a/src/Identifier/JwtSubjectIdentifier.php b/src/Identifier/JwtSubjectIdentifier.php index 96e32794..365a83d2 100644 --- a/src/Identifier/JwtSubjectIdentifier.php +++ b/src/Identifier/JwtSubjectIdentifier.php @@ -31,7 +31,7 @@ class JwtSubjectIdentifier extends TokenIdentifier * * @var array */ - protected array $_defaultConfig = [ + protected array $defaultConfig = [ 'tokenField' => 'id', 'dataField' => self::CREDENTIAL_JWT_SUBJECT, 'resolver' => 'Authentication.Orm', diff --git a/src/Identifier/Ldap/ExtensionAdapter.php b/src/Identifier/Ldap/ExtensionAdapter.php index 963f86a7..b88a2989 100644 --- a/src/Identifier/Ldap/ExtensionAdapter.php +++ b/src/Identifier/Ldap/ExtensionAdapter.php @@ -33,7 +33,7 @@ class ExtensionAdapter implements AdapterInterface /** * LDAP Object */ - protected ?Connection $_connection = null; + protected ?Connection $connection = null; /** * Constructor @@ -60,9 +60,9 @@ public function __construct() */ public function bind(string $bind, string $password): bool { - $this->_setErrorHandler(); + $this->setErrorHandler(); $result = ldap_bind($this->getConnection(), $bind, $password); - $this->_unsetErrorHandler(); + $this->unsetErrorHandler(); return $result; } @@ -75,11 +75,11 @@ public function bind(string $bind, string $password): bool */ public function getConnection(): Connection { - if (!$this->_connection instanceof Connection) { + if (!$this->connection instanceof Connection) { throw new RuntimeException('You are not connected to a LDAP server.'); } - return $this->_connection; + return $this->connection; } /** @@ -92,7 +92,7 @@ public function getConnection(): Connection */ public function connect(string $host, int $port, array $options): void { - $this->_setErrorHandler(); + $this->setErrorHandler(); $resource = ldap_connect(sprintf('%s:%d', $host, $port)); if ($resource === false) { throw new RuntimeException('Unable to connect to LDAP server.'); @@ -102,8 +102,8 @@ public function connect(string $host, int $port, array $options): void throw new RuntimeException('Starting TLS failed on connection to LDAP server.'); } unset($options['tls']); //don't pass through to PHP LDAP functions - $this->_connection = $resource; - $this->_unsetErrorHandler(); + $this->connection = $resource; + $this->unsetErrorHandler(); foreach ($options as $option => $value) { $this->setOption((int)$option, $value); @@ -119,9 +119,9 @@ public function connect(string $host, int $port, array $options): void */ public function setOption(int $option, mixed $value): void { - $this->_setErrorHandler(); + $this->setErrorHandler(); ldap_set_option($this->getConnection(), $option, $value); - $this->_unsetErrorHandler(); + $this->unsetErrorHandler(); } /** @@ -132,9 +132,9 @@ public function setOption(int $option, mixed $value): void */ public function getOption(int $option): mixed { - $this->_setErrorHandler(); + $this->setErrorHandler(); ldap_get_option($this->getConnection(), $option, $returnValue); - $this->_unsetErrorHandler(); + $this->unsetErrorHandler(); return $returnValue; } @@ -156,16 +156,16 @@ public function getDiagnosticMessage(): ?string */ public function unbind(): void { - if (!$this->_connection instanceof Connection) { + if (!$this->connection instanceof Connection) { return; } - $this->_setErrorHandler(); + $this->setErrorHandler(); /** @phpstan-ignore-next-line */ - ldap_unbind($this->_connection); - $this->_unsetErrorHandler(); + ldap_unbind($this->connection); + $this->unsetErrorHandler(); - $this->_connection = null; + $this->connection = null; } /** @@ -174,7 +174,7 @@ public function unbind(): void * @return void * @throws \ErrorException */ - protected function _setErrorHandler(): void + protected function setErrorHandler(): void { set_error_handler( function ($errorNumber, $errorText): void { @@ -189,7 +189,7 @@ function ($errorNumber, $errorText): void { * * @return void */ - protected function _unsetErrorHandler(): void + protected function unsetErrorHandler(): void { restore_error_handler(); } diff --git a/src/Identifier/LdapIdentifier.php b/src/Identifier/LdapIdentifier.php index 5ae3a19d..856c5575 100644 --- a/src/Identifier/LdapIdentifier.php +++ b/src/Identifier/LdapIdentifier.php @@ -55,7 +55,7 @@ class LdapIdentifier extends AbstractIdentifier * * @var array */ - protected array $_defaultConfig = [ + protected array $defaultConfig = [ 'ldap' => ExtensionAdapter::class, 'fields' => [ self::CREDENTIAL_USERNAME => 'username', @@ -72,12 +72,12 @@ class LdapIdentifier extends AbstractIdentifier * * @var array */ - protected array $_errors = []; + protected array $errors = []; /** * LDAP connection object */ - protected AdapterInterface $_ldap; + protected AdapterInterface $ldap; /** * @inheritDoc @@ -86,8 +86,8 @@ public function __construct(array $config = []) { parent::__construct($config); - $this->_checkLdapConfig(); - $this->_buildLdapObject(); + $this->checkLdapConfig(); + $this->buildLdapObject(); } /** @@ -97,18 +97,18 @@ public function __construct(array $config = []) * @throws \InvalidArgumentException * @return void */ - protected function _checkLdapConfig(): void + protected function checkLdapConfig(): void { - if (!isset($this->_config['bindDN'])) { + if (!isset($this->config['bindDN'])) { throw new RuntimeException('Config `bindDN` is not set.'); } - if (!is_callable($this->_config['bindDN'])) { + if (!is_callable($this->config['bindDN'])) { throw new InvalidArgumentException(sprintf( 'The `bindDN` config is not a callable. Got `%s` instead.', - gettype($this->_config['bindDN']), + gettype($this->config['bindDN']), )); } - if (!isset($this->_config['host'])) { + if (!isset($this->config['host'])) { throw new RuntimeException('Config `host` is not set.'); } } @@ -119,9 +119,9 @@ protected function _checkLdapConfig(): void * @throws \RuntimeException * @return void */ - protected function _buildLdapObject(): void + protected function buildLdapObject(): void { - $ldap = $this->_config['ldap']; + $ldap = $this->config['ldap']; if (is_string($ldap)) { $class = App::className($ldap, 'Identifier/Ldap'); @@ -139,7 +139,7 @@ protected function _buildLdapObject(): void throw new RuntimeException($message); } - $this->_ldap = $ldap; + $this->ldap = $ldap; } /** @@ -147,13 +147,13 @@ protected function _buildLdapObject(): void */ public function identify(array $credentials): ArrayAccess|array|null { - $this->_connectLdap(); + $this->connectLdap(); $fields = $this->getConfig('fields'); $isUsernameSet = isset($credentials[$fields[self::CREDENTIAL_USERNAME]]); $isPasswordSet = isset($credentials[$fields[self::CREDENTIAL_PASSWORD]]); if ($isUsernameSet && $isPasswordSet) { - return $this->_bindUser( + return $this->bindUser( $credentials[$fields[self::CREDENTIAL_USERNAME]], $credentials[$fields[self::CREDENTIAL_PASSWORD]], ); @@ -169,7 +169,7 @@ public function identify(array $credentials): ArrayAccess|array|null */ public function getAdapter(): AdapterInterface { - return $this->_ldap; + return $this->ldap; } /** @@ -177,11 +177,11 @@ public function getAdapter(): AdapterInterface * * @return void */ - protected function _connectLdap(): void + protected function connectLdap(): void { $config = $this->getConfig(); - $this->_ldap->connect( + $this->ldap->connect( $config['host'], $config['port'], (array)$this->getConfig('options'), @@ -195,22 +195,22 @@ protected function _connectLdap(): void * @param string $password The password * @return \ArrayAccess|null */ - protected function _bindUser(string $username, string $password): ?ArrayAccess + protected function bindUser(string $username, string $password): ?ArrayAccess { $config = $this->getConfig(); try { - $ldapBind = $this->_ldap->bind($config['bindDN']($username), $password); + $ldapBind = $this->ldap->bind($config['bindDN']($username), $password); if ($ldapBind) { - $this->_ldap->unbind(); + $this->ldap->unbind(); return new ArrayObject([ $config['fields'][self::CREDENTIAL_USERNAME] => $username, ]); } } catch (ErrorException $e) { - $this->_handleLdapError($e->getMessage()); + $this->handleLdapError($e->getMessage()); } - $this->_ldap->unbind(); + $this->ldap->unbind(); return null; } @@ -221,12 +221,12 @@ protected function _bindUser(string $username, string $password): ?ArrayAccess * @param string $message Exception message * @return void */ - protected function _handleLdapError(string $message): void + protected function handleLdapError(string $message): void { - $extendedError = $this->_ldap->getDiagnosticMessage(); + $extendedError = $this->ldap->getDiagnosticMessage(); if (!is_null($extendedError)) { - $this->_errors[] = $extendedError; + $this->errors[] = $extendedError; } - $this->_errors[] = $message; + $this->errors[] = $message; } } diff --git a/src/Identifier/PasswordIdentifier.php b/src/Identifier/PasswordIdentifier.php index 9bbe3c7f..56431aa3 100644 --- a/src/Identifier/PasswordIdentifier.php +++ b/src/Identifier/PasswordIdentifier.php @@ -63,7 +63,7 @@ class PasswordIdentifier extends AbstractIdentifier * * @var array */ - protected array $_defaultConfig = [ + protected array $defaultConfig = [ 'fields' => [ self::CREDENTIAL_USERNAME => 'username', self::CREDENTIAL_PASSWORD => 'password', @@ -79,17 +79,17 @@ class PasswordIdentifier extends AbstractIdentifier */ public function getPasswordHasher(): PasswordHasherInterface { - if (!$this->_passwordHasher instanceof PasswordHasherInterface) { + if (!$this->passwordHasher instanceof PasswordHasherInterface) { $passwordHasher = $this->getConfig('passwordHasher'); if ($passwordHasher !== null) { $passwordHasher = PasswordHasherFactory::build($passwordHasher); } else { $passwordHasher = $this->_getPasswordHasher(); } - $this->_passwordHasher = $passwordHasher; + $this->passwordHasher = $passwordHasher; } - return $this->_passwordHasher; + return $this->passwordHasher; } /** @@ -101,10 +101,10 @@ public function identify(array $credentials): ArrayAccess|array|null return null; } - $identity = $this->_findIdentity($credentials[self::CREDENTIAL_USERNAME]); + $identity = $this->findIdentity($credentials[self::CREDENTIAL_USERNAME]); if (array_key_exists(self::CREDENTIAL_PASSWORD, $credentials)) { $password = $credentials[self::CREDENTIAL_PASSWORD]; - if (!$this->_checkPassword($identity, $password)) { + if (!$this->checkPassword($identity, $password)) { return null; } } @@ -121,15 +121,13 @@ public function identify(array $credentials): ArrayAccess|array|null * @param string|null $password The password. * @return bool */ - protected function _checkPassword(ArrayAccess|array|null $identity, ?string $password): bool + protected function checkPassword(ArrayAccess|array|null $identity, ?string $password): bool { $passwordField = $this->getConfig('fields.' . self::CREDENTIAL_PASSWORD); - if ($identity === null) { - $identity = [ - $passwordField => '', - ]; - } + $identity ??= [ + $passwordField => '', + ]; $hasher = $this->getPasswordHasher(); $hashedPassword = $identity[$passwordField]; @@ -140,7 +138,7 @@ protected function _checkPassword(ArrayAccess|array|null $identity, ?string $pas return false; } - $this->_needsPasswordRehash = $hasher->needsRehash($hashedPassword); + $this->needsPasswordRehash = $hasher->needsRehash($hashedPassword); return true; } @@ -151,7 +149,7 @@ protected function _checkPassword(ArrayAccess|array|null $identity, ?string $pas * @param string $identifier The username/identifier. * @return \ArrayAccess|array|null */ - protected function _findIdentity(string $identifier): ArrayAccess|array|null + protected function findIdentity(string $identifier): ArrayAccess|array|null { $fields = $this->getConfig('fields.' . self::CREDENTIAL_USERNAME); $conditions = []; diff --git a/src/Identifier/Resolver/OrmResolver.php b/src/Identifier/Resolver/OrmResolver.php index 5baad800..3a46b36f 100644 --- a/src/Identifier/Resolver/OrmResolver.php +++ b/src/Identifier/Resolver/OrmResolver.php @@ -35,7 +35,7 @@ class OrmResolver implements ResolverInterface * * @var array */ - protected array $_defaultConfig = [ + protected array $defaultConfig = [ 'userModel' => 'Users', 'finder' => 'all', ]; @@ -55,10 +55,10 @@ public function __construct(array $config = []) */ public function find(array $conditions, string $type = self::TYPE_AND): ArrayAccess|array|null { - $table = $this->getTableLocator()->get($this->_config['userModel']); + $table = $this->getTableLocator()->get($this->config['userModel']); $query = $table->selectQuery(); - $finders = (array)$this->_config['finder']; + $finders = (array)$this->config['finder']; foreach ($finders as $finder => $options) { if (is_string($options)) { $query->find($options); diff --git a/src/Identifier/Resolver/ResolverAwareTrait.php b/src/Identifier/Resolver/ResolverAwareTrait.php index 89e5e634..b29bce6c 100644 --- a/src/Identifier/Resolver/ResolverAwareTrait.php +++ b/src/Identifier/Resolver/ResolverAwareTrait.php @@ -53,7 +53,7 @@ public function getResolver(): ResolverInterface * @param \Authentication\Identifier\Resolver\ResolverInterface $resolver Resolver instance. * @return $this */ - public function setResolver(ResolverInterface $resolver) + public function setResolver(ResolverInterface $resolver): static { $this->resolver = $resolver; diff --git a/src/Identifier/TokenIdentifier.php b/src/Identifier/TokenIdentifier.php index 47ed1d68..4500d2d5 100644 --- a/src/Identifier/TokenIdentifier.php +++ b/src/Identifier/TokenIdentifier.php @@ -34,7 +34,7 @@ class TokenIdentifier extends AbstractIdentifier * * @var array */ - protected array $_defaultConfig = [ + protected array $defaultConfig = [ 'tokenField' => 'token', 'dataField' => self::CREDENTIAL_TOKEN, 'resolver' => 'Authentication.Orm', diff --git a/src/Identity.php b/src/Identity.php index 1ea1c47c..25f16429 100644 --- a/src/Identity.php +++ b/src/Identity.php @@ -33,29 +33,21 @@ class Identity implements IdentityInterface * * - `fieldMap` Mapping of fields */ - protected array $_defaultConfig = [ + protected array $defaultConfig = [ 'fieldMap' => [ 'id' => 'id', ], ]; - /** - * Identity data - * - * @var \ArrayAccess|array - */ - protected ArrayAccess|array $data; - /** * Constructor * * @param \ArrayAccess|array $data Identity data * @param array $config Config options */ - public function __construct(ArrayAccess|array $data, array $config = []) + public function __construct(protected ArrayAccess|array $data, array $config = []) { $this->setConfig($config); - $this->data = $data; } /** @@ -104,7 +96,7 @@ public function get(?string $field = null): mixed return $this->data; } - $map = $this->_config['fieldMap']; + $map = $this->config['fieldMap']; if (isset($map[$field])) { $field = $map[$field]; } @@ -179,7 +171,7 @@ public function getOriginalData(): ArrayAccess|array public function __debugInfo(): array { return [ - 'config' => $this->_config, + 'config' => $this->config, 'data' => $this->data, ]; } diff --git a/src/Middleware/AuthenticationMiddleware.php b/src/Middleware/AuthenticationMiddleware.php index 46d1870f..6c3f51d8 100644 --- a/src/Middleware/AuthenticationMiddleware.php +++ b/src/Middleware/AuthenticationMiddleware.php @@ -23,8 +23,8 @@ use Authentication\Authenticator\AuthenticatorInterface; use Authentication\Authenticator\StatelessInterface; use Authentication\Authenticator\UnauthenticatedException; +use Cake\Container\ContainerInterface; use Cake\Core\ContainerApplicationInterface; -use Cake\Core\ContainerInterface; use Laminas\Diactoros\Response; use Laminas\Diactoros\Response\RedirectResponse; use Laminas\Diactoros\Stream; @@ -38,28 +38,16 @@ */ class AuthenticationMiddleware implements MiddlewareInterface { - /** - * Authentication service or application instance. - */ - protected AuthenticationServiceInterface|AuthenticationServiceProviderInterface $subject; - - /** - * The container instance from the application - */ - protected ?ContainerInterface $container; - /** * Constructor * * @param \Authentication\AuthenticationServiceInterface|\Authentication\AuthenticationServiceProviderInterface $subject Authentication service or application instance. - * @param \Cake\Core\ContainerInterface|null $container The container instance from the application. + * @param \Cake\Container\ContainerInterface|null $container The container instance from the application. */ public function __construct( - AuthenticationServiceInterface|AuthenticationServiceProviderInterface $subject, - ?ContainerInterface $container = null, + protected AuthenticationServiceInterface|AuthenticationServiceProviderInterface $subject, + protected ?ContainerInterface $container = null, ) { - $this->subject = $subject; - $this->container = $container; } /** @@ -76,7 +64,7 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface if ($this->subject instanceof ContainerApplicationInterface) { $container = $this->subject->getContainer(); $container->add(AuthenticationService::class, $service); - } elseif ($this->container) { + } elseif ($this->container instanceof ContainerInterface) { $this->container->add(AuthenticationService::class, $service); } @@ -103,7 +91,11 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface $response = $handler->handle($request); $authenticator = $service->getAuthenticationProvider(); - if ($authenticator instanceof AuthenticatorInterface && !$authenticator instanceof StatelessInterface && $result->getData()) { + if ( + $authenticator instanceof AuthenticatorInterface + && !$authenticator instanceof StatelessInterface + && $result->getData() + ) { $return = $service->persistIdentity($request, $response, $result->getData()); $response = $return['response']; } diff --git a/src/PasswordHasher/AbstractPasswordHasher.php b/src/PasswordHasher/AbstractPasswordHasher.php index 4dd4272b..83e232e0 100644 --- a/src/PasswordHasher/AbstractPasswordHasher.php +++ b/src/PasswordHasher/AbstractPasswordHasher.php @@ -29,7 +29,7 @@ abstract class AbstractPasswordHasher implements PasswordHasherInterface * * These are merged with user-provided config when the object is used. */ - protected array $_defaultConfig = []; + protected array $defaultConfig = []; /** * Constructor diff --git a/src/PasswordHasher/DefaultPasswordHasher.php b/src/PasswordHasher/DefaultPasswordHasher.php index 973d2233..0a2da68f 100644 --- a/src/PasswordHasher/DefaultPasswordHasher.php +++ b/src/PasswordHasher/DefaultPasswordHasher.php @@ -30,7 +30,7 @@ class DefaultPasswordHasher extends AbstractPasswordHasher * - `hashOptions` - Associative array of options. Check the PHP manual for * supported options for each hash type. Defaults to empty array. */ - protected array $_defaultConfig = [ + protected array $defaultConfig = [ 'hashType' => PASSWORD_DEFAULT, 'hashOptions' => [], ]; @@ -45,8 +45,8 @@ public function hash(string $password): string { return password_hash( $password, - $this->_config['hashType'], - $this->_config['hashOptions'], + $this->config['hashType'], + $this->config['hashOptions'], ); } @@ -71,6 +71,6 @@ public function check(string $password, string $hashedPassword): bool */ public function needsRehash(string $password): bool { - return password_needs_rehash($password, $this->_config['hashType'], $this->_config['hashOptions']); + return password_needs_rehash($password, $this->config['hashType'], $this->config['hashOptions']); } } diff --git a/src/PasswordHasher/FallbackPasswordHasher.php b/src/PasswordHasher/FallbackPasswordHasher.php index dbfd4d6d..afc671ed 100644 --- a/src/PasswordHasher/FallbackPasswordHasher.php +++ b/src/PasswordHasher/FallbackPasswordHasher.php @@ -25,14 +25,14 @@ class FallbackPasswordHasher extends AbstractPasswordHasher /** * Default config for this object. */ - protected array $_defaultConfig = [ + protected array $defaultConfig = [ 'hashers' => [], ]; /** * Holds the list of password hasher objects that will be used */ - protected array $_hashers = []; + protected array $hashers = []; /** * Constructor @@ -44,11 +44,11 @@ class FallbackPasswordHasher extends AbstractPasswordHasher public function __construct(array $config = []) { parent::__construct($config); - foreach ($this->_config['hashers'] as $key => $hasher) { + foreach ($this->config['hashers'] as $key => $hasher) { if (is_array($hasher) && !isset($hasher['className'])) { $hasher['className'] = $key; } - $this->_hashers[] = PasswordHasherFactory::build($hasher); + $this->hashers[] = PasswordHasherFactory::build($hasher); } } @@ -62,7 +62,7 @@ public function __construct(array $config = []) */ public function hash(string $password): string { - return $this->_hashers[0]->hash($password); + return $this->hashers[0]->hash($password); } /** @@ -77,13 +77,7 @@ public function hash(string $password): string */ public function check(string $password, string $hashedPassword): bool { - foreach ($this->_hashers as $hasher) { - if ($hasher->check($password, $hashedPassword)) { - return true; - } - } - - return false; + return array_any($this->hashers, fn($hasher) => $hasher->check($password, $hashedPassword)); } /** @@ -95,6 +89,6 @@ public function check(string $password, string $hashedPassword): bool */ public function needsRehash(string $password): bool { - return $this->_hashers[0]->needsRehash($password); + return $this->hashers[0]->needsRehash($password); } } diff --git a/src/PasswordHasher/LegacyPasswordHasher.php b/src/PasswordHasher/LegacyPasswordHasher.php index 718d713c..e655228b 100644 --- a/src/PasswordHasher/LegacyPasswordHasher.php +++ b/src/PasswordHasher/LegacyPasswordHasher.php @@ -32,7 +32,7 @@ class LegacyPasswordHasher extends AbstractPasswordHasher * - `hashType` String identifier of the hash type to use on the password. (e.g 'sha256' or 'md5') * - `salt` Boolean flag for salting the password in a hash, or check. */ - protected array $_defaultConfig = [ + protected array $defaultConfig = [ 'hashType' => null, 'salt' => true, ]; @@ -59,7 +59,7 @@ public function __construct(array $config = []) */ public function hash(string $password): string { - return Security::hash($password, $this->_config['hashType'], $this->_config['salt']); + return Security::hash($password, $this->config['hashType'], $this->config['salt']); } /** diff --git a/src/PasswordHasher/PasswordHasherTrait.php b/src/PasswordHasher/PasswordHasherTrait.php index b62b703d..53ffbe75 100644 --- a/src/PasswordHasher/PasswordHasherTrait.php +++ b/src/PasswordHasher/PasswordHasherTrait.php @@ -8,13 +8,13 @@ trait PasswordHasherTrait /** * Password hasher instance. */ - protected ?PasswordHasherInterface $_passwordHasher = null; + protected ?PasswordHasherInterface $passwordHasher = null; /** * Whether the user authenticated by this class * requires their password to be rehashed with another algorithm. */ - protected bool $_needsPasswordRehash = false; + protected bool $needsPasswordRehash = false; /** * Return password hasher object. @@ -24,11 +24,9 @@ trait PasswordHasherTrait */ public function getPasswordHasher(): PasswordHasherInterface { - if ($this->_passwordHasher === null) { - $this->_passwordHasher = new DefaultPasswordHasher(); - } + $this->passwordHasher ??= new DefaultPasswordHasher(); - return $this->_passwordHasher; + return $this->passwordHasher; } /** @@ -37,9 +35,9 @@ public function getPasswordHasher(): PasswordHasherInterface * @param \Authentication\PasswordHasher\PasswordHasherInterface $passwordHasher Password hasher instance. * @return $this */ - public function setPasswordHasher(PasswordHasherInterface $passwordHasher) + public function setPasswordHasher(PasswordHasherInterface $passwordHasher): static { - $this->_passwordHasher = $passwordHasher; + $this->passwordHasher = $passwordHasher; return $this; } @@ -52,6 +50,6 @@ public function setPasswordHasher(PasswordHasherInterface $passwordHasher) */ public function needsPasswordRehash(): bool { - return $this->_needsPasswordRehash; + return $this->needsPasswordRehash; } } diff --git a/src/UrlChecker/DefaultUrlChecker.php b/src/UrlChecker/DefaultUrlChecker.php index 97e7dec9..ad5ecbb3 100644 --- a/src/UrlChecker/DefaultUrlChecker.php +++ b/src/UrlChecker/DefaultUrlChecker.php @@ -31,7 +31,7 @@ class DefaultUrlChecker implements UrlCheckerInterface * * @var array */ - protected array $_defaultOptions = [ + protected array $defaultOptions = [ 'checkFullUrl' => false, ]; @@ -40,8 +40,8 @@ class DefaultUrlChecker implements UrlCheckerInterface */ public function check(ServerRequestInterface $request, array|string $loginUrls, array $options = []): bool { - $options = $this->_mergeDefaultOptions($options); - $url = $this->_getUrlFromRequest($request, $options['checkFullUrl']); + $options = $this->mergeDefaultOptions($options); + $url = $this->getUrlFromRequest($request, $options['checkFullUrl']); // Support both string URLs and array-based routes (like Router::url()) $validUrl = Router::url($loginUrls, $options['checkFullUrl']); @@ -55,9 +55,9 @@ public function check(ServerRequestInterface $request, array|string $loginUrls, * @param array $options Options to merge in * @return array */ - protected function _mergeDefaultOptions(array $options): array + protected function mergeDefaultOptions(array $options): array { - return $options + $this->_defaultOptions; + return $options + $this->defaultOptions; } /** @@ -67,7 +67,7 @@ protected function _mergeDefaultOptions(array $options): array * @param bool $getFullUrl Get the full URL or just the path * @return string */ - protected function _getUrlFromRequest(ServerRequestInterface $request, bool $getFullUrl = false): string + protected function getUrlFromRequest(ServerRequestInterface $request, bool $getFullUrl = false): string { $uri = $request->getUri(); diff --git a/src/UrlChecker/MultiUrlChecker.php b/src/UrlChecker/MultiUrlChecker.php index a458f5e6..d2059991 100644 --- a/src/UrlChecker/MultiUrlChecker.php +++ b/src/UrlChecker/MultiUrlChecker.php @@ -34,7 +34,7 @@ class MultiUrlChecker implements UrlCheckerInterface * * @var array */ - protected array $_defaultOptions = [ + protected array $defaultOptions = [ 'useRegex' => false, 'checkFullUrl' => false, ]; @@ -44,22 +44,19 @@ class MultiUrlChecker implements UrlCheckerInterface */ public function check(ServerRequestInterface $request, array|string $loginUrls, array $options = []): bool { - $options = $this->_mergeDefaultOptions($options); + $options = $this->mergeDefaultOptions($options); // For a single URL (string or array route), convert to array - $urls = is_string($loginUrls) || $this->_isSingleRoute($loginUrls) ? [$loginUrls] : $loginUrls; + $urls = is_string($loginUrls) || $this->isSingleRoute($loginUrls) ? [$loginUrls] : $loginUrls; - if (!$urls) { + if ($urls === []) { return true; } - foreach ($urls as $url) { - if ($this->_checkSingleUrl($request, $url, $options)) { - return true; - } - } - - return false; + return array_any( + $urls, + fn($url) => $this->checkSingleUrl($request, $url, $options), + ); } /** @@ -68,13 +65,13 @@ public function check(ServerRequestInterface $request, array|string $loginUrls, * @param array|string $value The value to check * @return bool */ - protected function _isSingleRoute(array|string $value): bool + protected function isSingleRoute(array|string $value): bool { if (!is_array($value)) { return false; } - if (!$value) { + if ($value === []) { return false; } $firstKey = array_key_first($value); @@ -90,7 +87,7 @@ protected function _isSingleRoute(array|string $value): bool * @param array $options Options array. * @return bool */ - protected function _checkSingleUrl(ServerRequestInterface $request, array|string $url, array $options): bool + protected function checkSingleUrl(ServerRequestInterface $request, array|string $url, array $options): bool { $checker = new DefaultUrlChecker(); @@ -103,8 +100,8 @@ protected function _checkSingleUrl(ServerRequestInterface $request, array|string * @param array $options The options to merge. * @return array */ - protected function _mergeDefaultOptions(array $options): array + protected function mergeDefaultOptions(array $options): array { - return $options + $this->_defaultOptions; + return $options + $this->defaultOptions; } } diff --git a/src/UrlChecker/StringUrlChecker.php b/src/UrlChecker/StringUrlChecker.php index 26026c88..3624bbdf 100644 --- a/src/UrlChecker/StringUrlChecker.php +++ b/src/UrlChecker/StringUrlChecker.php @@ -32,7 +32,7 @@ class StringUrlChecker implements UrlCheckerInterface * * @var array */ - protected array $_defaultOptions = [ + protected array $defaultOptions = [ 'useRegex' => false, 'checkFullUrl' => false, ]; @@ -48,9 +48,9 @@ public function check(ServerRequestInterface $request, array|string $loginUrls, ); } - $options = $this->_mergeDefaultOptions($options); - $checker = $this->_getChecker($options); - $url = $this->_getUrlFromRequest($request, $options['checkFullUrl']); + $options = $this->mergeDefaultOptions($options); + $checker = $this->getChecker($options); + $url = $this->getUrlFromRequest($request, $options['checkFullUrl']); return (bool)$checker($loginUrls, $url); } @@ -65,9 +65,9 @@ public function check(ServerRequestInterface $request, array|string $loginUrls, * @param array $options Options to merge in * @return array */ - protected function _mergeDefaultOptions(array $options): array + protected function mergeDefaultOptions(array $options): array { - return $options + $this->_defaultOptions; + return $options + $this->defaultOptions; } /** @@ -76,7 +76,7 @@ protected function _mergeDefaultOptions(array $options): array * @param array $options Array of options * @return callable */ - protected function _getChecker(array $options): callable + protected function getChecker(array $options): callable { if (!empty($options['useRegex'])) { return 'preg_match'; @@ -94,7 +94,7 @@ protected function _getChecker(array $options): callable * @param bool $getFullUrl Get the full URL or just the path * @return string */ - protected function _getUrlFromRequest(ServerRequestInterface $request, bool $getFullUrl = false): string + protected function getUrlFromRequest(ServerRequestInterface $request, bool $getFullUrl = false): string { $uri = $request->getUri(); diff --git a/src/UrlChecker/UrlCheckerTrait.php b/src/UrlChecker/UrlCheckerTrait.php index d6d6758f..f4b888cb 100644 --- a/src/UrlChecker/UrlCheckerTrait.php +++ b/src/UrlChecker/UrlCheckerTrait.php @@ -31,7 +31,7 @@ trait UrlCheckerTrait * @param \Psr\Http\Message\ServerRequestInterface $request The request that contains login information. * @return bool */ - protected function _checkUrl(ServerRequestInterface $request): bool + protected function checkUrl(ServerRequestInterface $request): bool { $loginUrl = $this->getConfig('loginUrl'); if ($loginUrl === null) { diff --git a/src/View/Helper/IdentityHelper.php b/src/View/Helper/IdentityHelper.php index 89f8ca05..f5829e8d 100644 --- a/src/View/Helper/IdentityHelper.php +++ b/src/View/Helper/IdentityHelper.php @@ -33,14 +33,14 @@ class IdentityHelper extends Helper * * @var array */ - protected array $_defaultConfig = [ + protected array $defaultConfig = [ 'identityAttribute' => 'identity', ]; /** * Identity Object */ - protected ?IdentityInterface $_identity = null; + protected ?IdentityInterface $identity = null; /** * Constructor hook method. @@ -52,7 +52,7 @@ class IdentityHelper extends Helper */ public function initialize(array $config): void { - $this->_identity = $this->_View->getRequest()->getAttribute($this->getConfig('identityAttribute')); + $this->identity = $this->View->getRequest()->getAttribute($this->getConfig('identityAttribute')); } /** @@ -62,11 +62,11 @@ public function initialize(array $config): void */ public function getId(): array|string|int|null { - if (!$this->_identity instanceof IdentityInterface) { + if (!$this->identity instanceof IdentityInterface) { return null; } - return $this->_identity->getIdentifier(); + return $this->identity->getIdentifier(); } /** @@ -76,7 +76,7 @@ public function getId(): array|string|int|null */ public function isLoggedIn(): bool { - return $this->_identity instanceof IdentityInterface; + return $this->identity instanceof IdentityInterface; } /** @@ -112,15 +112,15 @@ public function is(int|string $id, string $field = 'id'): bool */ public function get(?string $key = null): mixed { - if (!$this->_identity instanceof IdentityInterface) { + if (!$this->identity instanceof IdentityInterface) { return null; } if ($key === null) { - return $this->_identity->getOriginalData(); + return $this->identity->getOriginalData(); } - return Hash::get($this->_identity, $key); + return Hash::get($this->identity, $key); } /** @@ -130,6 +130,6 @@ public function get(?string $key = null): mixed */ public function getIdentity(): ?IdentityInterface { - return $this->_identity; + return $this->identity; } } diff --git a/tests/TestCase/AuthenticationTestCase.php b/tests/TestCase/AuthenticationTestCase.php index d383548a..7c56de49 100644 --- a/tests/TestCase/AuthenticationTestCase.php +++ b/tests/TestCase/AuthenticationTestCase.php @@ -36,7 +36,7 @@ class AuthenticationTestCase extends TestCase protected function setUp(): void { parent::setUp(); - $this->_setupUsersAndPasswords(); + $this->setupUsersAndPasswords(); } /** @@ -44,7 +44,7 @@ protected function setUp(): void * * @return void */ - protected function _setupUsersAndPasswords() + protected function setupUsersAndPasswords() { $password = password_hash('password', PASSWORD_DEFAULT); TableRegistry::getTableLocator()->clear(); diff --git a/tests/TestCase/Authenticator/PrimaryKeySessionAuthenticatorTest.php b/tests/TestCase/Authenticator/PrimaryKeySessionAuthenticatorTest.php index bbade753..1a5a6552 100644 --- a/tests/TestCase/Authenticator/PrimaryKeySessionAuthenticatorTest.php +++ b/tests/TestCase/Authenticator/PrimaryKeySessionAuthenticatorTest.php @@ -27,6 +27,7 @@ use Cake\Http\ServerRequestFactory; use Cake\Http\Session; use Cake\TestSuite\TestCase; +use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations; use PHPUnit\Framework\MockObject\MockObject; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; @@ -115,6 +116,7 @@ public function testAuthenticateSuccessWithDefaultIdentifier(): void * * @return void */ + #[AllowMockObjectsWithoutExpectations] public function testGetIdentifierReturnsDefaultWhenNotConfigured(): void { $authenticator = new PrimaryKeySessionAuthenticator(); @@ -130,6 +132,7 @@ public function testGetIdentifierReturnsDefaultWhenNotConfigured(): void * * @return void */ + #[AllowMockObjectsWithoutExpectations] public function testGetIdentifierUsesCustomConfig(): void { $authenticator = new PrimaryKeySessionAuthenticator(null, [ diff --git a/tests/TestCase/Identifier/Resolver/ResolverAwareTraitTest.php b/tests/TestCase/Identifier/Resolver/ResolverAwareTraitTest.php index b83b65dc..24bb0406 100644 --- a/tests/TestCase/Identifier/Resolver/ResolverAwareTraitTest.php +++ b/tests/TestCase/Identifier/Resolver/ResolverAwareTraitTest.php @@ -112,7 +112,7 @@ public function testGetResolverNotSet(): void $object = new class { use ResolverAwareTrait; - public function getConfig() + public function getConfig(): null { return null; } diff --git a/tests/TestCase/Middleware/AuthenticationMiddlewareTest.php b/tests/TestCase/Middleware/AuthenticationMiddlewareTest.php index 60426fe7..95daf9f0 100644 --- a/tests/TestCase/Middleware/AuthenticationMiddlewareTest.php +++ b/tests/TestCase/Middleware/AuthenticationMiddlewareTest.php @@ -24,7 +24,7 @@ use Authentication\IdentityInterface; use Authentication\Middleware\AuthenticationMiddleware; use Authentication\Test\TestCase\AuthenticationTestCase as TestCase; -use Cake\Core\Container; +use Cake\Container\Container; use Cake\Core\TestSuite\ContainerStubTrait; use Cake\Http\Response; use Cake\Http\ServerRequestFactory; diff --git a/tests/TestCase/View/Helper/IdentityHelperTest.php b/tests/TestCase/View/Helper/IdentityHelperTest.php index 584336d3..1ce07cc5 100644 --- a/tests/TestCase/View/Helper/IdentityHelperTest.php +++ b/tests/TestCase/View/Helper/IdentityHelperTest.php @@ -41,7 +41,7 @@ public function testWithIdentity(): void 'first_name' => 'cake', ], ]); - $request = (new ServerRequest())->withAttribute('identity', $identity); + $request = new ServerRequest()->withAttribute('identity', $identity); $view = new View($request); $helper = new IdentityHelper($view); @@ -65,7 +65,7 @@ public function testIdentityWithCustomAttribute(): void 'first_name' => 'cake', ], ]); - $request = (new ServerRequest())->withAttribute('customIdentity', $identity); + $request = new ServerRequest()->withAttribute('customIdentity', $identity); $view = new View($request); $helper = new IdentityHelper($view, ['identityAttribute' => 'customIdentity']); @@ -99,7 +99,7 @@ public function testGetIdentity(): void $identity = new Identity([ 'id' => 1, ]); - $request = (new ServerRequest())->withAttribute('identity', $identity); + $request = new ServerRequest()->withAttribute('identity', $identity); $view = new View($request); $helper = new IdentityHelper($view);