Skip to content

Commit

Permalink
Merge 52c1c12 into 615f6e9
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisivens committed Dec 20, 2018
2 parents 615f6e9 + 52c1c12 commit ac5b884
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 10 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ eight_points_guzzle:
| scope | One or more scope values indicating which parts of the user's account you wish to access | no | administration |
| audience | | no | |
| grant_type | Grant type class path. Class should implement GrantTypeInterface. <br/> Default: `Sainsburys\\Guzzle\\Oauth2\\GrantType\\ClientCredentials` | no | `Sainsburys\\Guzzle\\Oauth2\\GrantType\\PasswordCredentials`<br/>`Sainsburys\\Guzzle\\Oauth2\\GrantType\\AuthorizationCode`<br/>`Sainsburys\\Guzzle\\Oauth2\\GrantType\\JwtBearer` |
| persistent | Token will be stored in session. <br/> Default: false | no | |
| persistent | Token will be stored in session unless grant_type is client credentials; in which case it will be stored in the app cache. <br/> Default: false | no | |
| retry_limit | How many times request will be repeated on failure. <br/> Default: 5 | no | |

See more information about middleware [here][3].
Expand Down
1 change: 0 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"keywords": ["oauth2", "middleware", "plugin", "framework", "http", "rest", "web service", "curl", "client", "HTTP client"],
"homepage": "https://github.com/gregurco/GuzzleBundleOAuth2Plugin",
"license": "MIT",

"authors": [
{
"name": "Gregurco Vlad",
Expand Down
32 changes: 24 additions & 8 deletions src/GuzzleBundleOAuth2Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Sainsburys\Guzzle\Oauth2\GrantType\JwtBearer;
use Sainsburys\Guzzle\Oauth2\GrantType\PasswordCredentials;
use Sainsburys\Guzzle\Oauth2\GrantType\RefreshToken;
use Symfony\Component\Cache\Adapter\AdapterInterface;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpKernel\Bundle\Bundle;
Expand Down Expand Up @@ -90,14 +91,29 @@ public function loadForClient(array $config, ContainerBuilder $container, string
//Define middleware
$oAuth2MiddlewareDefinitionName = sprintf('guzzle_bundle_oauth2_plugin.middleware.%s', $clientName);
if ($config['persistent']) {
$oAuth2MiddlewareDefinition = new Definition('%guzzle_bundle_oauth2_plugin.persistent_middleware.class%');
$oAuth2MiddlewareDefinition->setArguments([
new Reference($oauthClientDefinitionName),
new Reference($passwordCredentialsDefinitionName),
new Reference($refreshTokenDefinitionName),
new Reference('session'),
$clientName
]);
if ($config['grant_type'] === ClientCredentials::class) {
$oAuth2MiddlewareDefinition = new Definition('%guzzle_bundle_oauth2_plugin.cached_middleware.class%');
$oAuth2MiddlewareDefinition->setArguments(
[
new Reference($oauthClientDefinitionName),
new Reference($passwordCredentialsDefinitionName),
new Reference($refreshTokenDefinitionName),
new Reference(AdapterInterface::class),
$clientName
]
);
} else {
$oAuth2MiddlewareDefinition = new Definition('%guzzle_bundle_oauth2_plugin.persistent_middleware.class%');
$oAuth2MiddlewareDefinition->setArguments(
[
new Reference($oauthClientDefinitionName),
new Reference($passwordCredentialsDefinitionName),
new Reference($refreshTokenDefinitionName),
new Reference('session'),
$clientName
]
);
}
} else {
$oAuth2MiddlewareDefinition = new Definition('%guzzle_bundle_oauth2_plugin.middleware.class%');
$oAuth2MiddlewareDefinition->setArguments([
Expand Down
130 changes: 130 additions & 0 deletions src/Middleware/CachedOAuthMiddleware.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<?php

namespace Gregurco\Bundle\GuzzleBundleOAuth2Plugin\Middleware;

use GuzzleHttp\ClientInterface;
use Psr\Cache\InvalidArgumentException;
use Sainsburys\Guzzle\Oauth2\AccessToken;
use Sainsburys\Guzzle\Oauth2\GrantType\GrantTypeInterface;
use Sainsburys\Guzzle\Oauth2\GrantType\RefreshTokenGrantTypeInterface;
use Sainsburys\Guzzle\Oauth2\Middleware\OAuthMiddleware;
use Symfony\Component\Cache\Adapter\AdapterInterface;

class CachedOAuthMiddleware extends OAuthMiddleware
{
/**
* @var AdapterInterface cacheClient
*/
private $cacheClient;

/**
* @var string clientName
*/
private $clientName;

/**
* Create a new Oauth2 subscriber.
*
* @param ClientInterface $client
* @param GrantTypeInterface|null $grantType
* @param RefreshTokenGrantTypeInterface|null $refreshTokenGrantType
* @param AdapterInterface $cacheClient
* @param string $clientName
*/
public function __construct(
ClientInterface $client,
GrantTypeInterface $grantType = null,
RefreshTokenGrantTypeInterface $refreshTokenGrantType = null,
AdapterInterface $cacheClient,
string $clientName
) {
parent::__construct($client, $grantType, $refreshTokenGrantType);

$this->cacheClient = $cacheClient;
$this->clientName = $clientName;
}

/**
* Get a new access token.
*
* @throws InvalidArgumentException
*
* @return AccessToken|null
*/
protected function acquireAccessToken()
{
$token = parent::acquireAccessToken();

$this->cacheToken($token);

return $token;
}

/**
* cacheToken sets the token in the cache adapter
*
* @param AccessToken $token
*
* @throws InvalidArgumentException
*/
protected function cacheToken(AccessToken $token)
{
$item = $this->cacheClient->getItem(sprintf('oauth.token.%s', $this->clientName));

$item->set(
[
'token' => $token->getToken(),
'type' => $token->getType(),
'data' => $token->getData(),
]
);
$item->tag('oauth');
$expires = $token->getExpires();

if ($expires) {
$item->expiresAt($expires->sub(\DateInterval::createFromDateString('1 minute')));
}

$this->cacheClient->saveDeferred($item);
}

/**
* getAccessToken will get the oauth token from the cache if available
*
* @throws \Exception
* @throws InvalidArgumentException
*
* @return null|AccessToken
*/
public function getAccessToken()
{
if ($this->accessToken === null) {
$this->restoreTokenFromCache();
}

return parent::getAccessToken();
}

/**
* restoreTokenFromCache
*
* @throws \Exception
* @throws InvalidArgumentException
*/
protected function restoreTokenFromCache()
{
$item = $this->cacheClient->getItem(sprintf('oauth.token.%s', $this->clientName));

if ($item->isHit()) {
$tokenData = $item->get();

$this->setAccessToken(
new AccessToken(
$tokenData['token'],
$tokenData['type'],
$tokenData['data']
)
);
}
}
}
1 change: 1 addition & 0 deletions src/Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
<parameters>
<parameter key="guzzle_bundle_oauth2_plugin.middleware.class">Sainsburys\Guzzle\Oauth2\Middleware\OAuthMiddleware</parameter>
<parameter key="guzzle_bundle_oauth2_plugin.persistent_middleware.class">Gregurco\Bundle\GuzzleBundleOAuth2Plugin\Middleware\PersistentOAuthMiddleware</parameter>
<parameter key="guzzle_bundle_oauth2_plugin.cached_middleware.class">Gregurco\Bundle\GuzzleBundleOAuth2Plugin\Middleware\CachedOAuthMiddleware</parameter>
</parameters>
</container>

0 comments on commit ac5b884

Please sign in to comment.