Skip to content

Updated the authentication configuration to support credentials #44

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 28, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 79 additions & 11 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,17 +120,7 @@ protected function configurePlugins(ArrayNodeDefinition $root)
->arrayNode('plugins')
->addDefaultsIfNotSet()
->children()

->arrayNode('authentication')
->canBeEnabled()
->children()
->scalarNode('authentication')
->info('This must be a service id to a service implementing Http\Message\Authentication')
->isRequired()
->cannotBeEmpty()
->end()
->end()
->end() // End authentication plugin
->append($this->addAuthenticationPluiginNode())

->arrayNode('cache')
->canBeEnabled()
Expand Down Expand Up @@ -235,4 +225,82 @@ protected function configurePlugins(ArrayNodeDefinition $root)
->end()
->end();
}

/**
* Add configuration for authentication plugin.
*
* @return ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\NodeDefinition
*/
private function addAuthenticationPluiginNode()
{
$builder = new TreeBuilder();
$node = $builder->root('authentication');
$node
->useAttributeAsKey('name')
->prototype('array')
->validate()
->always()
->then(function ($config) {
switch ($config['type']) {
case 'basic':
$this->validateAuthenticationType(['username', 'password'], $config, 'basic');
break;
case 'bearer':
$this->validateAuthenticationType(['token'], $config, 'bearer');
break;
case 'service':
$this->validateAuthenticationType(['service'], $config, 'service');
break;
case 'wsse':
$this->validateAuthenticationType(['username', 'password'], $config, 'wsse');
break;
}

return $config;
})
->end()
->children()
->enumNode('type')
->values(['basic', 'bearer', 'wsse', 'service'])
->isRequired()
->cannotBeEmpty()
->end()
->scalarNode('username')->end()
->scalarNode('password')->end()
->scalarNode('token')->end()
->scalarNode('service')->end()
->end()
->end()
->end(); // End authentication plugin

return $node;
}

/**
* Validate that the configuration fragment has the specified keys and none other.
*
* @param array $expected Fields that must exist
* @param array $actual Actual configuration hashmap
* @param string $authName Name of authentication method for error messages
*
* @throws InvalidConfigurationException If $actual does not have exactly the keys specified in $expected (plus 'type')
*/
private function validateAuthenticationType(array $expected, array $actual, $authName)
{
unset($actual['type']);
$actual = array_keys($actual);
sort($actual);
sort($expected);

if ($expected === $actual) {
return;
}

throw new InvalidConfigurationException(sprintf(
'Authentication "%s" requires %s but got %s',
$authName,
implode(', ', $expected),
implode(', ', $actual)
));
}
}
48 changes: 45 additions & 3 deletions DependencyInjection/HttplugExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

namespace Http\HttplugBundle\DependencyInjection;

