Skip to content

Commit 331a24e

Browse files
committed
feature #28061 [Security] add port in access_control (roukmoute)
This PR was squashed before being merged into the 4.2-dev branch (closes #28061). Discussion ---------- [Security] add port in access_control | Q | A | ------------- | --- | Branch? | master for features | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #26071 | License | MIT | Doc PR | symfony/symfony-docs#10359 Add port in access_control __Please Squash this P.R.__ Commits ------- 6413dcb [Security] add port in access_control
2 parents dce8f08 + 6413dcb commit 331a24e

File tree

10 files changed

+50
-11
lines changed

10 files changed

+50
-11
lines changed

src/Symfony/Bundle/SecurityBundle/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ CHANGELOG
1515
and added an "auto" mode to their "secure" config option to make them secure on HTTPS automatically.
1616
* Deprecated the `simple_form` and `simple_preauth` authentication listeners, use Guard instead.
1717
* Deprecated the `SimpleFormFactory` and `SimplePreAuthenticationFactory` classes, use Guard instead.
18+
* Added `port` in access_control
1819

1920
4.1.0
2021
-----

src/Symfony/Bundle/SecurityBundle/DependencyInjection/MainConfiguration.php

+1
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ private function addAccessControlSection(ArrayNodeDefinition $rootNode)
142142
->example('^/path to resource/')
143143
->end()
144144
->scalarNode('host')->defaultNull()->end()
145+
->integerNode('port')->defaultNull()->end()
145146
->arrayNode('ips')
146147
->beforeNormalization()->ifString()->then(function ($v) { return array($v); })->end()
147148
->prototype('scalar')->end()

src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php

+5-4
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ private function createAuthorization($config, ContainerBuilder $container)
172172
$container,
173173
$access['path'],
174174
$access['host'],
175+
$access['port'],
175176
$access['methods'],
176177
$access['ips']
177178
);
@@ -275,7 +276,7 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a
275276
$pattern = isset($firewall['pattern']) ? $firewall['pattern'] : null;
276277
$host = isset($firewall['host']) ? $firewall['host'] : null;
277278
$methods = isset($firewall['methods']) ? $firewall['methods'] : array();
278-
$matcher = $this->createRequestMatcher($container, $pattern, $host, $methods);
279+
$matcher = $this->createRequestMatcher($container, $pattern, $host, null, $methods);
279280
}
280281

281282
$config->replaceArgument(2, $matcher ? (string) $matcher : null);
@@ -696,20 +697,20 @@ private function createExpression($container, $expression)
696697
return $this->expressions[$id] = new Reference($id);
697698
}
698699

