8000 Integrate current firewall in profiler · symfony/symfony@9a95c6e · GitHub
[go: up one dir, main page]

Skip to content

Commit 9a95c6e

Browse files
committed
Integrate current firewall in profiler
Add firewall name to the toolbar Display bool values as metrics, Dont display request_matcher anymore Use allowsAnonymous()/isSecurityEnabled() in template, update labels accordingly Add SecurityDataCollectorTest::testCollectFirewall() Move collector.enabled check higher to cover token+firewall sections Allow Anonymous => Allows anonymous Tests null cases for SecurityDataCollector::getFirewall() Fix phpdoc block
1 parent f13bdda commit 9a95c6e

File tree

4 files changed

+244
-46
lines changed

4 files changed

+244
-46
lines changed

src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
2222
use Symfony\Component\Security\Core\Authorization\DebugAccessDecisionManager;
2323
use Symfony\Component\VarDumper\Cloner\Data;
24+
use Symfony\Component\Security\Http\FirewallMapInterface;
25+
use Symfony\Bundle\SecurityBundle\Security\ContextAwareFirewallMapInterface;
2426

2527
/**
2628
* SecurityDataCollector.
@@ -33,6 +35,7 @@ class SecurityDataCollector extends DataCollector
3335
private $roleHierarchy;
3436
private $logoutUrlGenerator;
3537
private $accessDecisionManager;
38+
private $firewallMap;
3639

3740
/**
3841
* Constructor.
@@ -41,13 +44,15 @@ class SecurityDataCollector extends DataCollector
4144
* @param RoleHierarchyInterface|null $roleHierarchy
4245
* @param LogoutUrlGenerator|null $logoutUrlGenerator
4346
* @param AccessDecisionManagerInterface|null $accessDecisionManager
47+
* @param FirewallMapInterface|null $firewallMap
4448
*/
45-
public function __construct(TokenStorageInterface $tokenStorage = null, RoleHierarchyInterface $roleHierarchy = null, LogoutUrlGenerator $logoutUrlGenerator = null, AccessDecisionManagerInterface $accessDecisionManager = null)
49+
public function __construct(TokenStorageInterface $tokenStorage = null, RoleHierarchyInterface $roleHierarchy = null, LogoutUrlGenerator $logoutUrlGenerator = null, AccessDecisionManagerInterface $accessDecisionManager = null, FirewallMapInterface $firewallMap = null)
4650
{
4751
$this->tokenStorage = $tokenStorage;
4852
$this->roleHierarchy = $roleHierarchy;
4953
$this->logoutUrlGenerator = $logoutUrlGenerator;
5054
$this->accessDecisionManager = $accessDecisionManager;
55+
$this->firewallMap = $firewallMap;
5156
}
5257

5358
/**
@@ -132,6 +137,16 @@ public function collect(Request $request, Response $response, \Exception $except
132137
$this->data['voter_strategy'] = 'unknown';
133138
$this->data['voters'] = array();
134139
}
140+
141+
// collect firewall context informations
142+
$this->data['firewall'] = null;
143+
if ($this->firewallMap instanceof ContextAwareFirewallMapInterface) {
144+
$firewallContext = $this->firewallMap->getContext($request);
145+
146+
if (null !== $firewallContext) {
147+
$this->data['firewall'] = $firewallContext->getConfig();
148+
}
149+
}
135150
}
136151

137152
/**
@@ -255,6 +270,16 @@ public function getAccessDecisionLog()
255270
return $this->data['access_decision_log'];
256271
}
257272

273+
/**
274+
* Returns the configuration of the current firewall context.
275+
*
276+
* @return array
277+
*/
278+
public function getFirewall()
279+
{
280+
return $this->data['firewall'];
281+
}
282+
258283
/**
259284
* {@inheritdoc}
260285
*/

src/Symfony/Bundle/SecurityBundle/Resources/config/collectors.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
<argument type="service" id="security.role_hierarchy" />
1212
<argument type="service" id="security.logout_url_generator" />
1313
<argument type="service" id="security.access.decision_manager" />
14+
<argument type="service" id="security.firewall.map" />
1415
</service>
1516
</services>
1617
</container>

