Skip to content

Commit 8fb2fe8

Browse files
makasimdkarlovi
authored andcommitted
Custom DB driver support (#553)
* Custom db driver. * add tests and doc. * remove commented out code. * fix doc * fix tests * fix tests
1 parent 2b76d49 commit 8fb2fe8

File tree

7 files changed

+262
-4
lines changed

7 files changed

+262
-4
lines changed

DependencyInjection/Configuration.php

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,34 @@ public function getConfigTreeBuilder()
3030
$treeBuilder = new TreeBuilder();
3131
$rootNode = $treeBuilder->root('fos_oauth_server');
3232

33-
$supportedDrivers = array('orm', 'mongodb', 'propel');
33+
$supportedDrivers = array('orm', 'mongodb', 'propel', 'custom');
3434

3535
$rootNode
36+
->validate()
37+
->always(function($v) {
38+
if ('custom' !== $v['db_driver']) {
39+
return $v;
40+
}
41+
42+
if (empty($v['service']['client_manager']) || $v['service']['client_manager'] === 'fos_oauth_server.client_manager.default') {
43+
throw new \InvalidArgumentException('The service client_manager must be set explicitly for custom db_driver.');
44+
}
45+
46+
if (empty($v['service']['access_token_manager']) || $v['service']['access_token_manager'] === 'fos_oauth_server.access_token_manager.default') {
47+
throw new \InvalidArgumentException('The service access_token_manager must be set explicitly for custom db_driver.');
48+
}
49+
50+
if (empty($v['service']['refresh_token_manager']) || $v['service']['refresh_token_manager'] === 'fos_oauth_server.refresh_token_manager.default') {
51+
throw new \InvalidArgumentException('The service refresh_token_manager must be set explicitly for custom db_driver.');
52+
}
53+
54+
if (empty($v['service']['auth_code_manager']) || $v['service']['auth_code_manager'] === 'fos_oauth_server.auth_code_manager.default') {
55+
throw new \InvalidArgumentException('The service auth_code_manager must be set explicitly for custom db_driver.');
56+
}
57+
58+
return $v;
59+
})
60+
->end()
3661
->children()
3762
->scalarNode('db_driver')
3863
->validate()

DependencyInjection/FOSOAuthServerExtension.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ public function load(array $configs, ContainerBuilder $container)
3333
$config = $processor->processConfiguration($configuration, $configs);
3434

3535
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
36-
$loader->load(sprintf('%s.xml', $config['db_driver']));
36+
37+
if ('custom' !== $config['db_driver']) {
38+
$loader->load(sprintf('%s.xml', $config['db_driver']));
39+
}
3740

3841
foreach (array('oauth', 'security') as $basename) {
3942
$loader->load(sprintf('%s.xml', $basename));

Resources/config/oauth.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
</service>
3838

3939
<service id="fos_oauth_server.create_client_command" class="FOS\OAuthServerBundle\Command\CreateClientCommand">
40-
<argument type="service" id="fos_oauth_server.client_manager.default" />
40+
<argument type="service" id="fos_oauth_server.client_manager" />
4141
<tag name="console.command" />
4242
</service>
4343
</services>

Resources/doc/custom_db_driver.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
Custom db driver.
2+
=================
3+
4+
The bundle provides drivers for Doctrine ORM, Doctrine MongoDB, and Propel libraries.
5+
Though sometimes you might want to use the bundle with a custom or in-house written storage.
6+
For that, the bundle has support for custom storage.
7+
Once set, setting manager options in fos_oauth_server.service section becomes mandatory.
8+
9+
Here's an example of custom configuration:
10+
11+
```yaml
12+
# config/packages/fos_oauth_server.yaml
13+
14+
fos_oauth_server:
15+
db_driver: custom
16+
service:
17+
user_provider: 'user_provider_manager_service_id'
18+
client_manager: 'client_provider_manager_service_id'
19+
access_token_manager: 'access_token_manager_service_id'
20+
refresh_token_manager: 'refresh_token_manager_service_id'
21+
auth_code_manager: 'auth_code_manager_service_id'
22+
23+
```
24+
25+
[Back to index](index.md)
26+

Resources/doc/index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,3 +619,5 @@ The `authorize` endpoint is at `/oauth/v2/auth` by default (see `Resources/confi
619619
[The OAuthEvent class](the_oauth_event_class.md)
620620

621621
[Adding Grant Extensions](adding_grant_extensions.md)
622+
623+
[Custom DB Driver](custom_db_driver.md)
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
<?php
2+
namespace FOS\OAuthServerBundle\Tests\DependencyInjection;
3+
4+
use FOS\OAuthServerBundle\DependencyInjection\Configuration;
5+
use Symfony\Component\Config\Definition\ConfigurationInterface;
6+
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
7+
use Symfony\Component\Config\Definition\Processor;
8+
9+
class ConfigurationTest extends \PHPUnit_Framework_TestCase
10+
{
11+
public function testShouldImplementConfigurationInterface()
12+
{
13+
$rc = new \ReflectionClass(Configuration::class);
14+
15+
$this->assertTrue($rc->implementsInterface(ConfigurationInterface::class));
16+
}
17+
public function testCouldBeConstructedWithoutAnyArguments()
18+
{
19+
new Configuration();
20+
}
21+
22+
public function testShouldNotMandatoryServiceIfNotCustomDriverIsUsed()
23+
{
24+
$configuration = new Configuration();
25+
$processor = new Processor();
26+
27+
$config = $processor->processConfiguration($configuration, [[
28+
'db_driver' => 'orm',
29+
'client_class' => 'aClientClass',
30+
'access_token_class' => 'anAccessTokenClass',
31+
'refresh_token_class' => 'aRefreshTokenClass',
32+
'auth_code_class' => 'anAuthCodeClass',
33+
]]);
34+
35+
$this->assertArraySubset([
36+
"db_driver" => "orm",
37+
"client_class" => "aClientClass",
38+
"access_token_class" => "anAccessTokenClass",
39+
"refresh_token_class" => "aRefreshTokenClass",
40+
"auth_code_class" => "anAuthCodeClass",
41+
"service" => [
42+
"storage" => "fos_oauth_server.storage.default",
43+
"user_provider" => null,
44+
"client_manager" => "fos_oauth_server.client_manager.default",
45+
"access_token_manager" => "fos_oauth_server.access_token_manager.default",
46+
"refresh_token_manager" => "fos_oauth_server.refresh_token_manager.default",
47+
"auth_code_manager" => "fos_oauth_server.auth_code_manager.default",
48+
],
49+
], $config);
50+
}
51+
52+
public function testShouldMakeClientManagerServiceMandatoryIfCustomDriverIsUsed()
53+
{
54+
$configuration = new Configuration();
55+
$processor = new Processor();
56+
57+
$this->setExpectedException(InvalidConfigurationException::class, 'Invalid configuration for path "fos_oauth_server": The service client_manager must be set explicitly for custom db_driver.');
58+
59+
$processor->processConfiguration($configuration, [[
60+
'db_driver' => 'custom',
61+
'client_class' => 'aClientClass',
62+
'access_token_class' => 'anAccessTokenClass',
63+
'refresh_token_class' => 'aRefreshTokenClass',
64+
'auth_code_class' => 'anAuthCodeClass',
65+
66+
]]);
67+
}
68+
69+
public function testShouldMakeAccessTokenManagerServiceMandatoryIfCustomDriverIsUsed()
70+
{
71+
$configuration = new Configuration();
72+
$processor = new Processor();
73+
74+
$this->setExpectedException(InvalidConfigurationException::class, 'Invalid configuration for path "fos_oauth_server": The service access_token_manager must be set explicitly for custom db_driver.');
75+
76+
$processor->processConfiguration($configuration, [[
77+
'db_driver' => 'custom',
78+
'client_class' => 'aClientClass',
79+
'access_token_class' => 'anAccessTokenClass',
80+
'refresh_token_class' => 'aRefreshTokenClass',
81+
'auth_code_class' => 'anAuthCodeClass',
82+
'service' => [
83+
'client_manager' => 'a_client_manager_id'
84+
]
85+
]]);
86+
}
87+
88+
public function testShouldMakeRefreshTokenManagerServiceMandatoryIfCustomDriverIsUsed()
89+
{
90+
$configuration = new Configuration();
91+
$processor = new Processor();
92+
93+
$this->setExpectedException(InvalidConfigurationException::class, 'Invalid configuration for path "fos_oauth_server": The service refresh_token_manager must be set explicitly for custom db_driver.');
94+
95+
$processor->processConfiguration($configuration, [[
96+
'db_driver' => 'custom',
97+
'client_class' => 'aClientClass',
98+
'access_token_class' => 'anAccessTokenClass',
99+
'refresh_token_class' => 'aRefreshTokenClass',
100+
'auth_code_class' => 'anAuthCodeClass',
101+
'service' => [
102+
'client_manager' => 'a_client_manager_id',
103+
'access_token_manager' => 'anId',
104+
]
105+
]]);
106+
}
107+
108+
public function testShouldMakeAuthCodeManagerServiceMandatoryIfCustomDriverIsUsed()
109+
{
110+
$configuration = new Configuration();
111+
$processor = new Processor();
112+
113+
$this->setExpectedException(InvalidConfigurationException::class, 'Invalid configuration for path "fos_oauth_server": The service auth_code_manager must be set explicitly for custom db_driver.');
114+
115+
$processor->processConfiguration($configuration, [[
116+
'db_driver' => 'custom',
117+
'client_class' => 'aClientClass',
118+
'access_token_class' => 'anAccessTokenClass',
119+
'refresh_token_class' => 'aRefreshTokenClass',
120+
'auth_code_class' => 'anAuthCodeClass',
121+
'service' => [
122+
'client_manager' => 'a_client_manager_id',
123+
'access_token_manager' => 'anId',
124+
'refresh_token_manager' => 'anId',
125+
126+
]
127+
]]);
128+
}
129+
130+
public function testShouldLoadCustomDriverConfig()
131+
{
132+
$configuration = new Configuration();
133+
$processor = new Processor();
134+
135+
$config = $processor->processConfiguration($configuration, [[
136+
'db_driver' => 'custom',
137+
'client_class' => 'aClientClass',
138+
'access_token_class' => 'anAccessTokenClass',
139+
'refresh_token_class' => 'aRefreshTokenClass',
140+
'auth_code_class' => 'anAuthCodeClass',
141+
'service' => [
142+
'client_manager' => 'a_client_manager_id',
143+
'access_token_manager' => 'an_access_token_manager_id',
144+
'refresh_token_manager' => 'a_refresh_token_manager_id',
145+
'auth_code_manager' => 'an_auth_code_manager_id',
146+
]
147+
]]);
148+
149+
$this->assertArraySubset([
150+
"db_driver" => "custom",
151+
"client_class" => "aClientClass",
152+
"access_token_class" => "anAccessTokenClass",
153+
"refresh_token_class" => "aRefreshTokenClass",
154+
"auth_code_class" => "anAuthCodeClass",
155+
"service" => [
156+
"storage" => "fos_oauth_server.storage.default",
157+
"user_provider" => null,
158+
"client_manager" => "a_client_manager_id",
159+
"access_token_manager" => "an_access_token_manager_id",
160+
"refresh_token_manager" => "a_refresh_token_manager_id",
161+
"auth_code_manager" => "an_auth_code_manager_id",
162+
],
163+
], $config);
164+
}
165+
}

Tests/DependencyInjection/FOSOAuthServerExtensionTest.php

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* file that was distributed with this source code.
1010
*/
1111

12-
namespace DependencyInjection;
12+
namespace FOS\OAuthServerBundle\Tests\DependencyInjection;
1313

1414
use FOS\OAuthServerBundle\DependencyInjection\FOSOAuthServerExtension;
1515
use Symfony\Component\Config\FileLocator;
@@ -92,4 +92,41 @@ public function testLoadTokenRouting()
9292
$this->assertEquals('/oauth/v2/token', $tokenRoute->getPath());
9393
$this->assertEquals(array('GET', 'POST'), $tokenRoute->getMethods());
9494
}
95+
96+
public function testShouldAliasServivesWhenCustomDriverIsUsed()
97+
{
98+
$container = new ContainerBuilder();
99+
$extension = new FOSOAuthServerExtension();
100+
$extension->load([[
101+
'db_driver' => 'custom',
102+
'client_class' => 'aClientClass',
103+
'access_token_class' => 'anAccessTokenClass',
104+
'refresh_token_class' => 'aRefreshTokenClass',
105+
'auth_code_class' => 'anAuthCodeClass',
106+
"service" => [
107+
"storage" => "fos_oauth_server.storage.default",
108+
"user_provider" => null,
109+
"client_manager" => "the_client_manager_id",
110+
"access_token_manager" => "the_access_token_manager_id",
111+
"refresh_token_manager" => "the_refresh_token_manager_id",
112+
"auth_code_manager" => "the_auth_code_manager_id",
113+
],
114+
]], $container);
115+
116+
117+
$this->assertTrue($container->hasAlias('fos_oauth_server.storage'));
118+
$this->assertSame('fos_oauth_server.storage.default', (string) $container->getAlias('fos_oauth_server.storage'));
119+
120+
$this->assertTrue($container->hasAlias('fos_oauth_server.client_manager'));
121+
$this->assertSame('the_client_manager_id', (string) $container->getAlias('fos_oauth_server.client_manager'));
122+
123+
$this->assertTrue($container->hasAlias('fos_oauth_server.access_token_manager'));
124+
$this->assertSame('the_access_token_manager_id', (string) $container->getAlias('fos_oauth_server.access_token_manager'));
125+
126+
$this->assertTrue($container->hasAlias('fos_oauth_server.refresh_token_manager'));
127+
$this->assertSame('the_refresh_token_manager_id', (string) $container->getAlias('fos_oauth_server.refresh_token_manager'));
128+
129+
$this->assertTrue($container->hasAlias('fos_oauth_server.auth_code_manager'));
130+
$this->assertSame('the_auth_code_manager_id', (string) $container->getAlias('fos_oauth_server.auth_code_manager'));
131+
}
95132
}

0 commit comments

Comments
 (0)