699-
private function createRequestMatcher($container, $path = null, $host = null, $methods = array(), $ip = null, array $attributes = array())
700+
private function createRequestMatcher($container, $path = null, $host = null, int $port = null, $methods = array(), $ip = null, array $attributes = array())
700701
{
701702
if ($methods) {
702703
$methods = array_map('strtoupper', (array) $methods);
703704
}
704705

705-
$id = '.security.request_matcher.'.ContainerBuilder::hash(array($path, $host, $methods, $ip, $attributes));
706+
$id = '.security.request_matcher.'.ContainerBuilder::hash(array($path, $host, $port, $methods, $ip, $attributes));
706707

707708
if (isset($this->requestMatchers[$id])) {
708709
return $this->requestMatchers[$id];
709710
}
710711

711712
// only add arguments that are necessary
712-
$arguments = array($path, $host, $methods, $ip, $attributes);
713+
$arguments = array($path, $host, $methods, $ip, $attributes, null, $port);
713714
while (\count($arguments) > 0 && !end($arguments)) {
714715
array_pop($arguments);
715716
}

src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public function testFirewalls()
8484
array(
8585
'simple',
8686
'security.user_checker',
87-
'.security.request_matcher.6tndozi',
87+
'.security.request_matcher.xmi9dcw',
8888
false,
8989
),
9090
array(
@@ -116,7 +116,7 @@ public function testFirewalls()
116116
array(
117117
'host',
118118
'security.user_checker',
119-
'.security.request_matcher.and0kk1',
119+
'.security.request_matcher.iw4hyjb',
120120
true,
121121
false,
122122
'security.user.provider.concrete.default',
@@ -238,7 +238,7 @@ public function testAccess()
238238
$this->assertEquals(array('ROLE_USER'), $attributes);
239239
$this->assertEquals('https', $channel);
240240
$this->assertEquals(
241-
array('/blog/524', null, array('GET', 'POST')),
241+
array('/blog/524', null, array('GET', 'POST'), array(), array(), null, 8000),
242242
$requestMatcher->getArguments()
243243
);
244244
} elseif (2 === $i) {

src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/php/container1.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@
9090
),
9191

9292
'access_control' => array(
93-
array('path' => '/blog/524', 'role' => 'ROLE_USER', 'requires_channel' => 'https', 'methods' => array('get', 'POST')),
93+
array('path' => '/blog/524', 'role' => 'ROLE_USER', 'requires_channel' => 'https', 'methods' => array('get', 'POST'), 'port' => 8000),
9494
array('path' => '/blog/.*', 'role' => 'IS_AUTHENTICATED_ANONYMOUSLY'),
9595
array('path' => '/blog/524', 'role' => 'IS_AUTHENTICATED_ANONYMOUSLY', 'allow_if' => "token.getUsername() matches '/^admin/'"),
9696
),

src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/xml/container1.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
<role id="ROLE_SUPER_ADMIN">ROLE_USER,ROLE_ADMIN,ROLE_ALLOWED_TO_SWITCH</role>
7373
<role id="ROLE_REMOTE">ROLE_USER,ROLE_ADMIN</role>
7474

75-
<rule path="/blog/524" role="ROLE_USER" requires-channel="https" methods="get,POST" />
75+
<rule path="/blog/524" role="ROLE_USER" requires-channel="https" methods="get,POST" port="8000" />
7676
<rule role='IS_AUTHENTICATED_ANONYMOUSLY' path="/blog/.*" />
7777
<rule role='IS_AUTHENTICATED_ANONYMOUSLY' allow-if="token.getUsername() matches '/^admin/'" path="/blog/524" />
7878
</config>

src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Fixtures/yml/container1.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ security:
7676
ROLE_REMOTE: ROLE_USER,ROLE_ADMIN
7777

7878
access_control:
79-
- { path: /blog/524, role: ROLE_USER, requires_channel: https, methods: [get, POST]}
79+
- { path: /blog/524, role: ROLE_USER, requires_channel: https, methods: [get, POST], port: 8000}
8080
-
8181
path: /blog/.*
8282
role: IS_AUTHENTICATED_ANONYMOUSLY

src/Symfony/Component/HttpFoundation/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ CHANGELOG
88
* the default value of the "$secure" and "$samesite" arguments of Cookie's constructor
99
will respectively change from "false" to "null" and from "null" to "lax" in Symfony
1010
5.0, you should define their values explicitly or use "Cookie::create()" instead.
11+
* added `matchPort()` in RequestMatcher
1112

1213
4.1.3
1314
-----

src/Symfony/Component/HttpFoundation/RequestMatcher.php

+21-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ class RequestMatcher implements RequestMatcherInterface
2828
*/
2929
private $host;
3030

31+
/**
32+
* @var int|null
33+
*/
34+
private $port;
35+
3136
/**
3237
* @var string[]
3338
*/
@@ -56,13 +61,14 @@ class RequestMatcher implements RequestMatcherInterface
5661
* @param array $attributes
5762
* @param string|string[]|null $schemes
5863
*/
59-
public function __construct(string $path = null, string $host = null, $methods = null, $ips = null, array $attributes = array(), $schemes = null)
64+
public function __construct(string $path = null, string $host = null, $methods = null, $ips = null, array $attributes = array(), $schemes = null, int $port = null)
6065
{
6166
$this->matchPath($path);
6267
$this->matchHost($host);
6368
$this->matchMethod($methods);
6469
$this->matchIps($ips);
6570
$this->matchScheme($schemes);
71+
$this->matchPort($port);
6672

6773
foreach ($attributes as $k => $v) {
6874
$this->matchAttribute($k, $v);
@@ -89,6 +95,16 @@ public function matchHost($regexp)
8995
$this->host = $regexp;
9096
}
9197

98+
/**
99+
* Adds a check for the the URL port.
100+
*
101+
* @param int|null $port The port number to connect to
102+
*/
103+
public function matchPort(int $port = null)
104+
{
105+
$this->port = $port;
106+
}
107+
92108
/**
93109
* Adds a check for the URL path info.
94110
*
@@ -167,6 +183,10 @@ public function matches(Request $request)
167183
return false;
168184
}
169185

186+
if (null !== $this->port && 0 < $this->port && $request->getPort() !== $this->port) {
187+
return false;
188+
}
189+
170190
if (IpUtils::checkIp($request->getClientIp(), $this->ips)) {
171191
return true;
172192
}

src/Symfony/Component/HttpFoundation/Tests/RequestMatcherTest.php

+15
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,21 @@ public function testHost($pattern, $isMatch)
7878
$this->assertSame($isMatch, $matcher->matches($request));
7979
}
8080

81+
public function testPort()
82+
{
83+
$matcher = new RequestMatcher();
84+
$request = Request::create('', 'get', array(), array(), array(), array('HTTP_HOST' => null, 'SERVER_PORT' => 8000));
85+
86+
$matcher->matchPort(8000);
87+
$this->assertTrue($matcher->matches($request));
88+
89+
$matcher->matchPort(9000);
90+
$this->assertFalse($matcher->matches($request));
91+
92+
$matcher = new RequestMatcher(null, null, null, null, array(), null, 8000);
93+
$this->assertTrue($matcher->matches($request));
94+
}
95+
8196
public function getHostData()
8297
{
8398
return array(

0 commit comments

Comments
 (0)