src/Symfony/Bundle/SecurityBundle/Resources/views/Collector/security.html.twig

Lines changed: 121 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@
3333
<span>{{ collector.tokenClass|abbr_class }}</span>
3434
</div>
3535
{% endif %}
36+
{% if collector.firewall %}
37+
<div class="sf-toolbar-info-piece">
38+
<b>Firewall name</b>
39+
<span>{{ collector.firewall.name }}</span>
40+
</div>
41+
{% endif %}
3642
{% if collector.logoutUrl %}
3743
<div class="sf-toolbar-info-piece">
3844
<b>Actions</b>
@@ -63,57 +69,127 @@
6369
{% block panel %}
6470
<h2>Security Token</h2>
6571

66-
{% if collector.token %}
67-
<div class 10000 ="metrics">
68-
<div class="metric">
69-
<span class="value">{{ collector.user == 'anon.' ? 'Anonymous' : collector.user }}</span>
70-
<span class="label">Username</span>
72+
{% if collector.enabled %}
73+
{% if collector.token %}
74+
<div class="metrics">
75+
<div class="metric">
76+
<span class="value">{{ collector.user == 'anon.' ? 'Anonymous' : collector.user }}</span>
77+
<span class="label">Username</span>
78+
</div>
79+
80+
<div class="metric">
81+
<span class="value">{{ include('@WebProfiler/Icon/' ~ (collector.authenticated ? 'yes' : 'no') ~ '.svg') }}</span>
82+
<span class="label">Authenticated</span>
83+
</div>
7184
</div>
7285

73-
<div class="metric">
74-
<span class="value">{{ include('@WebProfiler/Icon/' ~ (collector.authenticated ? 'yes' : 'no') ~ '.svg') }}</span>
75-
<span class="label">Authenticated</span>
86+
<table>
87+
<thead>
88+
<tr>
89+
<th scope="col" class="key">Property</th>
90+
<th scope="col">Value</th>
91+
</tr>
92+
</thead>
93+
<tbody>
94+
<tr>
95+
<th>Roles</th>
96+
<td>
97+
{{ collector.roles is empty ? 'none' : profiler_dump(collector.roles, maxDepth=1) }}
98+
99+
{% if not collector.authenticated and collector.roles is empty %}
100+
<p class="help">User is not authenticated probably because they have no roles.</p>
101+
{% endif %}
102+
</td>
103+
</tr>
104+
105+
{% if collector.supportsRoleHierarchy %}
106+
<tr>
107+
<th>Inherited Roles</th>
108+
<td>{{ collector.inheritedRoles is empty ? 'none' : profiler_dump(collector.inheritedRoles, maxDepth=1) }}</td>
109+
</tr>
110+
{% endif %}
111+
112+
{% if collector.token %}
113+
<tr>
114+
<th>Token</th>
115+
<td>{{ profiler_dump(collector.token) }}</td>
116+
</tr>
117+
{% endif %}
118+
</tbody>
119+
</table>
120+
{% elseif collector.enabled %}
121+
<div class="empty">
122+
<p>There is no security token.</p>
76123
</div>
77-
</div>
124+
{% endif %}
78125

79-
<table>
80-
<thead>
81-
<tr>
82-
<th scope="col" class="key">Property</th>
83-
<th scope="col">Value</th>
84-
</tr>
85-
</thead>
86-
<tbody>
87-
<tr>
88-
<th>Roles</th>
89-
<td>
90-
{{ collector.roles is empty ? 'none' : profiler_dump(collector.roles, maxDepth=1) }}
91-
92-
{% if not collector.authenticated and collector.roles is empty %}
93-
<p class="help">User is not authenticated probably because they have no roles.</p>
94-
{% endif %}
95-
</td>
96-
</tr>
97126

98-
{% if collector.supportsRoleHierarchy %}
99-
<tr>
100-
<th>Inherited Roles</th>
101-
<td>{{ collector.inheritedRoles is empty ? 'none' : profiler_dump(collector.inheritedRoles, maxDepth=1) }}</td>
102-
</tr>
103-
{% endif %}
127+
<h2>Security Firewall</h2>
104128

