From 13478aca61eb01664ed6ff2af9b754f10f6e0a36 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Dec 2022 01:41:12 +0000 Subject: [PATCH 01/18] Bump actions/stale from 6 to 7 Bumps [actions/stale](https://github.com/actions/stale) from 6 to 7. - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/stale dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index e5b390e0..184cf51b 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/stale@v6 + - uses: actions/stale@v7 with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-issue-message: 'This issue is stale because it has been open for 120 days with no activity. Remove the `stale` label or comment or this will be closed in 15 days' From 2d68b10f71d50781d2b04dadef0a7c4cdbe71f2c Mon Sep 17 00:00:00 2001 From: yosus <5551430+yosus@users.noreply.github.com> Date: Tue, 3 Jan 2023 21:18:57 +0800 Subject: [PATCH 02/18] Added link to Users table structure Needed an explanation of how the Users database table structure is. --- docs/en/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/index.rst b/docs/en/index.rst index cae7209a..175f3012 100644 --- a/docs/en/index.rst +++ b/docs/en/index.rst @@ -149,7 +149,7 @@ Building a Login Action ======================= Once you have the middleware applied to your application you'll need a way for -users to login. 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 :doc:`tutorial `. First generate a Users model and controller with bake: .. code-block:: shell From c326c9060b5a126e45e741e15428ae065d6ce4c1 Mon Sep 17 00:00:00 2001 From: Michael Hoffmann Date: Sat, 4 Feb 2023 23:24:24 +0100 Subject: [PATCH 03/18] Add missing links to sidebar and further reading --- docs/en/contents.rst | 1 + docs/en/index.rst | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/en/contents.rst b/docs/en/contents.rst index e53aa89d..5d45c6b8 100644 --- a/docs/en/contents.rst +++ b/docs/en/contents.rst @@ -13,6 +13,7 @@ Contents /middleware /authentication-component /testing + /impersonation /url-checkers /view-helper /migration-from-the-authcomponent diff --git a/docs/en/index.rst b/docs/en/index.rst index 175f3012..bd01e184 100644 --- a/docs/en/index.rst +++ b/docs/en/index.rst @@ -244,6 +244,7 @@ Further Reading * :doc:`/identifiers` * :doc:`/password-hashers` * :doc:`/identity-object` +* :doc:`/middleware` * :doc:`/authentication-component` * :doc:`/impersonation` * :doc:`/url-checkers` From 76ef0d0fc93cc6b69f6ca7810f0e963f1278b0a9 Mon Sep 17 00:00:00 2001 From: Kevin Pfeifer Date: Sun, 5 Feb 2023 19:44:14 +0100 Subject: [PATCH 04/18] fix impersonation version info in docs --- docs/en/impersonation.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/impersonation.rst b/docs/en/impersonation.rst index da2c081f..55dabf39 100644 --- a/docs/en/impersonation.rst +++ b/docs/en/impersonation.rst @@ -1,7 +1,7 @@ User Impersonation ################## -.. versionadded:: 3.0.0 +.. versionadded:: 2.10.0 User impersonation was added. After deploying your application, you may occasionally need to @@ -15,7 +15,7 @@ To impersonate another user you can use the ``impersonate()`` method on the ``AuthenticationComponent``. To impersonate a user you first need to load that user from your application's database:: - // In a controller + // In a controller public function impersonate() { $this->request->allowMethod(['POST']); From cdbef94ef889427b44d260945bf17ea795d4cc53 Mon Sep 17 00:00:00 2001 From: Luiz Marin <67489841+luizcmarin@users.noreply.github.com> Date: Fri, 3 Mar 2023 15:11:29 -0300 Subject: [PATCH 05/18] Update index.rst With "php composer.phar require "cakephp/authentication:^2.0"" result... "Your requirements could not be resolved to an installable set of packages. Problem 1 - zendframework/zend-diactoros[2.0.0, ..., 2.2.1] require php ^7.1 -> your php version (8.2.3) does not satisfy that requirement. - cakephp/authentication 2.0.0 requires zendframework/zend-diactoros ^2.0 -> satisfiable by zendframework/zend-diactoros[2.0.0, ..., 2.2.1]. - Root composer.json requires cakephp/authentication 2.0 -> satisfiable by cakephp/authentication[2.0.0]." BUT, with the change continues the installation without problems. (*Cakephp 4.4.11, windows 10, php 8.2.3) --- docs/en/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/index.rst b/docs/en/index.rst index bd01e184..aeb2d20f 100644 --- a/docs/en/index.rst +++ b/docs/en/index.rst @@ -6,7 +6,7 @@ Project's ROOT directory (where the **composer.json** file is located) .. code-block:: bash - php composer.phar require "cakephp/authentication:^2.0" + php composer.phar require cakephp/authentication Version 2 of the Authentication Plugin is compatible with CakePHP 4. From e23f6b66fe208827534c8cc26ce53fa5cdc357c8 Mon Sep 17 00:00:00 2001 From: Kevin Pfeifer Date: Mon, 13 Mar 2023 16:45:56 +0100 Subject: [PATCH 06/18] add example on how to mimic Auth->deny --- docs/en/migration-from-the-authcomponent.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/en/migration-from-the-authcomponent.rst b/docs/en/migration-from-the-authcomponent.rst index 28c5426a..26b6276b 100644 --- a/docs/en/migration-from-the-authcomponent.rst +++ b/docs/en/migration-from-the-authcomponent.rst @@ -238,6 +238,13 @@ present:: Each call to ``allowUnauthenticated()`` will overwrite the current action list. +To mimic ``$this->Auth->deny(['register']);`` you can do:: + + $action = $this->getRequest()->getParam('action'); + if ($action !== 'register') { + $this->Authentication->allowUnauthenticated([$action]); + } + Migrating Unauthenticated Redirects =================================== From efb0f069259a290690e25c17e88e5d7fefddc112 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Tue, 14 Mar 2023 22:47:59 -0400 Subject: [PATCH 07/18] Store only the original data in the impersonation session Identity objects could contain closures by fetching the original data we can serialize into the session more consistently. It also ensures that when we next build an identity that a new decorator is created. Fixes #606 --- src/Controller/Component/AuthenticationComponent.php | 2 +- .../Controller/Component/AuthenticationComponentTest.php | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Controller/Component/AuthenticationComponent.php b/src/Controller/Component/AuthenticationComponent.php index 9f7bf7f8..3bb2b8f7 100644 --- a/src/Controller/Component/AuthenticationComponent.php +++ b/src/Controller/Component/AuthenticationComponent.php @@ -373,7 +373,7 @@ public function impersonate(ArrayAccess $impersonated) $result = $service->impersonate( $controller->getRequest(), $controller->getResponse(), - $identity, + $identity->getOriginalData(), $impersonated ); diff --git a/tests/TestCase/Controller/Component/AuthenticationComponentTest.php b/tests/TestCase/Controller/Component/AuthenticationComponentTest.php index 4134a5ac..85f545d5 100644 --- a/tests/TestCase/Controller/Component/AuthenticationComponentTest.php +++ b/tests/TestCase/Controller/Component/AuthenticationComponentTest.php @@ -565,11 +565,16 @@ public function testImpersonate() $controller = new Controller($request, $this->response); $registry = new ComponentRegistry($controller); $component = new AuthenticationComponent($registry); + $this->assertEquals($impersonator, $controller->getRequest()->getSession()->read('Auth')); $this->assertNull($controller->getRequest()->getSession()->read('AuthImpersonate')); + $component->impersonate($impersonated); $this->assertEquals($impersonated, $controller->getRequest()->getSession()->read('Auth')); - $this->assertEquals($identity, $controller->getRequest()->getSession()->read('AuthImpersonate')); + $this->assertEquals($impersonator, $controller->getRequest()->getSession()->read('AuthImpersonate')); + + $component->stopImpersonating(); + $this->assertNull($controller->getRequest()->getSession()->read('AuthImpersonate')); } /** From 6fc5c4566945da1416b615bd74a1523804984d15 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Tue, 14 Mar 2023 23:31:35 -0400 Subject: [PATCH 08/18] Address complaints from psalm --- src/Controller/Component/AuthenticationComponent.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Controller/Component/AuthenticationComponent.php b/src/Controller/Component/AuthenticationComponent.php index 3bb2b8f7..2c2ffc71 100644 --- a/src/Controller/Component/AuthenticationComponent.php +++ b/src/Controller/Component/AuthenticationComponent.php @@ -368,12 +368,16 @@ public function impersonate(ArrayAccess $impersonated) if (!$identity) { throw new UnauthenticatedException('You must be logged in before impersonating a user.'); } + $impersonator = $identity->getOriginalData(); + if (!($impersonator instanceof ArrayAccess)) { + $impersonator = new ArrayAccess($impersonator); + } $controller = $this->getController(); /** @psalm-var array{request: \Cake\Http\ServerRequest, response: \Cake\Http\Response} $result */ $result = $service->impersonate( $controller->getRequest(), $controller->getResponse(), - $identity->getOriginalData(), + $impersonator, $impersonated ); From 43d33a0c2ffbd25539c9e24a0a746265dab4318f Mon Sep 17 00:00:00 2001 From: Mark Story Date: Wed, 15 Mar 2023 10:59:15 -0400 Subject: [PATCH 09/18] Fix interface construction --- src/Controller/Component/AuthenticationComponent.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Controller/Component/AuthenticationComponent.php b/src/Controller/Component/AuthenticationComponent.php index 2c2ffc71..25b7c5fb 100644 --- a/src/Controller/Component/AuthenticationComponent.php +++ b/src/Controller/Component/AuthenticationComponent.php @@ -17,6 +17,7 @@ namespace Authentication\Controller\Component; use ArrayAccess; +use ArrayObject; use Authentication\AuthenticationServiceInterface; use Authentication\Authenticator\ImpersonationInterface; use Authentication\Authenticator\PersistenceInterface; @@ -370,7 +371,7 @@ public function impersonate(ArrayAccess $impersonated) } $impersonator = $identity->getOriginalData(); if (!($impersonator instanceof ArrayAccess)) { - $impersonator = new ArrayAccess($impersonator); + $impersonator = new ArrayObject($impersonator); } $controller = $this->getController(); /** @psalm-var array{request: \Cake\Http\ServerRequest, response: \Cake\Http\Response} $result */ From 4b5cc235d740a8b8b9a4d349a33d44b14363a2a2 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Fri, 17 Mar 2023 11:02:22 -0400 Subject: [PATCH 10/18] Increase coverage. --- .../Component/AuthenticationComponentTest.php | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tests/TestCase/Controller/Component/AuthenticationComponentTest.php b/tests/TestCase/Controller/Component/AuthenticationComponentTest.php index 85f545d5..231ebf66 100644 --- a/tests/TestCase/Controller/Component/AuthenticationComponentTest.php +++ b/tests/TestCase/Controller/Component/AuthenticationComponentTest.php @@ -577,6 +577,37 @@ public function testImpersonate() $this->assertNull($controller->getRequest()->getSession()->read('AuthImpersonate')); } + /** + * test that impersonate() can handle identities with array data within them. + * + * @return void + */ + public function testImpersonateDecoratorIgnored() + { + $impersonator = ['username' => 'mariano']; + $impersonated = new ArrayObject(['username' => 'larry']); + + $this->request->getSession()->write('Auth', $impersonator); + $this->service->authenticate($this->request); + $identity = new Identity($impersonator); + $request = $this->request + ->withAttribute('identity', $identity) + ->withAttribute('authentication', $this->service); + $controller = new Controller($request, $this->response); + $registry = new ComponentRegistry($controller); + $component = new AuthenticationComponent($registry); + + $this->assertEquals($impersonator, $controller->getRequest()->getSession()->read('Auth')); + $this->assertNull($controller->getRequest()->getSession()->read('AuthImpersonate')); + + $component->impersonate($impersonated); + $this->assertEquals($impersonated, $controller->getRequest()->getSession()->read('Auth')); + $this->assertEquals(new ArrayObject($impersonator), $controller->getRequest()->getSession()->read('AuthImpersonate')); + + $component->stopImpersonating(); + $this->assertNull($controller->getRequest()->getSession()->read('AuthImpersonate')); + } + /** * testImpersonateNoIdentity * From 9aebb2ddd956d67cafe1cdcd391a47337e6876da Mon Sep 17 00:00:00 2001 From: Kevin Pfeifer Date: Tue, 25 Apr 2023 18:45:45 +0200 Subject: [PATCH 11/18] fix tests --- tests/TestCase/Authenticator/CookieAuthenticatorTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/TestCase/Authenticator/CookieAuthenticatorTest.php b/tests/TestCase/Authenticator/CookieAuthenticatorTest.php index f4746bd1..a4c27267 100644 --- a/tests/TestCase/Authenticator/CookieAuthenticatorTest.php +++ b/tests/TestCase/Authenticator/CookieAuthenticatorTest.php @@ -403,6 +403,8 @@ public function testClearIdentity() $this->assertInstanceOf(RequestInterface::class, $result['request']); $this->assertInstanceOf(ResponseInterface::class, $result['response']); - $this->assertSame('CookieAuth=; expires=Thu, 01-Jan-1970 00:00:01 UTC; path=/', $result['response']->getHeaderLine('Set-Cookie')); + $cookieHeader = $result['response']->getHeaderLine('Set-Cookie'); + $this->assertStringContainsString('CookieAuth=; expires=Thu, 01-Jan-1970 00:00:01', $cookieHeader); + $this->assertStringContainsString('; path=/', $cookieHeader); } } From fc84fac86f2f7706fd3d73b2335b600fba81e244 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Apr 2023 16:55:47 +0000 Subject: [PATCH 12/18] Bump actions/stale from 7 to 8 Bumps [actions/stale](https://github.com/actions/stale) from 7 to 8. - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/v7...v8) --- updated-dependencies: - dependency-name: actions/stale dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 184cf51b..bbcdd0b3 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/stale@v7 + - uses: actions/stale@v8 with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-issue-message: 'This issue is stale because it has been open for 120 days with no activity. Remove the `stale` label or comment or this will be closed in 15 days' From 1a00fd8cb9cd6f0727c03a4a3d19cb794e574e22 Mon Sep 17 00:00:00 2001 From: Kevin Pfeifer Date: Sat, 29 Apr 2023 22:56:57 +0200 Subject: [PATCH 13/18] fix tests --- src/Middleware/AuthenticationMiddleware.php | 1 + tests/TestCase/Authenticator/HttpDigestAuthenticatorTest.php | 1 + tests/bootstrap.php | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Middleware/AuthenticationMiddleware.php b/src/Middleware/AuthenticationMiddleware.php index b924877d..4ed0d39f 100644 --- a/src/Middleware/AuthenticationMiddleware.php +++ b/src/Middleware/AuthenticationMiddleware.php @@ -31,6 +31,7 @@ use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; use RuntimeException; +use function Cake\Core\deprecationWarning; /** * Authentication Middleware diff --git a/tests/TestCase/Authenticator/HttpDigestAuthenticatorTest.php b/tests/TestCase/Authenticator/HttpDigestAuthenticatorTest.php index 06f2c8c1..738ac3b8 100644 --- a/tests/TestCase/Authenticator/HttpDigestAuthenticatorTest.php +++ b/tests/TestCase/Authenticator/HttpDigestAuthenticatorTest.php @@ -27,6 +27,7 @@ use Cake\ORM\TableRegistry; use Cake\TestSuite\TestCase; use PHPUnit\Framework\Constraint\RegularExpression; +use function Cake\Core\env; /** * Test case for HttpDigestAuthentication diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 4f3d06b1..1232baba 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -21,6 +21,7 @@ use Cake\Routing\Router; use Cake\TestSuite\Fixture\SchemaLoader; use Cake\Utility\Security; +use function Cake\Core\env; $findRoot = function ($root) { do { @@ -36,7 +37,6 @@ unset($findRoot); chdir($root); -require_once 'vendor/cakephp/cakephp/src/basics.php'; require_once 'vendor/autoload.php'; define('ROOT', $root . DS . 'tests' . DS . 'test_app' . DS); From 75935c9ebd5baef78262e78dc02d1293b4457587 Mon Sep 17 00:00:00 2001 From: Kevin Pfeifer Date: Sat, 29 Apr 2023 23:03:08 +0200 Subject: [PATCH 14/18] fix CS --- src/Authenticator/CookieAuthenticator.php | 1 + src/UrlChecker/DefaultUrlChecker.php | 2 +- .../HttpDigestAuthenticatorTest.php | 2 +- .../Identifier/IdentifierCollectionTest.php | 2 +- .../AuthenticationMiddlewareTest.php | 30 ++++++------------- .../FallbackPasswordHasherTest.php | 1 - .../PasswordHasherFactoryTest.php | 4 +-- 7 files changed, 15 insertions(+), 27 deletions(-) diff --git a/src/Authenticator/CookieAuthenticator.php b/src/Authenticator/CookieAuthenticator.php index 6fdafa28..b6c29d27 100644 --- a/src/Authenticator/CookieAuthenticator.php +++ b/src/Authenticator/CookieAuthenticator.php @@ -28,6 +28,7 @@ use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use RuntimeException; +use function Cake\Core\deprecationWarning; /** * Cookie Authenticator diff --git a/src/UrlChecker/DefaultUrlChecker.php b/src/UrlChecker/DefaultUrlChecker.php index 4f22cd1a..bd156c36 100644 --- a/src/UrlChecker/DefaultUrlChecker.php +++ b/src/UrlChecker/DefaultUrlChecker.php @@ -74,7 +74,7 @@ public function check(ServerRequestInterface $request, $loginUrls, array $option */ protected function _mergeDefaultOptions(array $options): array { - return $options += $this->_defaultOptions; + return $options + $this->_defaultOptions; } /** diff --git a/tests/TestCase/Authenticator/HttpDigestAuthenticatorTest.php b/tests/TestCase/Authenticator/HttpDigestAuthenticatorTest.php index 738ac3b8..c04a81d9 100644 --- a/tests/TestCase/Authenticator/HttpDigestAuthenticatorTest.php +++ b/tests/TestCase/Authenticator/HttpDigestAuthenticatorTest.php @@ -301,7 +301,7 @@ public function testUnauthorizedFailReChallenge() { $this->auth->setConfig('scope.username', 'nate'); - $nonce = $this->generateNonce(); + $this->generateNonce(); $digest = <<assertInstanceOf('\ArrayAccess', $result); $this->assertInstanceOf(PasswordIdentifier::class, $collection->getIdentificationProvider()); - $result = $collection->identify([ + $collection->identify([ 'username' => 'mariano', 'password' => 'invalid password', ]); diff --git a/tests/TestCase/Middleware/AuthenticationMiddlewareTest.php b/tests/TestCase/Middleware/AuthenticationMiddlewareTest.php index e6e5883a..87651cca 100644 --- a/tests/TestCase/Middleware/AuthenticationMiddlewareTest.php +++ b/tests/TestCase/Middleware/AuthenticationMiddlewareTest.php @@ -67,7 +67,7 @@ public function testApplicationAuthentication() $handler = new TestRequestHandler(); $middleware = new AuthenticationMiddleware($this->application); - $response = $middleware->process($request, $handler); + $middleware->process($request, $handler); /** @var AuthenticationService $service */ $service = $handler->request->getAttribute('authentication'); @@ -92,7 +92,7 @@ public function testProviderAuthentication() ->willReturn($this->service); $middleware = new AuthenticationMiddleware($provider); - $response = $middleware->process($request, $handler); + $middleware->process($request, $handler); /** @var AuthenticationService $service */ $service = $handler->request->getAttribute('authentication'); @@ -239,7 +239,7 @@ public function testSuccessfulAuthenticationWithCustomIdentityAttribute() ]); $middleware = new AuthenticationMiddleware($this->service); - $response = $middleware->process($request, $handler); + $middleware->process($request, $handler); $identity = $handler->request->getAttribute('customIdentity'); $service = $handler->request->getAttribute('authentication'); @@ -264,7 +264,7 @@ public function testSuccessfulAuthenticationApplicationHook() $middleware = new AuthenticationMiddleware($this->application); - $response = $middleware->process($request, $handler); + $middleware->process($request, $handler); $identity = $handler->request->getAttribute('identity'); $service = $handler->request->getAttribute('authentication'); @@ -297,7 +297,7 @@ public function testSuccessfulAuthenticationPersistIdentity() $middleware = new AuthenticationMiddleware($this->service); $handler = new TestRequestHandler(function ($request) { - $service = $request->getAttribute('authentication'); + $request->getAttribute('authentication'); $this->assertNull($request->getAttribute('session')->read('Auth')); return new Response(); @@ -326,7 +326,7 @@ public function testNonSuccessfulAuthentication() $middleware = new AuthenticationMiddleware($this->service); - $response = $middleware->process($request, $handler); + $middleware->process($request, $handler); $identity = $handler->request->getAttribute('identity'); $service = $handler->request->getAttribute('authentication'); @@ -414,7 +414,7 @@ public function testUnauthenticatedNoRedirect() throw new UnauthenticatedException(); }); $middleware = new AuthenticationMiddleware($this->service); - $response = $middleware->process($request, $handler); + $middleware->process($request, $handler); } /** @@ -486,10 +486,6 @@ public function testUnauthenticatedRedirectWithQueryBackwardsCompatible() throw new UnauthenticatedException(); }); - $next = function ($request, $response) { - throw new UnauthenticatedException(); - }; - $this->service->setConfig([ 'unauthenticatedRedirect' => '/users/login', 'queryParam' => 'redirect', @@ -605,10 +601,6 @@ public function testUnauthenticatedRedirectWithQueryStringData() [], ['username' => 'mariano', 'password' => 'password'] ); - $response = new Response(); - $next = function ($request, $response) { - throw new UnauthenticatedException(); - }; $this->service->setConfig([ 'unauthenticatedRedirect' => '/users/login', @@ -662,7 +654,7 @@ public function testJwtTokenAuthorizationThroughTheMiddlewareStack() $handler = new TestRequestHandler(); $middleware = new AuthenticationMiddleware($this->service); - $response = $middleware->process($request, $handler); + $middleware->process($request, $handler); $identity = $handler->request->getAttribute('identity'); $service = $handler->request->getAttribute('authentication'); @@ -735,18 +727,14 @@ public function testServiceConfigurationFallback() 'password' => 'password', ] ); - $response = new Response(); $middleware = new AuthenticationMiddleware($service, [ 'identityAttribute' => 'user', 'unauthenticatedRedirect' => '/login', 'queryParam' => 'redirect', ]); - $next = function ($request, $response) { - return $response; - }; $this->deprecated(function () use ($request, $middleware) { $handler = new TestRequestHandler(); - $response = $middleware->process($request, $handler); + $middleware->process($request, $handler); }); $this->assertSame('user', $service->getConfig('identityAttribute')); $this->assertSame('redirect', $service->getConfig('queryParam')); diff --git a/tests/TestCase/PasswordHasher/FallbackPasswordHasherTest.php b/tests/TestCase/PasswordHasher/FallbackPasswordHasherTest.php index bb8a575a..61a78840 100644 --- a/tests/TestCase/PasswordHasher/FallbackPasswordHasherTest.php +++ b/tests/TestCase/PasswordHasher/FallbackPasswordHasherTest.php @@ -36,7 +36,6 @@ public function testHash() $legacy = new LegacyPasswordHasher(); $this->assertSame($legacy->hash('foo'), $hasher->hash('foo')); - $simple = new DefaultPasswordHasher(); $hasher = new FallbackPasswordHasher(['hashers' => ['Authentication.Legacy', 'Authentication.Default']]); $this->assertSame($legacy->hash('foo'), $hasher->hash('foo')); } diff --git a/tests/TestCase/PasswordHasher/PasswordHasherFactoryTest.php b/tests/TestCase/PasswordHasher/PasswordHasherFactoryTest.php index ad4a753b..9ac007d9 100644 --- a/tests/TestCase/PasswordHasher/PasswordHasherFactoryTest.php +++ b/tests/TestCase/PasswordHasher/PasswordHasherFactoryTest.php @@ -54,7 +54,7 @@ public function testBuildMissingHasher() { $this->expectException('RuntimeException'); $this->expectExceptionMessage('Password hasher class `FooBar` was not found.'); - $hasher = PasswordHasherFactory::build('FooBar'); + PasswordHasherFactory::build('FooBar'); } /** @@ -66,6 +66,6 @@ public function testBuildInvalidHasher() { $this->expectException('RuntimeException'); $this->expectExceptionMessage('Password hasher must implement PasswordHasherInterface.'); - $hasher = PasswordHasherFactory::build('Invalid'); + PasswordHasherFactory::build('Invalid'); } } From 5c59aaee4eed936736c91a619e3e567e095b1dc3 Mon Sep 17 00:00:00 2001 From: ADmad Date: Sun, 30 Apr 2023 10:43:02 +0530 Subject: [PATCH 15/18] Update finder methods and find() calls. --- src/Identifier/Resolver/OrmResolver.php | 2 +- .../Identifier/Resolver/OrmResolverTest.php | 2 +- .../TestApp/Model/Table/AuthUsersTable.php | 25 +++++++------------ 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/Identifier/Resolver/OrmResolver.php b/src/Identifier/Resolver/OrmResolver.php index a5856fae..7df39e59 100644 --- a/src/Identifier/Resolver/OrmResolver.php +++ b/src/Identifier/Resolver/OrmResolver.php @@ -63,7 +63,7 @@ public function find(array $conditions, $type = self::TYPE_AND): ArrayAccess|arr if (is_string($options)) { $query->find($options); } else { - $query->find($finder, $options); + $query->find($finder, ...$options); } } diff --git a/tests/TestCase/Identifier/Resolver/OrmResolverTest.php b/tests/TestCase/Identifier/Resolver/OrmResolverTest.php index 81ff4290..a9cd0de9 100644 --- a/tests/TestCase/Identifier/Resolver/OrmResolverTest.php +++ b/tests/TestCase/Identifier/Resolver/OrmResolverTest.php @@ -40,7 +40,7 @@ public function testFindConfig() 'userModel' => 'AuthUsers', 'finder' => [ 'all', - 'auth' => ['return_created' => true], + 'auth' => ['returnCreated' => true], ], ]); diff --git a/tests/test_app/TestApp/Model/Table/AuthUsersTable.php b/tests/test_app/TestApp/Model/Table/AuthUsersTable.php index e2d151fa..505c25be 100644 --- a/tests/test_app/TestApp/Model/Table/AuthUsersTable.php +++ b/tests/test_app/TestApp/Model/Table/AuthUsersTable.php @@ -13,7 +13,6 @@ */ namespace TestApp\Model\Table; -use Cake\Core\Exception\Exception; use Cake\ORM\Query\SelectQuery; use Cake\ORM\Table; @@ -26,13 +25,13 @@ class AuthUsersTable extends Table * Custom finder * * @param \Cake\ORM\Query\SelectQuery $query The query to find with - * @param array $options The options to find with - * @return \Cake\ORM\Query The query builder + * @param bool $returnCreated Whether to return 'created' field. + * @return \Cake\ORM\Query\SelectQuery The query builder */ - public function findAuth(SelectQuery $query, array $options) + public function findAuth(SelectQuery $query, bool $returnCreated = false): SelectQuery { $query->select(['id', 'username', 'password']); - if (!empty($options['return_created'])) { + if ($returnCreated) { $query->select(['created']); } @@ -43,19 +42,13 @@ public function findAuth(SelectQuery $query, array $options) * Custom finder * * @param \Cake\ORM\Query\SelectQuery $query The query to find with - * @param array $options The options to find with - * @return \Cake\ORM\Query The query builder + * @param string $username String username + * @return \Cake\ORM\Query\SelectQuery The query builder */ - public function findUsername(SelectQuery $query, array $options) + public function findUsername(SelectQuery $query, string $username): SelectQuery { - if (empty($options['username'])) { - throw new Exception('Username not defined'); - } - - $query = $this->find() - ->where(['username' => $options['username']]) + return $this->find() + ->where(['username' => $username]) ->select(['id', 'username', 'password']); - - return $query; } } From ac2f6498260bd11c2d44bd28b42528f715a628b1 Mon Sep 17 00:00:00 2001 From: ADmad Date: Sun, 30 Apr 2023 10:58:18 +0530 Subject: [PATCH 16/18] Add missing type --- src/Identifier/Resolver/OrmResolver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Identifier/Resolver/OrmResolver.php b/src/Identifier/Resolver/OrmResolver.php index 7df39e59..3e506616 100644 --- a/src/Identifier/Resolver/OrmResolver.php +++ b/src/Identifier/Resolver/OrmResolver.php @@ -53,7 +53,7 @@ public function __construct(array $config = []) /** * @inheritDoc */ - public function find(array $conditions, $type = self::TYPE_AND): ArrayAccess|array|null + public function find(array $conditions, string $type = self::TYPE_AND): ArrayAccess|array|null { $table = $this->getTableLocator()->get($this->_config['userModel']); From b0db63d034bfffe8a5ca8be2e89b9c9f4e0b90a9 Mon Sep 17 00:00:00 2001 From: Kevin Pfeifer Date: Sun, 30 Apr 2023 12:45:29 +0200 Subject: [PATCH 17/18] remove deprecated middleware config --- src/Middleware/AuthenticationMiddleware.php | 46 +------- .../AuthenticationMiddlewareTest.php | 110 +----------------- 2 files changed, 5 insertions(+), 151 deletions(-) diff --git a/src/Middleware/AuthenticationMiddleware.php b/src/Middleware/AuthenticationMiddleware.php index 4ed0d39f..b6049900 100644 --- a/src/Middleware/AuthenticationMiddleware.php +++ b/src/Middleware/AuthenticationMiddleware.php @@ -16,13 +16,11 @@ */ namespace Authentication\Middleware; -use Authentication\AuthenticationService; use Authentication\AuthenticationServiceInterface; use Authentication\AuthenticationServiceProviderInterface; use Authentication\Authenticator\AuthenticationRequiredException; use Authentication\Authenticator\StatelessInterface; use Authentication\Authenticator\UnauthenticatedException; -use Cake\Core\InstanceConfigTrait; use Laminas\Diactoros\Response; use Laminas\Diactoros\Response\RedirectResponse; use Laminas\Diactoros\Stream; @@ -30,31 +28,12 @@ use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; -use RuntimeException; -use function Cake\Core\deprecationWarning; /** * Authentication Middleware */ class AuthenticationMiddleware implements MiddlewareInterface { - use InstanceConfigTrait; - - /** - * Configuration options - * - * The following keys are deprecated and should instead be set on the AuthenticationService - * - * - `identityAttribute` - The request attribute to store the identity in. - * - `unauthenticatedRedirect` - The URL to redirect unauthenticated errors to. See - * AuthenticationComponent::allowUnauthenticated() - * - `queryParam` - The name of the query string parameter containing the previously blocked - * URL in case of unauthenticated redirect, or null to disable appending the denied URL. - * - * @var array - */ - protected array $_defaultConfig = []; - /** * Authentication service or application instance. * @@ -66,15 +45,12 @@ class AuthenticationMiddleware implements MiddlewareInterface * Constructor * * @param \Authentication\AuthenticationServiceInterface|\Authentication\AuthenticationServiceProviderInterface $subject Authentication service or application instance. - * @param array $config Array of configuration settings. * @throws \InvalidArgumentException When invalid subject has been passed. */ public function __construct( - AuthenticationServiceInterface|AuthenticationServiceProviderInterface $subject, - array $config = [] + AuthenticationServiceInterface|AuthenticationServiceProviderInterface $subject ) { $this->subject = $subject; - $this->setConfig($config); } /** @@ -145,26 +121,6 @@ protected function getAuthenticationService(ServerRequestInterface $request): Au $subject = $subject->getAuthenticationService($request); } - $forwardKeys = ['identityAttribute', 'unauthenticatedRedirect', 'queryParam']; - foreach ($forwardKeys as $key) { - $value = $this->getConfig($key); - if ($value) { - deprecationWarning( - '2.x', - "The `{$key}` configuration key on AuthenticationMiddleware is deprecated. " . - "Instead set the `{$key}` on your AuthenticationService instance." - ); - if ($subject instanceof AuthenticationService) { - $subject->setConfig($key, $value); - } else { - throw new RuntimeException( - 'Could not forward configuration to authentication service as ' . - 'it does not implement `getConfig()`' - ); - } - } - } - return $subject; } } diff --git a/tests/TestCase/Middleware/AuthenticationMiddlewareTest.php b/tests/TestCase/Middleware/AuthenticationMiddlewareTest.php index 87651cca..82efd2ee 100644 --- a/tests/TestCase/Middleware/AuthenticationMiddlewareTest.php +++ b/tests/TestCase/Middleware/AuthenticationMiddlewareTest.php @@ -189,37 +189,6 @@ public function testAuthenticationAndClearIdentityInteraction() $this->assertNull($request->getSession()->read('Auth'), 'no more session data.'); } - /** - * test middleware call with custom identity attribute on the middleware - * - * @return void - */ - public function testApplicationAuthenticationCustomIdentityAttributeDeprecatedOption() - { - $request = ServerRequestFactory::fromGlobals( - ['REQUEST_URI' => '/testpath'], - [], - ['username' => 'mariano', 'password' => 'password'] - ); - $handler = new TestRequestHandler(function ($req) { - /** @var \Authentication\AuthenticationService $service */ - $service = $req->getAttribute('authentication'); - $this->assertInstanceOf(AuthenticationService::class, $service); - $this->assertSame('customIdentity', $service->getConfig('identityAttribute')); - $this->assertTrue($service->identifiers()->has('Password')); - $this->assertTrue($service->authenticators()->has('Form')); - - return new Response(); - }); - $this->deprecated(function () use ($request, $handler) { - // Using the middleware option requires this test to use deprecated() - $middleware = new AuthenticationMiddleware($this->application, [ - 'identityAttribute' => 'customIdentity', - ]); - $middleware->process($request, $handler); - }); - } - /** * testSuccessfulAuthentication with custom identity attribute * @@ -386,12 +355,10 @@ public function testUnauthenticatedNoRedirectMiddlewareConfiguration() $this->expectException(UnauthenticatedException::class); $this->expectExceptionCode(401); - $middleware = new AuthenticationMiddleware($this->service, [ - 'unauthenticatedRedirect' => false, - ]); - $this->deprecated(function () use ($middleware, $request, $handler) { - $middleware->process($request, $handler); - }); + $service = $this->service; + $service->setConfig(['unauthenticatedRedirect' => null]); + $middleware = new AuthenticationMiddleware($service); + $middleware->process($request, $handler); } /** @@ -417,33 +384,6 @@ public function testUnauthenticatedNoRedirect() $middleware->process($request, $handler); } - /** - * test unauthenticated errors being converted into redirects when configured - * at the middleware (backwards compat) - * - * @return void - */ - public function testUnauthenticatedRedirectBackwardsCompatibleOption() - { - $request = ServerRequestFactory::fromGlobals( - ['REQUEST_URI' => '/testpath'], - [], - ['username' => 'mariano', 'password' => 'password'] - ); - $handler = new TestRequestHandler(function ($request) { - throw new UnauthenticatedException(); - }); - $middleware = new AuthenticationMiddleware($this->service, [ - 'unauthenticatedRedirect' => '/users/login', - ]); - $this->deprecated(function () use ($middleware, $request, $handler) { - $response = $middleware->process($request, $handler); - $this->assertSame(302, $response->getStatusCode()); - $this->assertSame('/users/login', $response->getHeaderLine('Location')); - $this->assertSame('', $response->getBody() . ''); - }); - } - /** * test unauthenticated errors being converted into redirects when configured * @@ -698,46 +638,4 @@ public function testCookieAuthorizationThroughTheMiddlewareStack() $this->assertStringContainsString('CookieAuth=%5B%22mariano%22', $response->getHeaderLine('Set-Cookie')); } - - /** - * Test that the service will inherit middleware configuration if - * its own configuration isn't set. - * - * @return void - */ - public function testServiceConfigurationFallback() - { - $service = new AuthenticationService([ - 'identifiers' => [ - 'Authentication.Password', - ], - 'authenticators' => [ - 'Authentication.Form', - ], - ]); - $this->assertSame('identity', $service->getConfig('identityAttribute')); - $this->assertNull($service->getConfig('unauthenticatedRedirect')); - $this->assertNull($service->getConfig('queryParam')); - - $request = ServerRequestFactory::fromGlobals( - ['REQUEST_URI' => '/'], - [], - [ - 'username' => 'mariano', - 'password' => 'password', - ] - ); - $middleware = new AuthenticationMiddleware($service, [ - 'identityAttribute' => 'user', - 'unauthenticatedRedirect' => '/login', - 'queryParam' => 'redirect', - ]); - $this->deprecated(function () use ($request, $middleware) { - $handler = new TestRequestHandler(); - $middleware->process($request, $handler); - }); - $this->assertSame('user', $service->getConfig('identityAttribute')); - $this->assertSame('redirect', $service->getConfig('queryParam')); - $this->assertSame('/login', $service->getConfig('unauthenticatedRedirect')); - } } From 254edbee91ec6644eccf1d1d1f5ad2bf92189fa9 Mon Sep 17 00:00:00 2001 From: Kevin Pfeifer Date: Sun, 30 Apr 2023 12:47:17 +0200 Subject: [PATCH 18/18] remove deprecated CookieAuthenticator config key fallbacks --- src/Authenticator/CookieAuthenticator.php | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/Authenticator/CookieAuthenticator.php b/src/Authenticator/CookieAuthenticator.php index b6c29d27..f18f5b33 100644 --- a/src/Authenticator/CookieAuthenticator.php +++ b/src/Authenticator/CookieAuthenticator.php @@ -28,7 +28,6 @@ use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use RuntimeException; -use function Cake\Core\deprecationWarning; /** * Cookie Authenticator @@ -236,23 +235,10 @@ protected function _createCookie(mixed $value): CookieInterface $name = $options['name']; unset($options['name']); - if (array_key_exists('expire', $options)) { - deprecationWarning('2.x', 'Config key `expire` is deprecated, use `expires` instead.'); - $options['expires'] = $options['expire']; - unset($options['expire']); - } - if (array_key_exists('httpOnly', $options)) { - deprecationWarning('2.x', 'Config key `httpOnly` is deprecated, use `httponly` instead.'); - $options['httponly'] = $options['httpOnly']; - unset($options['httpOnly']); - } - - $cookie = Cookie::create( + return Cookie::create( $name, $value, $options ); - - return $cookie; } }