diff --git a/composer-require-checker.json b/composer-require-checker.json index 96393e83..c7a3e18e 100644 --- a/composer-require-checker.json +++ b/composer-require-checker.json @@ -1,5 +1,7 @@ { "symbol-whitelist": [ + "Yiisoft\\Auth\\AuthenticationMethodInterface", + "Yiisoft\\Auth\\IdentityInterface", "opcache_invalidate" ] } diff --git a/composer.json b/composer.json index fb2a4bce..8094b3b1 100644 --- a/composer.json +++ b/composer.json @@ -55,6 +55,7 @@ "roave/infection-static-analysis-plugin": "^1.16", "spatie/phpunit-watcher": "^1.23", "vimeo/psalm": "^4.18", + "yiisoft/auth": "^3.0", "yiisoft/event-dispatcher": "^1.0", "yiisoft/log": "^2.0", "yiisoft/router-fastroute": "^2.0" diff --git a/config/params.php b/config/params.php index 4685330c..893655e2 100644 --- a/config/params.php +++ b/config/params.php @@ -7,12 +7,14 @@ use Psr\Http\Client\ClientInterface; use Psr\Log\LoggerInterface; use Yiisoft\Assets\AssetLoaderInterface; +use Yiisoft\Auth\AuthenticationMethodInterface; use Yiisoft\Cache\CacheInterface; use Yiisoft\Injector\Injector; use Yiisoft\Router\UrlMatcherInterface; use Yiisoft\Validator\ValidatorInterface; use Yiisoft\Yii\Debug\Collector\AssetCollector; use Yiisoft\Yii\Debug\Collector\AssetLoaderInterfaceProxy; +use Yiisoft\Yii\Debug\Collector\AuthenticationMethodInterfaceProxy; use Yiisoft\Yii\Debug\Collector\CommandCollector; use Yiisoft\Yii\Debug\Collector\ConsoleAppInfoCollector; use Yiisoft\Yii\Debug\Collector\ContainerInterfaceProxy; @@ -22,6 +24,7 @@ use Yiisoft\Yii\Debug\Collector\HttpClientCollector; use Yiisoft\Yii\Debug\Collector\HttpClientInterfaceProxy; use Yiisoft\Yii\Debug\Collector\HttpStreamCollector; +use Yiisoft\Yii\Debug\Collector\IdentityCollector; use Yiisoft\Yii\Debug\Collector\LogCollector; use Yiisoft\Yii\Debug\Collector\LoggerInterfaceProxy; use Yiisoft\Yii\Debug\Collector\MiddlewareCollector; @@ -64,6 +67,7 @@ MiddlewareCollector::class, AssetCollector::class, WebViewCollector::class, + IdentityCollector::class, ], 'collectors.console' => [ ConsoleAppInfoCollector::class, @@ -79,6 +83,7 @@ ValidatorInterface::class => [ValidatorInterfaceProxy::class, ValidatorCollector::class], AssetLoaderInterface::class => [AssetLoaderInterfaceProxy::class, AssetCollector::class], ClientInterface::class => [HttpClientInterfaceProxy::class, HttpClientCollector::class], + AuthenticationMethodInterface::class => [AuthenticationMethodInterfaceProxy::class, IdentityCollector::class], CacheInterface::class, ], 'dumper.excludedClasses' => [ diff --git a/src/Collector/AuthenticationMethodInterfaceProxy.php b/src/Collector/AuthenticationMethodInterfaceProxy.php new file mode 100644 index 00000000..36a50487 --- /dev/null +++ b/src/Collector/AuthenticationMethodInterfaceProxy.php @@ -0,0 +1,33 @@ +decorated->authenticate($request); + } finally { + $this->collector->collect($identity); + } + return $identity; + } + + public function challenge(ResponseInterface $response): ResponseInterface + { + return $this->decorated->challenge($response); + } +} diff --git a/src/Collector/IdentityCollector.php b/src/Collector/IdentityCollector.php new file mode 100644 index 00000000..5a7d6b8a --- /dev/null +++ b/src/Collector/IdentityCollector.php @@ -0,0 +1,51 @@ +identities; + } + + public function collect(?IdentityInterface $identity): void + { + if (!$this->isActive()) { + return; + } + + if ($identity === null) { + return; + } + + $this->identities[] = [ + 'id' => $identity->getId(), + 'class' => $identity::class, + ]; + } + + private function reset(): void + { + $this->identities = []; + } + + public function getIndexData(): array + { + $lastIdentity = end($this->identities); + return [ + 'identity' => [ + 'lastId' => is_array($lastIdentity) ? $lastIdentity['id'] : null, + 'total' => count($this->identities), + ], + ]; + } +} diff --git a/tests/Collector/UserCollectorTest.php b/tests/Collector/UserCollectorTest.php new file mode 100644 index 00000000..f678d9fb --- /dev/null +++ b/tests/Collector/UserCollectorTest.php @@ -0,0 +1,51 @@ +collect(null); + $collector->collect(new FakeIdentity('stub1')); + + $collector->collect(null); + $collector->collect(new FakeIdentity('stub2')); + $collector->collect(null); + } + + protected function getCollector(): CollectorInterface + { + return new IdentityCollector(); + } + + protected function checkCollectedData(array $data): void + { + parent::checkCollectedData($data); + + $this->assertCount(2, $data); + $this->assertEquals([ + ['id' => 'stub1', 'class' => FakeIdentity::class], + ['id' => 'stub2', 'class' => FakeIdentity::class], + ], $data); + } + + protected function checkIndexData(array $data): void + { + parent::checkIndexData($data); + + $this->assertArrayHasKey('identity', $data); + $this->assertArrayHasKey('lastId', $data['identity']); + $this->assertEquals('stub2', $data['identity']['lastId']); + $this->assertEquals(2, $data['identity']['total']); + } +} diff --git a/tests/Support/FakeIdentity.php b/tests/Support/FakeIdentity.php new file mode 100644 index 00000000..6b682979 --- /dev/null +++ b/tests/Support/FakeIdentity.php @@ -0,0 +1,19 @@ +id; + } +}