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

Skip to content

Commit 3677070

Browse files
committed 8000
Integrate current firewall in profile
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()
1 parent 4aa2242 commit 3677070

File tree

4 files changed

+248
-51
lines changed

4 files changed

+248
-51
lines changed

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

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
use Symfony\Component\Security\Http\Logout\LogoutUrlGenerator;
2121
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
2222
use Symfony\Component\Security\Core\Authorization\DebugAccessDecisionManager;
23+
use Symfony\Component\Security\Http\FirewallMapInterface;
24+
use Symfony\Bundle\SecurityBundle\Security\ContextAwareFirewallMapInterface;
2325

2426
/**
2527
* SecurityDataCollector.
@@ -32,21 +34,24 @@ class SecurityDataCollector extends DataCollector
3234
private $roleHierarchy;
3335
private $logoutUrlGenerator;
3436
private $accessDecisionManager;
37+
private $firewallMap;
3538

3639
/**
3740
* Constructor.
3841
*
39-
* @param TokenStorageInterface|null $tokenStorage
40-
* @param RoleHierarchyInterface|null $roleHierarchy
41-
* @param LogoutUrlGenerator|null $logoutUrlGenerator
42-
* @param AccessDecisionManagerInterface|null $accessDecisionManager
42+
* @param TokenStorageInterface|null $tokenStorage
43+
* @param RoleHierarchyInterface|null $roleHierarchy
44+
* @param LogoutUrlGenerator|null $logoutUrlGenerator
45+
* @param AccessDecisionManagerInterface|null $accessDecisionManager
46+
* @param ContextAwareFirewallMapInterface|null $firewallMap
4347
*/
44-
public function __construct(TokenStorageInterface $tokenStorage = null, RoleHierarchyInterface $roleHierarchy = null, LogoutUrlGenerator $logoutUrlGenerator = null, AccessDecisionManagerInterface $accessDecisionManager = null)
48+
public function __construct(TokenStorageInterface $tokenStorage = null, RoleHierarchyInterface $roleHierarchy = null, LogoutUrlGenerator $logoutUrlGenerator = null, AccessDecisionManagerInterface $accessDecisionManager = null, FirewallMapInterface $firewallMap = null)
4549
{
4650
$this->tokenStorage = $tokenStorage;
4751
$this->roleHierarchy = $roleHierarchy;
4852
$this->logoutUrlGenerator = $logoutUrlGenerator;
4953
$this->accessDecisionManager = $accessDecisionManager;
54+
$this->firewallMap = $firewallMap;
5055
}
5156

5257
/**
@@ -123,6 +128,16 @@ public function collect(Request $request, Response $response, \Exception $except
123128
$this->data['voter_strategy'] = 'unknown';
124129
$this->data['voters'] = array();
125130
}
131+
132+
// collect firewall context informations
133+
$this->data['firewall'] = null;
134+
if ($this->firewallMap instanceof ContextAwareFirewallMapInterface) {
135+
$firewallContext = $this->firewallMap->getContext($request);
136+
137+
if (null !== $firewallContext) {
138+
$this->data['firewall'] = $firewallContext->getConfig();
139+
}
140+
}
126141
}
127142

128143
/**
@@ -236,6 +251,16 @@ public function getAccessDecisionLog()
236251
return $this->data['access_decision_log'];
237252
}
238253

254+
/**
255+
* Returns the configuration of the current firewall context.
256+
*
257+
* @return array
258+
*/
259+
public function getFirewall()
260+
{
261+
return $this->data['firewall'];
262+
}
263+
239264
/**
240265
* {@inheritdoc}
241266
*/

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 & 46 deletions
10000
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,126 @@
6369
{% block panel %}
6470
<h2>Security Token</h2>
6571

66-
{% if collector.tokenClass %}
67-
<div class="metrics">
68-
<div class="metric">
69-
<span class="value">{{ collector.user == 'anon.' ? 'Anonymous' : collector.user }}</span>
70-
<span class="label">Username</span>
71-
</div>
72+
{% if collector.enabled %}
73+
{% if collector.tokenClass %}
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>
7279

