Skip to content

Commit

Permalink
Throw AuthroizeFailedException when api response not contains access_…
Browse files Browse the repository at this point in the history
  • Loading branch information
overtrue committed Nov 28, 2016
1 parent 42b4ceb commit 8ef5d47
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 36 deletions.
35 changes: 35 additions & 0 deletions src/AuthorizeFailedException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

/*
* This file is part of the overtrue/socialite.
*
* (c) overtrue <[email protected]>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Overtrue\Socialite;

class AuthorizeFailedException extends \RuntimeException
{
/**
* Response body.
*
* @var array
*/
public $body;

/**
* Constructor.
*
* @param string $message
* @param string $body
*/
public function __construct($message, $body)
{
parent::__construct($message, -1);

$this->body = $body;
}
}
4 changes: 2 additions & 2 deletions src/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public function set($key, $value)
* @return bool true on success or false on failure.
* </p>
* <p>
* The return value will be casted to boolean if non-boolean was returned.
* The return value will be casted to boolean if non-boolean was returned
*
* @since 5.0.0
*/
Expand All @@ -119,7 +119,7 @@ public function offsetExists($offset)
* The offset to retrieve.
* </p>
*
* @return mixed Can return all value types.
* @return mixed Can return all value types
*
* @since 5.0.0
*/
Expand Down
16 changes: 16 additions & 0 deletions src/InvalidArgumentException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

/*
* This file is part of the overtrue/socialite.
*
* (c) overtrue <[email protected]>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Overtrue\Socialite;

class InvalidArgumentException extends \InvalidArgumentException
{
}
21 changes: 15 additions & 6 deletions src/Providers/AbstractProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use GuzzleHttp\ClientInterface;
use Overtrue\Socialite\AccessToken;
use Overtrue\Socialite\AccessTokenInterface;
use Overtrue\Socialite\AuthorizeFailedException;
use Overtrue\Socialite\InvalidStateException;
use Overtrue\Socialite\ProviderInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
Expand Down Expand Up @@ -77,7 +78,7 @@ abstract class AbstractProvider implements ProviderInterface
/**
* The type of the encoding in the query.
*
* @var int Can be either PHP_QUERY_RFC3986 or PHP_QUERY_RFC1738.
* @var int Can be either PHP_QUERY_RFC3986 or PHP_QUERY_RFC1738
*/
protected $encodingType = PHP_QUERY_RFC1738;

Expand All @@ -98,10 +99,10 @@ abstract class AbstractProvider implements ProviderInterface
*/
public function __construct(Request $request, $clientId, $clientSecret, $redirectUrl = null)
{
$this->request = $request;
$this->clientId = $clientId;
$this->request = $request;
$this->clientId = $clientId;
$this->clientSecret = $clientSecret;
$this->redirectUrl = $redirectUrl;
$this->redirectUrl = $redirectUrl;
}

/**
Expand Down Expand Up @@ -385,13 +386,21 @@ protected function getTokenFields($code)
/**
* Get the access token from the token response body.
*
* @param \Psr\Http\Message\StreamInterface $body
* @param \Psr\Http\Message\StreamInterface|array $body
*
* @return \Overtrue\Socialite\AccessToken
*/
protected function parseAccessToken($body)
{
return new AccessToken((array) json_decode($body, true));
if (!is_array($body)) {
$body = json_decode($body, true);
}

if (empty($body['access_token'])) {
throw new AuthorizeFailedException('Authorize Failed: '.json_encode($body, JSON_UNESCAPED_UNICODE), $body);
}

return new AccessToken($body);
}

