Skip to content

Commit

Permalink
Identities collector (#194)
Browse files Browse the repository at this point in the history
* Add collecting identities

* Apply fixes from StyleCI

* [ci-review] Apply changes from Rector action.

---------

Co-authored-by: StyleCI Bot <bot@styleci.io>
Co-authored-by: rector-bot <rector@yiiframework.com>
  • Loading branch information
3 people committed Feb 16, 2023
1 parent f8dc651 commit 03c53ad
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 0 deletions.
2 changes: 2 additions & 0 deletions composer-require-checker.json
@@ -1,5 +1,7 @@
{
"symbol-whitelist": [
"Yiisoft\\Auth\\AuthenticationMethodInterface",
"Yiisoft\\Auth\\IdentityInterface",
"opcache_invalidate"
]
}
1 change: 1 addition & 0 deletions composer.json
Expand Up @@ -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"
Expand Down
5 changes: 5 additions & 0 deletions config/params.php
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -64,6 +67,7 @@
MiddlewareCollector::class,
AssetCollector::class,
WebViewCollector::class,
IdentityCollector::class,
],
'collectors.console' => [
ConsoleAppInfoCollector::class,
Expand All @@ -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' => [
Expand Down
33 changes: 33 additions & 0 deletions src/Collector/AuthenticationMethodInterfaceProxy.php
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Yii\Debug\Collector;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Yiisoft\Auth\AuthenticationMethodInterface;
use Yiisoft\Auth\IdentityInterface;

final class AuthenticationMethodInterfaceProxy implements AuthenticationMethodInterface
{
public function __construct(private AuthenticationMethodInterface $decorated, private IdentityCollector $collector)
{
}

public function authenticate(ServerRequestInterface $request): ?IdentityInterface
{
$identity = null;
try {
$identity = $this->decorated->authenticate($request);
} finally {
$this->collector->collect($identity);
}
return $identity;
}

public function challenge(ResponseInterface $response): ResponseInterface
{
return $this->decorated->challenge($response);
}
}
51 changes: 51 additions & 0 deletions src/Collector/IdentityCollector.php
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Yii\Debug\Collector;

use Yiisoft\Auth\IdentityInterface;

final class IdentityCollector implements CollectorInterface, IndexCollectorInterface
{
use CollectorTrait;

private array $identities = [];

public function getCollected(): array
{
return $this->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),
],
];
}
}
51 changes: 51 additions & 0 deletions tests/Collector/UserCollectorTest.php
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Yii\Debug\Tests\Collector;

use Yiisoft\Yii\Debug\Collector\CollectorInterface;
use Yiisoft\Yii\Debug\Collector\IdentityCollector;
use Yiisoft\Yii\Debug\Tests\Support\FakeIdentity;

final class UserCollectorTest extends AbstractCollectorTestCase
{
/**
* @param IdentityCollector $collector
*/
protected function collectTestData(CollectorInterface $collector): void
{
$collector->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']);
}
}
19 changes: 19 additions & 0 deletions tests/Support/FakeIdentity.php
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Yii\Debug\Tests\Support;

use Yiisoft\Auth\IdentityInterface;

final class FakeIdentity implements IdentityInterface
{
public function __construct(private ?string $id)
{
}

public function getId(): ?string
{
return $this->id;
}
}

0 comments on commit 03c53ad

Please sign in to comment.