105-
{% if collector.token %}
106-
<tr>
107-
<th>Token</th>
108-
<td>{{ profiler_dump(collector.token) }}</td>
109-
</tr>
110-
{% endif %}
111-
</tbody>
112-
</table>
113-
{% elseif collector.enabled %}
114-
<div class="empty">
115-
<p>There is no security token.</p>
116-
</div>
129+
{% if collector.firewall %}
130+
<div class="metrics">
131+
<div class="metric">
132+
<span class="value">{{ collector.firewall.name }}</span>
133+
<span class="label">Name</span>
134+
</div>
135+
<div class="metric">
136+
<span class="value">{{ include('@WebProfiler/Icon/' ~ (collector.firewall.securityEnabled ? 'yes' : 'no') ~ '.svg') }}</span>
137+
<span class="label">Security enabled</span>
138+
</div>
139+
<div class="metric">
140+
<span class="value">{{ include('@WebProfiler/Icon/' ~ (collector.firewall.stateless ? 'yes' : 'no') ~ '.svg') }}</span>
141+
<span class="label">Stateless</span>
142+
</div>
143+
<div class="metric">
144+
<span class="value">{{ include('@WebProfiler/Icon/' ~ (collector.firewall.allowsAnonymous ? 'yes' : 'no') ~ '.svg') }}</span>
145+
<span class="label">Allows anonymous</span>
146+
</div>
147+
</div>
148+
{% if collector.firewall.securityEnabled %}
149+
<table>
150+
<thead>
151+
<tr>
152+
<th scope="col" class="key">Key</th>
153+
<th scope="col">Value</th>
154+
</tr>
155+
</thead>
156+
<tbody>
157+
<tr>
158+
<th>provider</th>
159+
<td>{{ collector.firewall.provider }}</td>
160+
</tr>
161+
<tr>
162+
<th>context</th>
163+
<td>{{ collector.firewall.context }}</td>
164+
</tr>
165+
<tr>
166+
<th>entry_point</th>
167+
<td>{{ collector.firewall.entryPoint }}</td>
168+
</tr>
169+
<tr>
170+
<th>user_checker</th>
171+
<td>{{ collector.firewall.userChecker }}</td>
172+
</tr>
173+
<tr>
174+
<th>access_denied_handler</th>
175+
<td>{{ collector.firewall.accessDeniedHandler }}</td>
176+
</tr>
177+
<tr>
178+
<th>access_denied_url</th>
179+
<td>{{ collector.firewall.accessDeniedUrl }}</td>
180+
</tr>
181+
<tr>
182+
<th>listeners</th>
183+
<td>{{ collector.firewall.listeners is empty ? 'none' : profiler_dump(collector.firewall.listeners, maxDepth=1) }}</td>
184+
</tr>
185+
</tbody>
186+
</table>
187+
{% endif %}
188+
{% elseif collector.enabled %}
189+
<div class="empty">
190+
<p>There is no firewall.</p>
191+
</div>
192+
{% endif %}
117193
{% else %}
118194
<div class="empty">
119195
<p>The security component is disabled.</p>

src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,14 @@
1212
namespace Symfony\Bundle\SecurityBundle\Tests\DataCollector;
1313

1414
use Symfony\Bundle\SecurityBundle\DataCollector\SecurityDataCollector;
15+
use Symfony\Bundle\SecurityBundle\Security\FirewallConfig;
16+
use Symfony\Bundle\SecurityBundle\Security\FirewallContext;
17+
use Symfony\Bundle\SecurityBundle\Security\ContextAwareFirewallMapInterface;
1518
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
1619
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
1720
use Symfony\Component\Security\Core\Role\Role;
1821
use Symfony\Component\Security\Core\Role\RoleHierarchy;
22+
use Symfony\Component\Security\Http\FirewallMapInterface;
1923

2024
class SecurityDataCollectorTest extends \PHPUnit_Framework_TestCase
2125
{
@@ -32,6 +36,7 @@ public function testCollectWhenSecurityIsDisabled()
3236
$this->assertCount(0, $collector->getRoles());
3337
$this->assertCount(0, $collector->getInheritedRoles());
3438
$this->assertEmpty($collector->getUser());
39+
$this->assertNull($collector->getFirewall());
3540
}
3641