/**
Expand Down
5 changes: 2 additions & 3 deletions src/Providers/FacebookProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

namespace Overtrue\Socialite\Providers;

use Overtrue\Socialite\AccessToken;
use Overtrue\Socialite\AccessTokenInterface;
use Overtrue\Socialite\ProviderInterface;
use Overtrue\Socialite\User;
Expand Down Expand Up @@ -97,7 +96,7 @@ protected function parseAccessToken($body)
{
parse_str($body, $token);

return new AccessToken($token);
return parent::parseAccessToken($token);
}

/**
Expand All @@ -124,7 +123,7 @@ protected function mapUserToObject(array $user)
$avatarUrl = $this->graphUrl.'/'.$this->version.'/'.$user['id'].'/picture';

$firstName = $this->arrayItem($user, 'first_name');
$lastName = $this->arrayItem($user, 'last_name');
$lastName = $this->arrayItem($user, 'last_name');

return new User([
'id' => $this->arrayItem($user, 'id'),
Expand Down
11 changes: 5 additions & 6 deletions src/Providers/QQProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

namespace Overtrue\Socialite\Providers;

use Overtrue\Socialite\AccessToken;
use Overtrue\Socialite\AccessTokenInterface;
use Overtrue\Socialite\ProviderInterface;
use Overtrue\Socialite\User;
Expand Down Expand Up @@ -126,7 +125,7 @@ public function parseAccessToken($body)
{
parse_str($body, $token);

return new AccessToken($token);
return parent::parseAccessToken($token);
}

/**
Expand All @@ -153,8 +152,8 @@ protected function getUserByToken(AccessTokenInterface $token)

$response = $this->getHttpClient()->get($url);

$me = json_decode($this->removeCallback($response->getBody()->getContents()), true);
$this->openId = $me['openid'];
$me = json_decode($this->removeCallback($response->getBody()->getContents()), true);
$this->openId = $me['openid'];
$this->unionId = isset($me['unionid']) ? $me['unionid'] : '';

$queries = [
Expand Down Expand Up @@ -197,8 +196,8 @@ protected function mapUserToObject(array $user)
protected function removeCallback($response)
{
if (strpos($response, 'callback') !== false) {
$lpos = strpos($response, '(');
$rpos = strrpos($response, ')');
$lpos = strpos($response, '(');
$rpos = strrpos($response, ')');
$response = substr($response, $lpos + 1, $rpos - $lpos - 1);
}

Expand Down
14 changes: 3 additions & 11 deletions src/Providers/WeChatProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@

namespace Overtrue\Socialite\Providers;

use InvalidArgumentException;
use Overtrue\Socialite\AccessToken;
use Overtrue\Socialite\AccessTokenInterface;
use Overtrue\Socialite\InvalidArgumentException;
use Overtrue\Socialite\ProviderInterface;
use Overtrue\Socialite\User;

Expand Down Expand Up @@ -160,14 +160,6 @@ public function getAccessToken($code)
return $this->parseAccessToken($response->getBody()->getContents());
}

/**
* {@inheritdoc}.
*/
protected function parseAccessToken($body)
{
return new AccessToken(json_decode($body, true));
}

/**
* Remove the fucking callback parentheses.
*
Expand All @@ -178,8 +170,8 @@ protected function parseAccessToken($body)
protected function removeCallback($response)
{
if (strpos($response, 'callback') !== false) {
$lpos = strpos($response, '(');
$rpos = strrpos($response, ')');
$lpos = strpos($response, '(');
$rpos = strrpos($response, ')');
$response = substr($response, $lpos + 1, $rpos - $lpos - 1);
}

Expand Down
2 changes: 1 addition & 1 deletion src/SocialiteManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class SocialiteManager implements FactoryInterface
*/
public function __construct(array $config, Request $request = null)
{
$this->config = new Config($config);
$this->config = new Config($config);
$this->request = $request ?: $this->createDefaultRequest();
}

Expand Down
32 changes: 25 additions & 7 deletions tests/OAuthTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public function testRedirectGeneratesTheProperSymfonyRedirectResponse()
$response = $provider->redirect();

$this->assertInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse', $response);
$this->assertEquals('http://auth.url', $response->getTargetUrl());
$this->assertSame('http://auth.url', $response->getTargetUrl());
}

public function testRedirectUrl()
Expand All @@ -43,20 +43,20 @@ public function testRedirectUrl()
$this->assertNull($provider->getRedirectUrl());

