Skip to content

Commit e8d96b0

Browse files
Merge pull request #2 from VincentChalnot/v2.x
New v2.0 version for Sf5+ and PHP8.1, better overall exception management and token retrieval.
2 parents ca2a488 + 1ad2619 commit e8d96b0

24 files changed

+179
-83
lines changed

CleverAgeOAuthApiBundle.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<?php
22
/*
3-
* This file is part of the CleverAge/OAuthApiBundle package. * Copyright (C) 2017-2021 Clever-Age * For the full copyright and license information, please view the LICENSE
3+
* This file is part of the CleverAge/OAuthApiBundle package.
4+
* Copyright (C) 2017-2023 Clever-Age
5+
* For the full copyright and license information, please view the LICENSE
46
* file that was distributed with this source code.
57
*/
68
declare(strict_types=1);

Client/ApiClient.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<?php
22
/*
3-
* This file is part of the CleverAge/OAuthApiBundle package. * Copyright (C) 2017-2021 Clever-Age * For the full copyright and license information, please view the LICENSE
3+
* This file is part of the CleverAge/OAuthApiBundle package.
4+
* Copyright (C) 2017-2023 Clever-Age
5+
* For the full copyright and license information, please view the LICENSE
46
* file that was distributed with this source code.
57
*/
68
declare(strict_types=1);
@@ -11,11 +13,11 @@
1113
use CleverAge\OAuthApiBundle\Exception\ApiRequestException;
1214
use CleverAge\OAuthApiBundle\Exception\RequestFailedException;
1315
use CleverAge\OAuthApiBundle\Request\ApiRequestInterface;
14-
use Nyholm\Psr7\Stream;
1516
use Psr\Http\Client\ClientInterface;
1617
use Psr\Http\Client\RequestExceptionInterface;
1718
use Psr\Http\Message\RequestFactoryInterface;
1819
use Psr\Http\Message\RequestInterface;
20+
use Psr\Http\Message\StreamFactoryInterface;
1921
use Psr\Log\LoggerInterface;
2022
use Symfony\Component\Serializer\SerializerInterface;
2123

@@ -27,6 +29,7 @@ class ApiClient implements ApiClientInterface
2729
public function __construct(
2830
protected ClientInterface $client,
2931
protected RequestFactoryInterface $requestFactory,
32+
protected StreamFactoryInterface $streamFactory,
3033
protected SerializerInterface $serializer,
3134
protected LoggerInterface $logger,
3235
) {
@@ -77,7 +80,7 @@ protected function getRequest(ApiRequestInterface $apiRequest): RequestInterface
7780
$apiRequest->getSerializationContext()
7881
);
7982

80-
return $request->withBody(Stream::create($serializedContent));
83+
return $request->withBody($this->streamFactory->createStream($serializedContent));
8184
}
8285