3742
public function testCollectWhenAuthenticationTokenIsNull()
@@ -47,6 +52,7 @@ public function testCollectWhenAuthenticationTokenIsNull()
4752
$this->assertCount(0, $collector->getRoles());
4853
$this->assertCount(0, $collector->getInheritedRoles());
4954
$this->assertEmpty($collector->getUser());
55+
$this->assertNull($collector->getFirewall());
5056
}
5157

5258
/** @dataProvider provideRoles */
@@ -71,6 +77,96 @@ public function testCollectAuthenticationTokenAndRoles(array $roles, array $norm
7177
$this->assertSame('hhamon', $collector->getUser());
7278
}
7379

80+
public function testGetFirewall()
81+
{
82+
$firewallConfig = new FirewallConfig('dummy', 'security.request_matcher.dummy');
83+
$request = $this->getRequest();
84+
85+
$firewallContext = $this
86+
->getMockBuilder(FirewallContext::class)
87+
->disableOriginalConstructor()
88+
->getMock();
89+
$firewallContext
90+
->expects($this->once())
91+
->method('getConfig')
92+
->willReturn($firewallConfig);
93+
94+
$firewallMap = $this
95+
->getMockBuilder(ContextAwareFirewallMapInterface::class)
96+
->disableOriginalConstructor()
97+
->getMock();
98+
$firewallMap
99+
->expects($this->once())
100+
->method('getContext')
101+
->with($request)
102+
->willReturn($firewallContext);
103+
104+
$collector = new SecurityDataCollector(null, null, null, null, $firewallMap);
105+
$collector->collect($request, $this->getResponse());
106+
107+
$this->assertSame($firewallConfig, $collector->getFirewall());
108+
}
109+
110+
public function testGetFirewallReturnsNull()
111+
{
112+
$request = $this->getRequest();
113+
$response = $this->getResponse();
114+
115+
// Don't inject any firewall map
116+
$collector = new SecurityDataCollector();
117+
$collector->collect($request, $response);
118+
$this->assertNull($collector->getFirewall());
119+
120+
// Inject an instance that is not context aware
121+
$firewallMap = $this
122+
->getMockBuilder(FirewallMapInterface::class)
123+
->disableOriginalConstructor()
124+
->getMock();
125+
126+
$collector = new SecurityDataCollector(null, null, null, null, $firewallMap);
127+
$collector->collect($request, $response);
128+
$this->assertNull($collector->getFirewall());
129+
130+
// Return a null context
131+
$firewallMap = $this
132+
->getMockBuilder(ContextAwareFirewallMapInterface::class)
133+
->disableOriginalConstructor()
134+
->getMock();
135+
$firewallMap
136+
->expects($this->once())
137+
->method('getContext')
138+
->with($request)
139+
->willReturn(null);
140+
141+
$collector = new SecurityDataCollector(null, null, null, null, $firewallMap);
142+
$collector->collect($request, $response);
143+
$this->assertNull($collector->getFirewall());
144+
145+
// Return a null config
146+
$firewallContext = $this
147+
->getMockBuilder(FirewallContext::class)
148+
->disableOriginalConstructor()
149+
->getMock();
150+
$firewallContext
151+
->expects($this->once())
152+
->method('getConfig')
153+
->willReturn(null);
154+
155+
$firewallMap = $this
156+
->getMockBuilder(ContextAwareFirewallMapInterface::class)
157+
->disableOriginalConstructor()
158+
->getMock();
159+
$firewallMap
160+
->expects($this->once())
161+
->method('getContext')
162+
->with($request)
163+
->willReturn($firewallContext);
164+
165+
$collector = new SecurityDataCollector(null, null, null, null, $firewallMap);
166+
$collector->collect($request, $response);
167+
$this->assertNull($collector->getFirewall());
168+
}
169+
74170
public function provideRoles()
75171
{
76172
return array(

0 commit comments

Comments
 (0)
0