Skip to content

Commit 37b3b9d

Browse files
jdeniaudkarlovi
authored andcommitted
Allow array in supported_scopes option (#552)
* Allow multiline in supported_scopes option * move from multiline string to array definition * document array notation for supported scopes * add exception if supported_scopes mixes array notation and string notation
1 parent 07f6471 commit 37b3b9d

File tree

5 files changed

+146
-3
lines changed

5 files changed

+146
-3
lines changed

Controller/AuthorizeController.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ protected function getRedirectionUrl(UserInterface $user)
249249
}
250250

251251
/**
252-
* @return ClientInterface.
252+
* @return ClientInterface
253253
*/
254254
protected function getClient()
255255
{

DependencyInjection/Configuration.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ private function addServiceSection(ArrayNodeDefinition $node)
104104
->arrayNode('options')
105105
->useAttributeAsKey('key')
106106
->treatNullLike([])
107-
->prototype('scalar')->end()
107+
->prototype('variable')->end()
108108
->end()
109109
->end()
110110
->end()

DependencyInjection/FOSOAuthServerExtension.php

+17-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace FOS\OAuthServerBundle\DependencyInjection;
1515

1616
use FOS\OAuthServerBundle\Util\LegacyFormHelper;
17+
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
1718
use Symfony\Component\Config\Definition\Processor;
1819
use Symfony\Component\Config\FileLocator;
1920
use Symfony\Component\DependencyInjection\Alias;
@@ -51,7 +52,11 @@ public function load(array $configs, ContainerBuilder $container)
5152
$container->setAlias('fos_oauth_server.user_provider', new Alias($config['service']['user_provider'], false));
5253
}
5354

54-
$container->setParameter('fos_oauth_server.server.options', $config['service']['options']);
55+
$options = $config['service']['options'];
56+
if (is_array($options['supported_scopes'] ?? null)) {
57+
$options['supported_scopes'] = $this->computeArraySupportedScopes($options['supported_scopes']);
58+
}
59+
$container->setParameter('fos_oauth_server.server.options', $options);
5560

5661
$this->remapParametersNamespaces($config, $container, [
5762
'' => [
@@ -150,4 +155,15 @@ protected function loadAuthorize(array $config, ContainerBuilder $container, Xml
150155
'form' => 'fos_oauth_server.authorize.form.%s',
151156
]);
152157
}
158+
159+
private function computeArraySupportedScopes(array $supportedScopes)
160+
{
161+
foreach ($supportedScopes as $scope) {
162+
if (false !== mb_strpos($scope, ' ')) {
163+
throw new InvalidConfigurationException('The array notation for supported_scopes should not contain spaces in array items. Either use full array notation or use the string notation for supported_scopes. See https://git.io/vx1X0 for more informations.');
164+
}
165+
}
166+
167+
return implode(' ', $supportedScopes);
168+
}
153169
}

Resources/doc/dealing_with_scopes.md

+14
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,19 @@ That's why the `scope` column in the model layer is a string, not an array for i
1313

1414
To configure allowed scopes in your application, you have to edit your `app/config/config.yml` file:
1515

16+
``` yaml
17+
# app/config/config.yml
18+
fos_oauth_server:
19+
service:
20+
options:
21+
supported_scopes:
22+
- scope1
23+
- scope2
24+
- scope3
25+
- scope4
26+
```
27+
28+
If you have a short list of scopes, you can define them as a simple string:
1629
``` yaml
1730
# app/config/config.yml
1831
fos_oauth_server:
@@ -21,6 +34,7 @@ fos_oauth_server:
2134
supported_scopes: scope1 scope2
2235
```
2336
37+
2438
Now, clients will be able to pass a `scope` parameter when they request an access token.
2539

2640

Tests/DependencyInjection/FOSOAuthServerExtensionTest.php

+113
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,25 @@
1313

1414
namespace FOS\OAuthServerBundle\Tests\DependencyInjection;
1515

16+
use FOS\OAuthServerBundle\DependencyInjection\FOSOAuthServerExtension;
17+
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
1618
use Symfony\Component\Config\FileLocator;
19+
use Symfony\Component\DependencyInjection\ContainerBuilder;
20+
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
1721
use Symfony\Component\Routing\Loader\XmlFileLoader;
1822