73-
<div class="metric">
74-
<span class="value">{{ include('@WebProfiler/Icon/' ~ (collector.authenticated ? 'yes' : 'no') ~ '.svg') }}</span>
75-
<span class="label">Authenticated</span>
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>
7684
</div>
77-
</div>
7885

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' : collector.roles|yaml_encode }}
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>
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' : collector.roles|yaml_encode }}
9798

98-
{% if collector.supportsRoleHierarchy %}
99-
<tr>
100-
<th>Inherited Roles</th>
101-
<td>{{ collector.inheritedRoles is empty ? 'none' : collector.inheritedRoles|yaml_encode }}</td>
102-
</tr>
103-
{% endif %}
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>
104104

105-
{% if collector.tokenClass %}
106-
<tr>
107-
<th>Token class</th>
108-
<td>{{ collector.tokenClass }}</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>
105+
{% if collector.supportsRoleHierarchy %}
106+
<tr>
107+
<th>Inherited Roles</th>
108+
<td>{{ collector.inheritedRoles is empty ? 'none' : collector.inheritedRoles|yaml_encode }}</td>
109+
</tr>
110+
{% endif %}
111+
112+
{% if collector.tokenClass %}
113+
<tr>
114+
<th>Token class</th>
115+
<td>{{ collector.tokenClass }}</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>
123+
</div>
124+
{% endif %}
125+
126+
<h2>Security Firewall</h2>
127+
128+
{% if collector.firewall %}
129+
<div class="metrics">
130+
<div class="metric">
131+
<span class="value">{{ collector.firewall.name }}</span>
132+
<span class="label">Name</span>
133+
</div>
134+
<div class="metric">
135+
<span class="value">{{ include('@WebProfiler/Icon/' ~ (collector.firewall.securityEnabled ? 'yes' : 'no') ~ '.svg') }}</span>
136+
<span class="label">Security enabled</span>
137+
</div>
138+
<div class="metric">
139+
<span class="value">{{ include('@WebProfiler/Icon/' ~ (collector.firewall.stateless ? 'yes' : 'no') ~ '.svg') }}</span>
140+
<span class="label">Stateless</span>
141+
</div>
142+
<div class="metric">
143+
<span class="value">{{ include('@WebProfiler/Icon/' ~ (collector.firewall.allowsAnonymous ? 'yes' : 'no') ~ '.svg') }}</span>
144+
<span class="label">Allows anonymous</span>
145+
</div>
146+
</div>
147+
{% if collector.firewall.securityEnabled %}
148+
<table>
149+
<thead>
150+
<tr>
151+
<th scope="col" class="key">Key</th>
152+
<th scope="col">Value</th>
153+
</tr>
154+
</thead>
155+
<tbody>
156+
<tr>
157+
<th>provider</th>
158+
<td>{{ collector.firewall.provider }}</td>
159+
</tr>
160+
<tr>
161+
<th>context</th>
162+
<td>{{ collector.firewall.context }}</td>
163+
</tr>
164+
<tr>
165+
<th>entry_point</th>
166+
<td>{{ collector.firewall.entryPoint }}</td>
167+
</tr>
168+
<tr>
169+
<th>user_checker</th>
170+
<td>{{ collector.firewall.userChecker }}</td>
171+
</tr>
172+
<tr>
173+
<th>access_denied_handler</th>
174+
<td>{{ collector.firewall.accessDeniedHandler }}</td>
175+
</tr>
176+
<tr>
177+
<th>access_denied_url</th>
178+
<td>{{ collector.firewall.accessDeniedUrl }}</td>
179+
</tr>
180+
<tr>
181+
<th>listeners</th>
182+
<td>{{ collector.firewall.listeners|yaml_encode }}</td>
183+
</tr>
184+
</tbody>
185+
</table>
186+
{% endif %}
187+
{% elseif collector.enabled %}
188+
<div class="empty">
189+
<p>There is no firewall.</p>
190+
</div>
191+
{% endif %}
117192
{% else %}
118193
<div class="empty">
119194
<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 */
@@ -67,6 +73,96 @@ public function testCollectAuthenticationTokenAndRoles(array $roles, array $norm
6773
$this->assertSame('hhamon', $collector->getUser());
6874
}
6975

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

0 commit comments

Comments
 (0)
0