$provider = new OAuthTwoTestProviderStub($request, 'client_id', 'client_secret', 'redirect_uri');
$this->assertEquals('redirect_uri', $provider->getRedirectUrl());
$this->assertSame('redirect_uri', $provider->getRedirectUrl());
$provider->setRedirectUrl('overtrue.me');
$this->assertEquals('overtrue.me', $provider->getRedirectUrl());
$this->assertSame('overtrue.me', $provider->getRedirectUrl());

$provider->withRedirectUrl('http://overtrue.me');
$this->assertEquals('http://overtrue.me', $provider->getRedirectUrl());
$this->assertSame('http://overtrue.me', $provider->getRedirectUrl());
}

public function testUserReturnsAUserInstanceForTheAuthenticatedRequest()
{
$request = Request::create('foo', 'GET', ['state' => str_repeat('A', 40), 'code' => 'code']);
$request->setSession($session = m::mock('Symfony\Component\HttpFoundation\Session\SessionInterface'));
$session->shouldReceive('get')->once()->with('state')->andReturn(str_repeat('A', 40));
$provider = new OAuthTwoTestProviderStub($request, 'client_id', 'client_secret', 'redirect_uri');
$provider = new OAuthTwoTestProviderStub($request, 'client_id', 'client_secret', 'redirect_uri');
$provider->http = m::mock('StdClass');
$provider->http->shouldReceive('post')->once()->with('http://token.url', [
'headers' => ['Accept' => 'application/json'], 'form_params' => ['client_id' => 'client_id', 'client_secret' => 'client_secret', 'code' => 'code', 'redirect_uri' => 'redirect_uri'],
Expand All @@ -65,7 +65,7 @@ public function testUserReturnsAUserInstanceForTheAuthenticatedRequest()
$user = $provider->user();

$this->assertInstanceOf('Overtrue\Socialite\User', $user);
$this->assertEquals('foo', $user->getId());
$this->assertSame('foo', $user->getId());
}

/**
Expand All @@ -77,6 +77,24 @@ public function testExceptionIsThrownIfStateIsInvalid()
$request->setSession($session = m::mock('Symfony\Component\HttpFoundation\Session\SessionInterface'));
$session->shouldReceive('get')->once()->with('state')->andReturn(str_repeat('A', 40));
$provider = new OAuthTwoTestProviderStub($request, 'client_id', 'client_secret', 'redirect');
$user = $provider->user();
}

/**
* @expectedException Overtrue\Socialite\AuthorizeFailedException
* @expectedExceptionMessage Authorize Failed: {"error":"scope is invalid"}
*/
public function testExceptionisThrownIfAuthorizeFailed()
{
$request = Request::create('foo', 'GET', ['state' => str_repeat('A', 40), 'code' => 'code']);
$request->setSession($session = m::mock('Symfony\Component\HttpFoundation\Session\SessionInterface'));
$session->shouldReceive('get')->once()->with('state')->andReturn(str_repeat('A', 40));
$provider = new OAuthTwoTestProviderStub($request, 'client_id', 'client_secret', 'redirect_uri');
$provider->http = m::mock('StdClass');
$provider->http->shouldReceive('post')->once()->with('http://token.url', [
'headers' => ['Accept' => 'application/json'], 'form_params' => ['client_id' => 'client_id', 'client_secret' => 'client_secret', 'code' => 'code', 'redirect_uri' => 'redirect_uri'],
])->andReturn($response = m::mock('StdClass'));
$response->shouldReceive('getBody')->once()->andReturn('{"error":"scope is invalid"}');
$user = $provider->user();
}

Expand All @@ -89,7 +107,7 @@ public function testExceptionIsThrownIfStateIsNotSet()
$request->setSession($session = m::mock('Symfony\Component\HttpFoundation\Session\SessionInterface'));
$session->shouldReceive('get')->once()->with('state');
$provider = new OAuthTwoTestProviderStub($request, 'client_id', 'client_secret', 'redirect');
$user = $provider->user();
$user = $provider->user();
}
}

Expand Down

0 comments on commit 8ef5d47

Please sign in to comment.