Skip to content

Commit d17806a

Browse files
committed
UserStorage: call identity initializer only once
1 parent 3aa53cf commit d17806a

File tree

2 files changed

+75
-3
lines changed

2 files changed

+75
-3
lines changed

src/UserStorage.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ class UserStorage extends Object implements INamespaceUserStorage
2222
/** @var string fallback */
2323
protected $namespace;
2424

25+
/** @var IIdentity[] */
26+
protected $initializedIdentities = array();
2527

2628
/**
2729
* @param \Nette\Security\IUserStorage $userStorage
@@ -96,11 +98,14 @@ function getLogoutReason()
9698
public function getIdentity()
9799
{
98100
$identity = $this->innerUserStorage->getIdentity();
99-
if ($identity && $this->identityInitializer) {
100-
$identity = $this->identityInitializer->initialize($identity);
101+
if (!$identity || !$this->identityInitializer) {
102+
return $identity;
103+
}
104+
if (!isset($this->initializedIdentities[$hash = spl_object_hash($identity)])) {
105+
$this->initializedIdentities[$hash] = $this->identityInitializer->initialize($identity);
101106
}
102107

103-
return $identity;
108+
return $this->initializedIdentities[$hash];
104109
}
105110

106111
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
namespace LibretteTests\SecurityNamespace;
3+
4+
use Librette\SecurityNamespaces\Identity\IIdentityInitializer;
5+
use Librette\SecurityNamespaces\UserStorage;
6+
use Nette\Security\Identity;
7+
use Nette\Security\IIdentity;
8+
use Nette\Security\IUserStorage;
9+
use Tester\Assert;
10+
use Tester\TestCase;
11+
12+
require __DIR__ . '/../bootstrap.php';
13+
require __DIR__ . '/mocks/UserStorageMock.php';
14+
15+
class MyInitializer implements IIdentityInitializer
16+
{
17+
18+
public $counter = 0;
19+
20+
public function initialize(IIdentity $identity)
21+
{
22+
$this->counter++;
23+
24+
return $identity;
25+
}
26+
27+
}
28+
29+
class IdentityInitializerTestCase extends TestCase
30+
{
31+
32+
/** @var UserStorage */
33+
protected $userStorage;
34+
35+
/** @var UserStorageMock */
36+
protected $innerUserStorage;
37+
38+
/** @var MyInitializer */
39+
protected $initializer;
40+
41+
public function setUp()
42+
{
43+
$this->innerUserStorage = new UserStorageMock();
44+
$this->userStorage = new UserStorage($this->innerUserStorage, $this->initializer = new MyInitializer());
45+
}
46+
47+
public function testInvocationCount()
48+
{
49+
Assert::equal(0, $this->initializer->counter);
50+
$this->userStorage->getIdentity();
51+
Assert::equal(0, $this->initializer->counter);
52+
$this->userStorage->setIdentity(new Identity(1));
53+
$this->userStorage->getIdentity();
54+
Assert::equal(1, $this->initializer->counter);
55+
$this->userStorage->getIdentity();
56+
Assert::equal(1, $this->initializer->counter);
57+
$this->userStorage->setIdentity(new Identity(2));
58+
$this->userStorage->getIdentity();
59+
Assert::equal(2, $this->initializer->counter);
60+
$this->userStorage->getIdentity();
61+
Assert::equal(2, $this->initializer->counter);
62+
}
63+
64+
}
65+
66+
67+
run(new IdentityInitializerTestCase());

0 commit comments

Comments
 (0)