Skip to content

Commit 0b1d176

Browse files
committed
Merge branch 'master' into 3.x
2 parents 4f637ec + 9df2924 commit 0b1d176

File tree

6 files changed

+72
-9
lines changed

6 files changed

+72
-9
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# OAuth 2.0 Client Changelog
22

3+
## 2.8.1
4+
5+
_Released: 2025-02-26_
6+
7+
* Only provide scopes in access token when set in options [#1053](https://github.com/thephpleague/oauth2-client/pull/1053)
8+
* Add missing `@throws` annotations for Guzzle exceptions [#1055](https://github.com/thephpleague/oauth2-client/pull/1055)
9+
310
## 2.8.0
411

512
_Released: 2024-12-11_

docs/Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ GEM
235235
minitest (5.25.4)
236236
net-http (0.6.0)
237237
uri
238-
nokogiri (1.17.0)
238+
nokogiri (1.18.3)
239239
mini_portile2 (~> 2.8.2)
240240
racc (~> 1.4)
241241
octokit (4.25.1)

docs/providers/thirdparty.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ Gateway | Composer Package | Maintainer
5353
[Dribbble](https://github.com/crewlabs/oauth2-dribbble) | crewlabs/oauth2-dribbble | [Crew Labs](https://crew.co/labs)
5454
[Dropbox](https://github.com/stevenmaguire/oauth2-dropbox) | stevenmaguire/oauth2-dropbox | [Steven Maguire](https://github.com/stevenmaguire)
5555
[Drupal](https://github.com/chrishemmings/oauth2-drupal) | chrishemmings/oauth2-drupal | [Chris Hemmings](https://github.com/chrishemmings)
56+
[Ebay](https://github.com/Gugiman/oauth2-ebay) | gugiman/oauth2-ebay | [Dennis Steffen](https://github.com/gugiman)
5657
[Ecwid](https://github.com/mugnate/oauth2-ecwid) | mugnate/oauth2-ecwid | [Nikolay Votintsev](https://github.com/votintsev)
5758
[Edenred](https://github.com/jzecca/oauth2-edenred) | jzecca/oauth2-edenred | [Jérôme Zecca](https://github.com/jzecca)
5859
[Elance](https://github.com/stevenmaguire/oauth2-elance) | stevenmaguire/oauth2-elance | [Steven Maguire](https://github.com/stevenmaguire)

src/Provider/AbstractProvider.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
namespace League\OAuth2\Client\Provider;
1919

2020
use GuzzleHttp\Exception\BadResponseException;
21+
use GuzzleHttp\Exception\GuzzleException;
2122
use InvalidArgumentException;
2223
use League\OAuth2\Client\Grant\AbstractGrant;
2324
use League\OAuth2\Client\Grant\GrantFactory;
@@ -621,16 +622,13 @@ protected function getAccessTokenRequest(array $params): RequestInterface
621622
* @throws ClientExceptionInterface
622623
* @throws IdentityProviderException
623624
* @throws UnexpectedValueException
625+
* @throws GuzzleException
624626
*/
625627
public function getAccessToken(mixed $grant, array $options = []): AccessTokenInterface
626628
{
627629
$grant = $this->verifyGrant($grant);
628630

629-
if (!isset($options['scope'])) {
630-
$options['scope'] = $this->getDefaultScopes();
631-
}
632-
633-
if (is_array($options['scope'])) {
631+
if (isset($options['scope']) && is_array($options['scope'])) {
634632
$separator = $this->getScopeSeparator();
635633
$options['scope'] = implode($separator, $options['scope']);
636634
}
@@ -758,6 +756,7 @@ public function getResponse(RequestInterface $request): ResponseInterface
758756
* @throws ClientExceptionInterface
759757
* @throws IdentityProviderException
760758
* @throws UnexpectedValueException
759+
* @throws GuzzleException
761760
*/
762761
public function getParsedResponse(RequestInterface $request): array
763762
{
@@ -914,6 +913,7 @@ abstract protected function createResourceOwner(array $response, AccessToken $to
914913
* @throws ClientExceptionInterface
915914
* @throws IdentityProviderException
916915
* @throws UnexpectedValueException
916+
* @throws GuzzleException
917917
*/
918918
public function getResourceOwner(AccessToken $token): ResourceOwnerInterface
919919
{
@@ -930,6 +930,7 @@ public function getResourceOwner(AccessToken $token): ResourceOwnerInterface
930930
* @throws ClientExceptionInterface
931931
* @throws IdentityProviderException
932932
* @throws UnexpectedValueException
933+
* @throws GuzzleException
933934
*/
934935
protected function fetchResourceOwnerDetails(AccessToken $token): array
935936
{

test/src/Grant/PasswordTest.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ protected function getParamExpectation(): Closure
2525
return fn (array $body) => isset($body['grant_type'])
2626
&& $body['grant_type'] === 'password'
2727
&& isset($body['username'])
28-
&& isset($body['password'])
29-
&& isset($body['scope']);
28+
&& isset($body['password']);
3029
}
3130

3231
public function testToString(): void

test/src/Provider/AbstractProviderTest.php

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,7 @@ public function testGetAccessToken(string $method): void
714714
->once()
715715
->with(
716716
['client_id' => 'mock_client_id', 'client_secret' => 'mock_secret', 'redirect_uri' => 'none'],
717-
['code' => 'mock_authorization_code', 'scope' => 'test'],
717+
['code' => 'mock_authorization_code'],
718718
)
719719
->andReturn([]);
720720

@@ -755,6 +755,61 @@ public function testGetAccessToken(string $method): void
755755
&& (string) $request->getUri() === $provider->getBaseAccessTokenUrl([]));
756756
}
757757

758+
#[DataProvider('getAccessTokenMethodProvider')]
759+
public function testGetAccessTokenWithScope(string $method): void
760+
{
761+
$provider = $this->getMockProvider();
762+
$provider->setAccessTokenMethod($method);
763+
764+
$rawResponse = ['access_token' => 'okay', 'expires' => time() + 3600, 'resource_owner_id' => 3];
765+
766+
$grant = Mockery::mock(AbstractGrant::class);
767+
$grant
768+
->shouldReceive('prepareRequestParameters')
769+
->once()
770+
->with(
771+
['client_id' => 'mock_client_id', 'client_secret' => 'mock_secret', 'redirect_uri' => 'none'],
772+
['code' => 'mock_authorization_code', 'scope' => 'foo,bar'],
773+
)
774+
->andReturn([]);
775+
776+
$stream = Mockery::mock(StreamInterface::class);
777+
$stream
778+
->shouldReceive('__toString')
779+
->once()
780+
->andReturn(json_encode($rawResponse));
781+
782+
$response = Mockery::mock(ResponseInterface::class);
783+
$response
784+
->shouldReceive('getBody')
785+
->once()
786+
->andReturn($stream);
787+
$response
788+
->shouldReceive('getHeader')
789+
->once()
790+
->with('content-type')
791+
->andReturn(['application/json']);
792+
793+
$client = Mockery::spy(ClientInterface::class, [
794+
'sendRequest' => $response,
795+
]);
796+
797+
$provider->setHttpClient($client);
798+
$token = $provider->getAccessToken($grant, ['code' => 'mock_authorization_code', 'scope' => ['foo', 'bar']]);
799+
800+
$this->assertInstanceOf(ResourceOwnerAccessTokenInterface::class, $token);
801+
802+
$this->assertSame($rawResponse['resource_owner_id'], $token->getResourceOwnerId());
803+
$this->assertSame($rawResponse['access_token'], $token->getToken());
804+
$this->assertSame($rawResponse['expires'], $token->getExpires());
805+
806+
$client
807+
->shouldHaveReceived('sendRequest')
808+
->once()
809+
->withArgs(fn (RequestInterface $request) => $request->getMethod() === $provider->getAccessTokenMethod()
810+
&& (string) $request->getUri() === $provider->getBaseAccessTokenUrl([]));
811+
}
812+
758813
public function testGetAccessTokenWithNonJsonResponse(): void
759814
{
760815
$provider = $this->getMockProvider();

0 commit comments

Comments
 (0)