1923
class FOSOAuthServerExtensionTest extends \PHPUnit\Framework\TestCase
2024
{
25+
private $container;
26+
27+
public function setUp()
28+
{
29+
$parameterBag = new ParameterBag();
30+
$this->container = new ContainerBuilder($parameterBag);
31+
32+
parent::setUp();
33+
}
34+
2135
public function testLoadAuthorizeRouting()
2236
{
2337
$locator = new FileLocator();
@@ -39,4 +53,103 @@ public function testLoadTokenRouting()
3953
$this->assertSame('/oauth/v2/token', $tokenRoute->getPath());
4054
$this->assertSame(['GET', 'POST'], $tokenRoute->getMethods());
4155
}
56+
57+
public function testWithoutService()
58+
{
59+
$config = [
60+
'db_driver' => 'orm',
61+
'client_class' => 'dumb_class',
62+
'access_token_class' => 'dumb_access_token_class',
63+
'refresh_token_class' => 'dumb_refresh_token_class',
64+
'auth_code_class' => 'dumb_auth_code_class',
65+
];
66+
$instance = new FOSOAuthServerExtension();
67+
$instance->load([$config], $this->container);
68+
69+
$this->assertSame(
70+
$this->container->getParameter('fos_oauth_server.server.options'),
71+
[]
72+
);
73+
}
74+
75+
public function testStringSupportedScopes()
76+
{
77+
$scopes = 'scope1 scope2 scope3 scope4';
78+
79+
$config = [
80+
'db_driver' => 'orm',
81+
'client_class' => 'dumb_class',
82+
'access_token_class' => 'dumb_access_token_class',
83+
'refresh_token_class' => 'dumb_refresh_token_class',
84+
'auth_code_class' => 'dumb_auth_code_class',
85+
'service' => [
86+
'options' => [
87+
'supported_scopes' => $scopes,
88+
],
89+
],
90+
];
91+
92+
$instance = new FOSOAuthServerExtension();
93+
$instance->load([$config], $this->container);
94+
95+
$this->assertSame(
96+
$this->container->getParameter('fos_oauth_server.server.options'),
97+
[
98+
'supported_scopes' => 'scope1 scope2 scope3 scope4',
99+
]
100+
);
101+
}
102+
103+
public function testArraySupportedScopes()
104+
{
105+
$scopes = ['scope1', 'scope2', 'scope3', 'scope4'];
106+
107+
$config = [
108+
'db_driver' => 'orm',
109+
'client_class' => 'dumb_class',
110+
'access_token_class' => 'dumb_access_token_class',
111+
'refresh_token_class' => 'dumb_refresh_token_class',
112+
'auth_code_class' => 'dumb_auth_code_class',
113+
'service' => [
114+
'options' => [
115+
'supported_scopes' => $scopes,
116+
'enforce_redirect' => true,
117+
],
118+
],
119+
];
120+
$instance = new FOSOAuthServerExtension();
121+
$instance->load([$config], $this->container);
122+
123+
$this->assertSame(
124+
$this->container->getParameter('fos_oauth_server.server.options'),
125+
[
126+
'supported_scopes' => 'scope1 scope2 scope3 scope4',
127+
'enforce_redirect' => true,
128+
]
129+
);
130+
}
131+
132+
public function testArraySupportedScopesWithSpace()
133+
{
134+
$scopes = ['scope1 scope2', 'scope3', 'scope4'];
135+
136+
$config = [
137+
'db_driver' => 'orm',
138+
'client_class' => 'dumb_class',
139+
'access_token_class' => 'dumb_access_token_class',
140+
'refresh_token_class' => 'dumb_refresh_token_class',
141+
'auth_code_class' => 'dumb_auth_code_class',
142+
'service' => [
143+
'options' => [
144+
'supported_scopes' => $scopes,
145+
'enforce_redirect' => true,
146+
],
147+
],
148+
];
149+
$instance = new FOSOAuthServerExtension();
150+
151+
$this->expectException(InvalidConfigurationException::class);
152+
$this->expectExceptionMessage('The array notation for supported_scopes should not contain spaces in array items. Either use full array notation or use the string notation for supported_scopes. See https://git.io/vx1X0 for more informations.');
153+
$instance->load([$config], $this->container);
154+
}
42155
}

0 commit comments

Comments
 (0)