diff --git a/.travis.yml b/.travis.yml index 8e60692..edb8a09 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,13 @@ language: php - +dist: trusty sudo: required php: - - 5.4 - - 5.5 - 5.6 + - 7.1 + - 7.2 + - 7.3 + - 7.4 env: TEST_PARAMS='-c tests/php.ini' diff --git a/composer.json b/composer.json index c005229..6645a5c 100644 --- a/composer.json +++ b/composer.json @@ -10,13 +10,13 @@ } ], "require": { - "php": ">=5.4", - "guzzlehttp/guzzle": "^5.3" + "php": ">=5.6", + "guzzlehttp/guzzle": "^6.2" }, "require-dev": { "tracy/tracy": "^2.4", "nette/tester": "^1.7", - "mockery/mockery": "^0.9.9", + "mockery/mockery": "^1.3", "latte/latte": "^2.4" }, "autoload": { diff --git a/examples/clientApi.php b/examples/clientApi.php index c0da779..44975ec 100644 --- a/examples/clientApi.php +++ b/examples/clientApi.php @@ -3,7 +3,7 @@ require __DIR__ . '/bootstrap.php'; use GuzzleHttp\Exception\BadResponseException; -use GuzzleHttp\Message\Request; +use GuzzleHttp\Psr7\Request; use SizeID\OAuth2\ClientApi; diff --git a/examples/popupLogin.php b/examples/popupLogin.php index cd77550..4b76b79 100644 --- a/examples/popupLogin.php +++ b/examples/popupLogin.php @@ -1,6 +1,6 @@ clientId = $clientId; $this->clientSecret = $clientSecret; $this->accessTokenRepository = $accessTokenRepository; - if ($authorizationServerUrl === NULL) { + if ($authorizationServerUrl === null) { $authorizationServerUrl = Config::AUTHORIZATION_SERVER_URL; } - if ($apiBaseUrl === NULL) { + if ($apiBaseUrl === null) { $apiBaseUrl = Config::API_URL; } - if ($httpClient === NULL) { - $httpClient = new Client(); + if ($httpClient === null) { + $httpClient = new Client( + [ + RequestOptions::HTTP_ERRORS => false, + ] + ); } $this->authorizationServerUrl = $authorizationServerUrl; $this->apiBaseUrl = $apiBaseUrl; @@ -154,7 +159,7 @@ protected function parseToken(ResponseInterface $response) private function createResponse(RequestInterface $request) { $response = $this->callApi($this->buildRequest($request)); - if ($response->getStatusCode() === 401 && $response->getHeader(self::SIZEID_ERROR_CODE_HEADER) == 109) { + if ($response->getStatusCode() === 401 && $response->getHeaderLine(self::SIZEID_ERROR_CODE_HEADER) == 109) { $this->refreshAccessToken(); return $this->callApi($this->buildRequest($request)); } @@ -176,9 +181,7 @@ private function callApi(RequestInterface $request) */ private function buildRequest(RequestInterface $request) { - $request = clone $request; - $request->addHeader('Authorization', 'Bearer ' . $this->getAccessToken()->getAccessToken()); - $request->setUrl($this->apiBaseUrl . '/' . $request->getUrl()); - return $request; + return $request->withAddedHeader('Authorization', 'Bearer ' . $this->getAccessToken()->getAccessToken()) + ->withUri(new Uri($this->apiBaseUrl . '/' . $request->getUri())); } } \ No newline at end of file diff --git a/src/ClientApi.php b/src/ClientApi.php index 7b8519e..9c6648d 100644 --- a/src/ClientApi.php +++ b/src/ClientApi.php @@ -46,7 +46,7 @@ public function acquireNewAccessToken() $response = $this->httpClient->post( $this->authorizationServerUrl . '/access-token', [ - 'body' => [ + 'form_params' => [ 'grant_type' => 'client_credentials', 'client_id' => $this->clientId, 'client_secret' => $this->clientSecret, diff --git a/src/UserApi.php b/src/UserApi.php index a740994..2a96194 100644 --- a/src/UserApi.php +++ b/src/UserApi.php @@ -4,8 +4,9 @@ use GuzzleHttp\ClientInterface; use GuzzleHttp\Exception\ClientException; -use GuzzleHttp\Message\ResponseInterface; -use GuzzleHttp\Url; +use Psr\Http\Message\ResponseInterface; +use GuzzleHttp\Psr7\Uri; +use Psr\Http\Message\UriInterface; use SizeID\OAuth2\Entities\AccessToken; use SizeID\OAuth2\Exceptions\InvalidCSRFTokenException; use SizeID\OAuth2\Exceptions\InvalidStateException; @@ -69,16 +70,13 @@ public function __construct( */ public function getAuthorizationUrl() { - $url = Url::fromString($this->authorizationServerUrl); - $url->setQuery( - [ - 'response_type' => 'code', - 'client_id' => $this->clientId, - 'redirect_uri' => $this->redirectUri, - 'state' => $this->csrfTokenRepository->generateCSRFToken(), - ] - ); - return $url; + $url = new Uri($this->authorizationServerUrl); + return Uri::withQueryValues($url, [ + 'response_type' => 'code', + 'client_id' => $this->clientId, + 'redirect_uri' => $this->redirectUri, + 'state' => $this->csrfTokenRepository->generateCSRFToken(), + ]); } /** @@ -149,7 +147,7 @@ public function refreshAccessToken() $this->saveTokenFromResponse($response); } catch (ClientException $ex) { $response = $ex->getResponse(); - $sizeIdErrorCode = (int)$response->getHeader(self::SIZEID_ERROR_CODE_HEADER); + $sizeIdErrorCode = (int)$response->getHeaderLine(self::SIZEID_ERROR_CODE_HEADER); if ($response->getStatusCode() === 400 && $sizeIdErrorCode === 108) { //refresh token expired throw RedirectException::create( diff --git a/tests/ApiTest.phpt b/tests/ApiTest.phpt index 94f383a..240e9bb 100644 --- a/tests/ApiTest.phpt +++ b/tests/ApiTest.phpt @@ -2,8 +2,8 @@ namespace SizeID\OAuth2\Tests; -use GuzzleHttp\Message\Request; -use GuzzleHttp\Message\Response; +use GuzzleHttp\Psr7\Request; +use GuzzleHttp\Psr7\Response; use Mockery as m; use SizeID\OAuth2\ClientApi; use SizeID\OAuth2\Entities\AccessToken; @@ -20,7 +20,7 @@ class ApiTest extends TestCase $tokenRepository = m::mock('SizeID\OAuth2\Repositories\SessionAccessTokenRepository'); $tokenRepository ->shouldReceive('hasAccessToken') - ->andReturn(NULL); + ->andReturn(null); $clientApi = new ClientApi( 'clientId', 'clientSecret', diff --git a/tests/ClientApiTest.phpt b/tests/ClientApiTest.phpt index ff59a28..7b342ee 100644 --- a/tests/ClientApiTest.phpt +++ b/tests/ClientApiTest.phpt @@ -2,12 +2,14 @@ namespace SizeID\OAuth2\Tests; -use GuzzleHttp\Message\Request; -use GuzzleHttp\Message\Response; +use GuzzleHttp\Psr7\Request; +use GuzzleHttp\Psr7\Response; use Mockery as m; +use Psr\Http\Message\StreamInterface; use SizeID\OAuth2\Api; use SizeID\OAuth2\ClientApi; use SizeID\OAuth2\Entities\AccessToken; +use SizeID\OAuth2\Repositories\SessionAccessTokenRepository; use Tester\Assert; use Tester\TestCase; @@ -27,7 +29,7 @@ class ClientApiTest extends TestCase public function testAcquireToken() { - $tokenRepository = m::mock('SizeID\OAuth2\Repositories\SessionAccessTokenRepository'); + $tokenRepository = m::mock(SessionAccessTokenRepository::class); $tokenRepository ->shouldReceive('hasAccessToken') ->andReturn(FALSE); @@ -38,7 +40,7 @@ class ClientApiTest extends TestCase ->shouldReceive('getAccessToken') ->andReturn($accessToken); $httpClient = m::mock('GuzzleHttp\Client'); - $stream = m::mock('GuzzleHttp\Stream\StreamInterface'); + $stream = m::mock(StreamInterface::class); $stream ->shouldReceive('getContents') ->andReturn('{"access_token":"token", "expires_in": 60}'); @@ -57,13 +59,13 @@ class ClientApiTest extends TestCase NULL, $httpClient ); - Assert::type('SizeID\OAuth2\ClientApi', $clientApi); + Assert::type(ClientApi::class, $clientApi); $clientApi->send(new Request('get', 'client')); } public function testRefreshToken() { - $tokenRepository = m::mock('SizeID\OAuth2\Repositories\SessionAccessTokenRepository'); + $tokenRepository = m::mock(SessionAccessTokenRepository::class); $tokenRepository ->shouldReceive('hasAccessToken') ->andReturn(TRUE); @@ -78,7 +80,7 @@ class ClientApiTest extends TestCase $httpClient ->shouldReceive('send') ->andReturn($response); - $stream = m::mock('GuzzleHttp\Stream\StreamInterface'); + $stream = m::mock(StreamInterface::class); $stream ->shouldReceive('getContents') ->andReturn('{"access_token":"token", "expires_in": 60}'); @@ -97,8 +99,8 @@ class ClientApiTest extends TestCase NULL, $httpClient ); - Assert::type('SizeID\OAuth2\ClientApi', $clientApi); - Assert::type('GuzzleHttp\Message\Response', $clientApi->send(new Request('POST', 'client'))); + Assert::type(ClientApi::class, $clientApi); + Assert::type(Response::class, $clientApi->send(new Request('POST', 'client'))); } } diff --git a/tests/UserApiTest.phpt b/tests/UserApiTest.phpt index f6bc07d..5789437 100644 --- a/tests/UserApiTest.phpt +++ b/tests/UserApiTest.phpt @@ -2,12 +2,19 @@ namespace SizeID\OAuth2\Tests; -use GuzzleHttp\Message\Request; -use GuzzleHttp\Message\Response; +use GuzzleHttp\ClientInterface; +use GuzzleHttp\Exception\ClientException; +use GuzzleHttp\Psr7\Request; +use GuzzleHttp\Psr7\Response; use Mockery as m; +use Psr\Http\Message\StreamInterface; use SizeID\OAuth2\Api; use SizeID\OAuth2\Entities\AccessToken; +use SizeID\OAuth2\Exceptions\InvalidCSRFTokenException; +use SizeID\OAuth2\Exceptions\InvalidStateException; use SizeID\OAuth2\Exceptions\RedirectException; +use SizeID\OAuth2\Repositories\AccessTokenRepositoryInterface; +use SizeID\OAuth2\Repositories\CsrfTokenRepositoryInterface; use SizeID\OAuth2\UserApi; use Tester\Assert; use Tester\TestCase; @@ -24,26 +31,26 @@ class UserApiTest extends TestCase 'clientSecret', 'http://9gag.com' ); - Assert::type('SizeID\OAuth2\UserApi', $clientApi); + Assert::type(UserApi::class, $clientApi); } public function testAuthorize() { - $tokenRepository = m::mock('SizeID\OAuth2\Repositories\AccessTokenRepositoryInterface'); + $tokenRepository = m::mock(AccessTokenRepositoryInterface::class); $tokenRepository ->shouldReceive('hasAccessToken') ->once() - ->andReturn(FALSE); + ->andReturn(false); $tokenRepository ->shouldReceive('saveAccessToken'); - $stateRepository = m::mock('SizeID\OAuth2\Repositories\CsrfTokenRepositoryInterface'); + $stateRepository = m::mock(CsrfTokenRepositoryInterface::class); $stateRepository ->shouldReceive('generateCSRFToken') ->andReturn('csrfToken'); $stateRepository ->shouldReceive('loadTokenCSRFToken') ->andReturn('csrfToken'); - $httpClient = m::mock('GuzzleHttp\ClientInterface'); + $httpClient = m::mock(ClientInterface::class); $userApi = new UserApi( 'clientId', 'clientSecret', @@ -56,7 +63,7 @@ class UserApiTest extends TestCase ); try { $userApi->send(new Request('get', 'user')); - Assert::fail('SizeID\OAuth2\Exceptions\RedirectException' . ' should be thrown'); + Assert::fail(RedirectException::class . ' should be thrown'); } catch (RedirectException $ex) { Assert::equal(RedirectException::CODE_MISSING_TOKEN, $ex->getCode()); Assert::equal( @@ -64,7 +71,7 @@ class UserApiTest extends TestCase (string)$ex->getRedirectUrl() ); } - $stream = m::mock('GuzzleHttp\Stream\StreamInterface'); + $stream = m::mock(StreamInterface::class); $stream ->shouldReceive('getContents') ->andReturn('{"access_token":"token", "expires_in": 60, "refresh_token": "refresh_token"}'); @@ -75,7 +82,7 @@ class UserApiTest extends TestCase $userApi->completeAuthorization("authCode", "csrfToken"); $tokenRepository ->shouldReceive('hasAccessToken') - ->andReturn(TRUE); + ->andReturn(true); $tokenRepository ->shouldReceive('deleteAccessToken'); $tokenRepository @@ -86,7 +93,7 @@ class UserApiTest extends TestCase function () use ($userApi) { $userApi->send(new Request('get', 'user')); }, - 'SizeID\OAuth2\Exceptions\InvalidStateException' + InvalidStateException::class ); $tokenRepository ->shouldReceive('getAccessToken') @@ -94,30 +101,30 @@ class UserApiTest extends TestCase $httpClient ->shouldReceive('send') ->andReturn(new Response(200)); - Assert::type('GuzzleHttp\Message\Response', $userApi->send(new Request('get', 'user'))); + Assert::type(Response::class, $userApi->send(new Request('get', 'user'))); } public function testRefreshToken() { - $tokenRepository = m::mock('SizeID\OAuth2\Repositories\AccessTokenRepositoryInterface'); + $tokenRepository = m::mock(AccessTokenRepositoryInterface::class); $tokenRepository ->shouldReceive('getAccessToken') - ->andReturn(new AccessToken('acessToken', 'refreshToken')); + ->andReturn(new AccessToken('accessToken', 'refreshToken')); $tokenRepository ->shouldReceive('saveAccessToken') ->with( m::on( function (AccessToken $accessToken) { Assert::equal('newRefreshToken', $accessToken->getRefreshToken()); - return TRUE; + return true; } ) ); - $stream = m::mock('GuzzleHttp\Stream\StreamInterface'); + $stream = m::mock(StreamInterface::class); $stream ->shouldReceive('getContents') ->andReturn('{"access_token":"token", "expires_in": 60, "refresh_token": "newRefreshToken"}'); - $httpClient = m::mock('GuzzleHttp\ClientInterface'); + $httpClient = m::mock(ClientInterface::class); $httpClient ->shouldReceive('post') ->andReturn(new Response(200, [], $stream)); @@ -129,18 +136,18 @@ class UserApiTest extends TestCase 'authServer', 'apiUrl', $httpClient, - NULL + null ); $userApi->refreshAccessToken(); } public function testInvalidRefreshToken() { - $tokenRepository = m::mock('SizeID\OAuth2\Repositories\AccessTokenRepositoryInterface'); + $tokenRepository = m::mock(AccessTokenRepositoryInterface::class); $tokenRepository ->shouldReceive('getAccessToken') - ->andReturn(new AccessToken('acessToken', 'refreshToken')); - $responseException = m::mock('GuzzleHttp\Exception\ClientException'); + ->andReturn(new AccessToken('accessToken', 'refreshToken')); + $responseException = m::mock(ClientException::class); $errorResponse = new Response( 400, [Api::SIZEID_ERROR_CODE_HEADER => "108"] @@ -148,7 +155,7 @@ class UserApiTest extends TestCase $responseException ->shouldReceive('getResponse') ->andReturn($errorResponse); - $httpClient = m::mock('GuzzleHttp\ClientInterface'); + $httpClient = m::mock(ClientInterface::class); $httpClient ->shouldReceive('post') ->once() @@ -161,18 +168,17 @@ class UserApiTest extends TestCase 'authServer', 'apiUrl', $httpClient, - NULL + null ); Assert::exception( function () use ($userApi) { $userApi->refreshAccessToken(); - } - , - 'SizeID\OAuth2\Exceptions\RedirectException', - NULL, + }, + RedirectException::class, + null, RedirectException::CODE_EXPIRED_REFRESH_TOKEN ); - $responseException = m::mock('GuzzleHttp\Exception\ClientException'); + $responseException = m::mock(ClientException::class); $errorResponse = new Response( 400 ); @@ -188,7 +194,7 @@ class UserApiTest extends TestCase $userApi->refreshAccessToken(); } , - 'GuzzleHttp\Exception\ClientException' + ClientException::class ); } @@ -196,7 +202,7 @@ class UserApiTest extends TestCase { $_GET['code'] = 'code'; $_GET['state'] = 'state1'; - $csrfTokenRepository = m::mock('SizeID\OAuth2\Repositories\CsrfTokenRepositoryInterface'); + $csrfTokenRepository = m::mock(CsrfTokenRepositoryInterface::class); $csrfTokenRepository ->shouldReceive('loadTokenCSRFToken') ->andReturn('state2'); @@ -204,17 +210,17 @@ class UserApiTest extends TestCase 'clientId', 'clientSecret', 'redirectUri', - NULL, + null, 'authServer', 'apiUrl', - NULL, - NULL + null, + null ); Assert::exception( function () use ($userApi) { $userApi->completeAuthorization(); }, - 'SizeID\OAuth2\Exceptions\InvalidCSRFTokenException', + InvalidCSRFTokenException::class, 'Invalid CSRF token.' ); }