use Http\Client\Plugin\AuthenticationPlugin;
use Http\Client\Plugin\PluginClient;
use Http\HttplugBundle\ClientFactory\DummyClient;
use Http\Message\Authentication\BasicAuth;
use Http\Message\Authentication\Bearer;
use Http\Message\Authentication\Wsse;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
Expand Down Expand Up @@ -106,6 +110,11 @@ private function configureClients(ContainerBuilder $container, array $config)
*/
private function configurePlugins(ContainerBuilder $container, array $config)
{
if (!empty($config['authentication'])) {
$this->configureAuthentication($container, $config['authentication']);
}
unset($config['authentication']);

foreach ($config as $name => $pluginConfig) {
$pluginId = 'httplug.plugin.'.$name;
if ($pluginConfig['enabled']) {
Expand All @@ -125,9 +134,6 @@ private function configurePlugins(ContainerBuilder $container, array $config)
private function configurePluginByName($name, Definition $definition, array $config)
{
switch ($name) {
case 'authentication':
$definition->replaceArgument(0, new Reference($config['authentication']));
break;
case 'cache':
$definition
->replaceArgument(0, new Reference($config['cache_pool']))
Expand Down Expand Up @@ -162,4 +168,40 @@ private function configurePluginByName($name, Definition $definition, array $con
break;
}
}

/**
* @param ContainerBuilder $container
* @param Definition $parent
* @param array $config
*/
private function configureAuthentication(ContainerBuilder $container, array $config)
{
foreach ($config as $name => $values) {
$authServiceKey = sprintf('httplug.plugin.authentication.%s.auth', $name);
switch ($values['type']) {
case 'bearer':
$container->register($authServiceKey, Bearer::class)
->addArgument($values['token']);
break;
case 'basic':
$container->register($authServiceKey, BasicAuth::class)
->addArgument($values['username'])
->addArgument($values['password']);
break;
case 'wsse':
$container->register($authServiceKey, Wsse::class)
->addArgument($values['username'])
->addArgument($values['password']);
break;
case 'service':
$authServiceKey = $values['service'];
break;
default:
throw new \LogicException(sprintf('Unknown authentication type: "%s"', $values['type']));
}

$container->register('httplug.plugin.authentication.'.$name, AuthenticationPlugin::class)
->addArgument(new Reference($authServiceKey));
}
}
}
30 changes: 29 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ For information how to write applications with the services provided by this bun
| httplug.client.[name] | This is your Httpclient that you have configured. With the configuration below the name would be `acme_client`.
| httplug.client | This is the first client configured or a client named `default`.
| httplug.plugin.content_length <br> httplug.plugin.decoder<br> httplug.plugin.error<br> httplug.plugin.logger<br> httplug.plugin.redirect<br> httplug.plugin.retry<br> httplug.plugin.stopwatch | These are plugins that are enabled by default. These services are not public and may only be used when configure HttpClients or other services.
| httplug.plugin.authentication <br> httplug.plugin.cache<br> httplug.plugin.cookie<br> httplug.plugin.history | These are plugins that are disabled by default. They need to be configured before they can be used. These services are not public and may only be used when configure HttpClients or other services.
| httplug.plugin.cache<br> httplug.plugin.cookie<br> httplug.plugin.history | These are plugins that are disabled by default. They need to be configured before they can be used. These services are not public and may only be used when configure HttpClients or other services.

\* *These services are always an alias to another service. You can specify your own service or leave the default, which is the same name with `.default` appended. The default services in turn use the service discovery mechanism to provide the best available implementation. You can specify a class for each of the default services to use instead of discovery, as long as those classes can be instantiated without arguments.*

Expand Down Expand Up @@ -134,6 +134,34 @@ httpug:
base_uri: 'http://google.se/'
```

#### Authentication

```yaml
// config.yml
httpug:
plugins:
authentication:
my_basic:
type: 'basic'
username: 'my_username'
password: 'p4ssw0rd'
my_wsse:
type: 'wsse'
username: 'my_username'
password: 'p4ssw0rd'
my_brearer:
type: 'bearer'
token: 'authentication_token_hash'
my_service:
type: 'service'
service: 'my_authentication_service'

clients:
acme:
factory: 'httplug.factory.guzzle6'
plugins: ['httplug.plugin.authentication.my_wsse']
```


### Use for Reusable Bundles

Expand Down
3 changes: 0 additions & 3 deletions Resources/config/plugins.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

<services>
<service id="httplug.plugin.authentication" class="Http\Client\Plugin\AuthenticationPlugin" public="false">
<argument />
</service>
<service id="httplug.plugin.cache" class="Http\Client\Plugin\CachePlugin" public="false">
<argument />
<argument />
Expand Down
55 changes: 55 additions & 0 deletions Tests/Resources/Fixtures/config/full.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,59 @@
'uri_factory' => 'Http\Message\UriFactory\GuzzleUriFactory',
'stream_factory' => 'Http\Message\StreamFactory\GuzzleStreamFactory',
],
'toolbar' => [
'enabled' => true,
'formatter' => 'my_toolbar_formatter',
],
'plugins' => [
'authentication' => [
'my_basic' => [
'type' => 'basic',
'username' => 'foo',
'password' => 'bar',
],
'my_wsse' => [
'type' => 'wsse',
'username' => 'foo',
'password' => 'bar',
],
'my_bearer' => [
'type' => 'bearer',
'token' => 'foo',
],
'my_service' => [
'type' => 'service',
'service' => 'my_auth_service',
],
],
'cache' => [
'cache_pool' => 'my_cache_pool',
'stream_factory' => 'my_other_stream_factory',
'config' => [
'default_ttl' => 42,
'respect_cache_headers' => false,
],
],
'cookie' => [
'cookie_jar' => 'my_cookie_jar',
],
'decoder' => [
'enabled' => false,
],
'history' => [
'journal' => 'my_journal',
],
'logger' => [
'enabled' => false,
],
'redirect' => [
'enabled' => false,
],
'retry' => [
'enabled' => false,
],
'stopwatch' => [
'enabled' => false,
],
],
]);
19 changes: 19 additions & 0 deletions Tests/Resources/Fixtures/config/full.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,25 @@
<uri-factory>Http\Message\UriFactory\GuzzleUriFactory</uri-factory>
<stream-factory>Http\Message\StreamFactory\GuzzleStreamFactory</stream-factory>
</classes>
<toolbar enabled="true" formatter="my_toolbar_formatter"/>
<plugins>
<authentication>
<my_basic type="basic" username="foo" password="bar"/>
<my_wsse type="wsse" username="foo" password="bar"/>
<my_bearer type="bearer" token="foo"/>
<my_service type="service" service="my_auth_service"/>
</authentication>
<cache cache-pool="my_cache_pool" stream-factory="my_other_stream_factory">
<config default-ttl="42" respect-cache-headers="false"/>
</cache>
<cookie cookie-jar="my_cookie_jar"/>
<decoder enabled="false"/>
<history journal="my_journal"/>
<logger enabled="false"/>
<redirect enabled="false"/>
<retry enabled="false"/>
<stopwatch enabled="false"/>
</plugins>
</config>

</container>
41 changes: 40 additions & 1 deletion Tests/Resources/Fixtures/config/full.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,43 @@ httplug:
client: Http\Adapter\Guzzle6\Client
message_factory: Http\Message\MessageFactory\GuzzleMessageFactory
uri_factory: Http\Message\UriFactory\GuzzleUriFactory
stream_factory: Http\Message\StreamFactory\GuzzleStreamFactory
stream_factory: Http\Message\StreamFactory\GuzzleStreamFactory
toolbar:
enabled: true
formatter: my_toolbar_formatter
plugins:
authentication:
my_basic:
type: basic
username: foo
password: bar
my_wsse:
type: wsse
username: foo
password: bar
my_bearer:
type: bearer
token: foo
my_service:
type: service
service: my_auth_service
cache:
cache_pool: my_cache_pool
stream_factory: my_other_stream_factory
config:
default_ttl: 42
respect_cache_headers: false
cookie:
cookie_jar: my_cookie_jar
decoder:
enabled: false
history:
journal: my_journal
logger:
enabled: false
redirect:
enabled: false
retry:
enabled: false
stopwatch:
enabled: false
8 changes: 8 additions & 0 deletions Tests/Resources/Fixtures/config/invalid_auth.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
httplug:
plugins:
authentication:
my_auth:
type: service
service: foobar
username: user
password: pass
Loading