8386
protected function getResponseData(

Client/ApiClientInterface.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<?php
22
/*
3-
* This file is part of the CleverAge/OAuthApiBundle package. * Copyright (C) 2017-2021 Clever-Age * For the full copyright and license information, please view the LICENSE
3+
* This file is part of the CleverAge/OAuthApiBundle package.
4+
* Copyright (C) 2017-2023 Clever-Age
5+
* For the full copyright and license information, please view the LICENSE
46
* file that was distributed with this source code.
57
*/
68
declare(strict_types=1);
@@ -10,7 +12,7 @@
1012
use CleverAge\OAuthApiBundle\Request\ApiRequestInterface;
1113

1214
/**
13-
* Base logic used to query a remote API object
15+
* Base logic used to query a remote API object.
1416
*/
1517
interface ApiClientInterface
1618
{

Client/CachedApiClient.php

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<?php
22
/*
3-
* This file is part of the CleverAge/OAuthApiBundle package. * Copyright (C) 2017-2021 Clever-Age * For the full copyright and license information, please view the LICENSE
3+
* This file is part of the CleverAge/OAuthApiBundle package.
4+
* Copyright (C) 2017-2023 Clever-Age
5+
* For the full copyright and license information, please view the LICENSE
46
* file that was distributed with this source code.
57
*/
68
declare(strict_types=1);
@@ -12,26 +14,29 @@
1214
use Psr\Http\Client\ClientInterface;
1315
use Psr\Http\Message\RequestFactoryInterface;
1416
use Psr\Http\Message\RequestInterface;
17+
use Psr\Http\Message\StreamFactoryInterface;
1518
use Psr\Log\LoggerInterface;
1619
use Symfony\Component\Serializer\SerializerInterface;
1720
use Symfony\Contracts\Cache\ItemInterface;
1821
use Symfony\Contracts\Cache\TagAwareCacheInterface;
1922

2023
/**
21-
* Api client improved with caching capabilities
24+
* Api client improved with caching capabilities.
2225
*/
2326
class CachedApiClient extends ApiClient implements CachedApiClientInterface
2427
{
2528
public function __construct(
2629
ClientInterface $client,
2730
RequestFactoryInterface $requestFactory,
31+
StreamFactoryInterface $streamFactory,
2832
SerializerInterface $serializer,
2933
LoggerInterface $logger,
3034
protected TagAwareCacheInterface $cache,
3135
) {
3236
parent::__construct(
3337
client: $client,
3438
requestFactory: $requestFactory,
39+
streamFactory: $streamFactory,
3540
serializer: $serializer,
3641
logger: $logger,
3742
);
@@ -80,13 +85,11 @@ protected function getCacheKey(RequestInterface $request, bool $private): string
8085
{
8186
$subCacheKey = $request->getMethod().$request->getUri().$request->getBody();
8287
if ($private) {
83-
$client = $this->client;
84-
if (!$client instanceof OAuthTokenAwareRequestFactoryInterface) {
88+
if (!$this->requestFactory instanceof OAuthTokenAwareRequestFactoryInterface) {
8589
throw new \UnexpectedValueException('Unable to store private API cache, no private token available');
8690
}
87-
8891
// Append authorization token to cache key if private
89-
$subCacheKey .= $client->getToken()->getAuthorization();
92+
$subCacheKey .= $this->requestFactory->getToken()->getAuthorization();
9093
}
9194

9295
return sha1($subCacheKey);
@@ -97,12 +100,12 @@ protected function convertTags(array $tags, bool $private): array
97100
if (!$private) {
98101
return $tags;
99102
}
100-
if (!$this->client instanceof OAuthTokenAwareRequestFactoryInterface) {
103+
if (!$this->requestFactory instanceof OAuthTokenAwareRequestFactoryInterface) {
101104
throw new \UnexpectedValueException('Unable to store private API cache, no private token available');
102105
}
103106

104107
// Append authorization token to cache key if private
105-
$subCacheKey = $this->client->getToken()->getAuthorization();
108+
$subCacheKey = $this->requestFactory->getToken()->getAuthorization();
106109
$privateTags = [];
107110
foreach ($tags as $tag) {
108111
$privateTags[] = $tag.'_'.$subCacheKey;

Client/CachedApiClientInterface.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
<?php
22
/*
3-
* This file is part of the CleverAge/OAuthApiBundle package. * Copyright (C) 2017-2021 Clever-Age * For the full copyright and license information, please view the LICENSE
3+
* This file is part of the CleverAge/OAuthApiBundle package.
4+
* Copyright (C) 2017-2023 Clever-Age
5+
* For the full copyright and license information, please view the LICENSE
46
* file that was distributed with this source code.
57
*/
68
declare(strict_types=1);
79

810
namespace CleverAge\OAuthApiBundle\Client;
911

1012
/**
11-
* Additional method to manage cache for API requests
13+
* Additional method to manage cache for API requests.
1214
*/
1315
interface CachedApiClientInterface extends ApiClientInterface
1416
{

Client/OAuthRequestFactory.php

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
<?php
22
/*
3-
* This file is part of the CleverAge/OAuthApiBundle package. * Copyright (C) 2017-2021 Clever-Age * For the full copyright and license information, please view the LICENSE
3+
* This file is part of the CleverAge/OAuthApiBundle package.
4+
* Copyright (C) 2017-2023 Clever-Age
5+
* For the full copyright and license information, please view the LICENSE
46
* file that was distributed with this source code.
57
*/
68
declare(strict_types=1);
79

810
namespace CleverAge\OAuthApiBundle\Client;
911

1012
use CleverAge\OAuthApiBundle\Exception\OAuthAuthenticationException;
11-
use CleverAge\OAuthApiBundle\Token\OAuthToken;
13+
use CleverAge\OAuthApiBundle\Token\OAuthTokenFactoryInterface;
1214
use CleverAge\OAuthApiBundle\Token\OAuthTokenInterface;
13-
use Nyholm\Psr7\Stream;
1415
use Psr\Http\Client\ClientInterface;
1516
use Psr\Http\Message\RequestFactoryInterface;
1617
use Psr\Http\Message\RequestInterface;
18+
use Psr\Http\Message\StreamFactoryInterface;
1719

1820
/**
19-
* Handles authentication token negotiation to simplify request creation
21+
* Handles authentication token negotiation to simplify request creation.
2022
*/
2123
class OAuthRequestFactory implements OAuthTokenAwareRequestFactoryInterface
2224
{
@@ -25,9 +27,12 @@ class OAuthRequestFactory implements OAuthTokenAwareRequestFactoryInterface
2527
public function __construct(
2628
protected ClientInterface $client,
2729
protected RequestFactoryInterface $requestFactory,
30+
protected StreamFactoryInterface $streamFactory,
31+
protected OAuthTokenFactoryInterface $tokenFactory,
2832
protected string $baseUrl,
2933
protected string $tokenRequestPath,
3034
protected array $authenticationParams,
35+
protected string $tokenRequestContentType = 'application/json',
3136
) {
3237
}
3338

@@ -40,20 +45,18 @@ public function createRequest(string $method, $uri): RequestInterface
4045
public function getToken(): OAuthTokenInterface
4146
{
4247
if (!$this->token) {
43-
$this->token = $this->updateToken(
44-
$this->createTokenRequest(),
45-
static function (array $data) {
46-
return OAuthToken::createFromResponse($data);
47-
}
48-
);
48+
$this->token = $this->updateToken($this->createTokenRequest());
4949
}
5050

5151
return $this->token;
5252
}
5353

54-
protected function updateToken(RequestInterface $request, callable $method): OAuthTokenInterface
54+
protected function updateToken(RequestInterface $request): OAuthTokenInterface
5555
{
5656
$response = $this->client->sendRequest($request);
57+
if (200 !== $response->getStatusCode()) {
58+
throw OAuthAuthenticationException::createFromTokenResponse($response, $this->tokenRequestPath);
59+
}
5760

5861
$content = (string) $response->getBody();
5962
if (!$content) {
@@ -66,16 +69,26 @@ protected function updateToken(RequestInterface $request, callable $method): OAu
6669
}
6770

6871
try {
69-
return $method($data);
72+
return $this->tokenFactory->createToken($data);
7073
} catch (\Exception) {
7174
throw OAuthAuthenticationException::createFromTokenResponse($response, $this->tokenRequestPath);
7275
}
7376
}
7477

7578
protected function createTokenRequest(): RequestInterface
7679
{
77-
return $this->requestFactory->createRequest('POST', $this->baseUrl.$this->tokenRequestPath)
78-
->withHeader('Content-Type', 'application/x-www-form-urlencoded')
79-
->withBody(Stream::create(http_build_query($this->authenticationParams)));
80+
$tokenRequest = $this->requestFactory->createRequest('POST', $this->baseUrl.$this->tokenRequestPath)
81+
->withHeader('Content-Type', $this->tokenRequestContentType);
82+
83+
if ('application/x-www-form-urlencoded' === $this->tokenRequestContentType) {
84+
$content = http_build_query($this->authenticationParams);
85+
} elseif ('application/json' === $this->tokenRequestContentType) {
86+
$content = json_encode($this->authenticationParams, JSON_THROW_ON_ERROR);
87+
} else {
88+
$m = "Unsupported token request content type {$this->tokenRequestContentType}";
89+
throw new \UnexpectedValueException($m);
90+
}
91+
92+
return $tokenRequest->withBody($this->streamFactory->createStream($content));
8093
}
8194
}

Client/OAuthTokenAwareRequestFactoryInterface.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<?php
22
/*
3-
* This file is part of the CleverAge/OAuthApiBundle package. * Copyright (C) 2017-2021 Clever-Age * For the full copyright and license information, please view the LICENSE
3+
* This file is part of the CleverAge/OAuthApiBundle package.
4+
* Copyright (C) 2017-2023 Clever-Age
5+
* For the full copyright and license information, please view the LICENSE
46
* file that was distributed with this source code.
57
*/
68
declare(strict_types=1);
@@ -11,7 +13,7 @@
1113
use Psr\Http\Message\RequestFactoryInterface;
1214

1315
/**
14-
* Defines an HTTP client that can provide an OAuth Token
16+
* Defines an HTTP client that can provide an OAuth Token.
1517
*/
1618
interface OAuthTokenAwareRequestFactoryInterface extends RequestFactoryInterface
1719
{

Exception/ApiDeserializationException.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
<?php
22
/*
3-
* This file is part of the CleverAge/OAuthApiBundle package. * Copyright (C) 2017-2021 Clever-Age * For the full copyright and license information, please view the LICENSE
3+
* This file is part of the CleverAge/OAuthApiBundle package.
4+
* Copyright (C) 2017-2023 Clever-Age
5+
* For the full copyright and license information, please view the LICENSE
46
* file that was distributed with this source code.
57
*/
68
declare(strict_types=1);
79

810
namespace CleverAge\OAuthApiBundle\Exception;
911

1012
/**
11-
* Thrown when not able to deserialize a response from the API
13+
* Thrown when not able to deserialize a response from the API.
1214
*/
1315
class ApiDeserializationException extends \RuntimeException
1416
{

Exception/ApiRequestException.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
<?php
22
/*
3-
* This file is part of the CleverAge/OAuthApiBundle package. * Copyright (C) 2017-2021 Clever-Age * For the full copyright and license information, please view the LICENSE
3+
* This file is part of the CleverAge/OAuthApiBundle package.
4+
* Copyright (C) 2017-2023 Clever-Age
5+
* For the full copyright and license information, please view the LICENSE
46
* file that was distributed with this source code.
57
*/
68
declare(strict_types=1);
79

810
namespace CleverAge\OAuthApiBundle\Exception;
911

1012
/**
11-
* Thrown when unable to request a remote API
13+
* Thrown when unable to request a remote API.
1214
*/
1315
class ApiRequestException extends \RuntimeException
1416
{

Exception/ClientRequestFailedException.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<?php
22
/*
3-
* This file is part of the CleverAge/OAuthApiBundle package. * Copyright (C) 2017-2021 Clever-Age * For the full copyright and license information, please view the LICENSE
3+
* This file is part of the CleverAge/OAuthApiBundle package.
4+
* Copyright (C) 2017-2023 Clever-Age
5+
* For the full copyright and license information, please view the LICENSE
46
* file that was distributed with this source code.
57
*/
68
declare(strict_types=1);

0 commit comments

Comments
 (0)