diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9832126..24c6ad3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,19 +8,31 @@ jobs: strategy: matrix: - php: [7.0, 7.1, 7.2, 7.3, 7.4] + php: [7.3, 7.4, 8.0, 8.1, 8.2] + phpunit: [9] + composer: [2] + include: + - php: 7.0 + phpunit: 6 + composer: 2.2 + - php: 7.1 + phpunit: 6 + composer: 2.2 + - php: 7.2 + phpunit: 6 + composer: 2 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - - uses: php-actions/composer@v5 + - uses: php-actions/composer@v6 with: + version: ${{ matrix.composer }} php_version: ${{ matrix.php }} - name: PHPUnit Tests - uses: php-actions/phpunit@v2 + uses: php-actions/phpunit@v3 with: - version: 6 + version: ${{ matrix.phpunit }} php_version: ${{ matrix.php }} - bootstrap: vendor/autoload.php args: --coverage-text diff --git a/.gitignore b/.gitignore index d1e59b6..4faeb5e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /vendor composer.lock +*.cache .idea diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 1edcfb1..0000000 --- a/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -sudo: false - -language: php - -php: - - '7.1' - -before_script: - - composer self-update - - composer install --no-interaction - -script: - - ./vendor/bin/phpunit diff --git a/README.md b/README.md index 083aacd..622ee93 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # ChatWork Provider for OAuth 2.0 Client -[![Build Status](https://travis-ci.com/chatwork/oauth2-chatwork-php.svg?branch=master)](https://travis-ci.com/chatwork/oauth2-chatwork-php) +[![Build Status](https://github.com/chatwork/oauth2-chatwork-php/actions/workflows/ci.yml/badge.svg)](https://github.com/chatwork/oauth2-chatwork-php/actions/workflows/ci.yml) [![Latest Stable Version](https://poser.pugx.org/chatwork/oauth2-chatwork/version)](https://packagist.org/packages/chatwork/oauth2-chatwork) [![License](https://poser.pugx.org/chatwork/oauth2-chatwork/license)](https://packagist.org/packages/chatwork/oauth2-chatwork) diff --git a/composer.json b/composer.json index 3606db2..6e52380 100644 --- a/composer.json +++ b/composer.json @@ -17,11 +17,11 @@ "chatwork" ], "require": { - "php": "^7.0", - "league/oauth2-client": ">=2.2.0 <2.4.0" + "php": "^7.0 || ^8.0", + "league/oauth2-client": "^2.7.0" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^6.0 || ^9.0" }, "autoload": { "psr-4": { diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 54df6b9..c6ec904 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -8,6 +8,7 @@ processIsolation="false" stopOnFailure="false" bootstrap="vendor/autoload.php" + verbose="true" colors="true"> diff --git a/src/ChatWorkProvider.php b/src/ChatWorkProvider.php index 8e9ae18..fc0fe8d 100644 --- a/src/ChatWorkProvider.php +++ b/src/ChatWorkProvider.php @@ -2,8 +2,7 @@ namespace ChatWork\OAuth2\Client; -use League\OAuth2\Client\Grant\AuthorizationCode; -use League\OAuth2\Client\Grant\RefreshToken; +use League\OAuth2\Client\OptionProvider\HttpBasicAuthOptionProvider; use League\OAuth2\Client\Provider\AbstractProvider; use League\OAuth2\Client\Provider\Exception\IdentityProviderException; use League\OAuth2\Client\Provider\ResourceOwnerInterface; @@ -26,11 +25,10 @@ final class ChatWorkProvider extends AbstractProvider */ public function __construct(string $clientId, string $clientSecret, string $redirectUri = '', array $collaborators = []) { - parent::__construct([ - 'clientId' => $clientId, - 'clientSecret' => $clientSecret, - 'redirectUri' => $redirectUri - ], $collaborators); + // use Basic Auth: https://developer.chatwork.com/docs/oauth#%E8%AA%8D%E8%A8%BC + $collaborators += ['optionProvider' => new HttpBasicAuthOptionProvider()]; + + parent::__construct(compact('clientId', 'clientSecret', 'redirectUri') , $collaborators); } /** @@ -69,7 +67,7 @@ protected function getDefaultScopes(): array /** * @inheritdoc */ - protected function checkResponse(ResponseInterface $response, $data): void + protected function checkResponse(ResponseInterface $response, $data) { if (isset($data['error'])) { throw new IdentityProviderException( @@ -116,56 +114,9 @@ protected function createResourceOwner(array $response, AccessToken $token): Res /** * @inheritdoc */ - protected function getScopeSeparator() + protected function getScopeSeparator(): string { return ' '; } - /** - * @inheritdoc - */ - protected function getAccessTokenOptions(array $params) - { - $options = [ - 'headers' => [ - 'content-type' => 'application/x-www-form-urlencoded', - 'authorization' => 'Basic ' . base64_encode($params['client_id'] . ':' . $params['client_secret']), - ] - ]; - - if ($this->getAccessTokenMethod() === self::METHOD_POST) { - $options['body'] = $this->getAccessTokenBody( - $params['grant_type'] === (string) new AuthorizationCode() ? $this->getAuthorizationCodeGrantOptions($params) : $this->getRefreshTokenGrantOptions($params) - ); - } - - return $options; - } - - /** - * @param array $params - * @return array - */ - private function getAuthorizationCodeGrantOptions(array $params) - { - return [ - 'code' => $params['code'], - 'redirect_uri' => $params['redirect_uri'], - 'grant_type' => (string) new AuthorizationCode() - ]; - } - - /** - * @param array $params - * @return array - */ - private function getRefreshTokenGrantOptions(array $params) - { - return [ - 'refresh_token' => $params['refresh_token'], - 'redirect_uri' => $params['redirect_uri'], - 'grant_type' => (string) new RefreshToken() - ]; - } - } diff --git a/tests/ChatWorkProviderTest.php b/tests/ChatWorkProviderTest.php index a407f14..11af700 100644 --- a/tests/ChatWorkProviderTest.php +++ b/tests/ChatWorkProviderTest.php @@ -2,13 +2,13 @@ namespace ChatWork\OAuth2\Client\Test; -require 'vendor/phpunit/phpunit/src/Framework/Assert/Functions.php'; - use ChatWork\OAuth2\Client\ChatWorkProvider; use League\OAuth2\Client\Grant\AuthorizationCode; use PHPUnit\Framework\TestCase; use Psr\Http\Message\RequestInterface; +class Rejection extends \RuntimeException {} + /** * @package ChatWork\OAuth2\Client\Test */ @@ -42,26 +42,33 @@ public function getAccessToken_willSendClientIdByHeader() $clientSecret = 'test_client_secret'; $expectedToken = base64_encode("{$clientId}:{$clientSecret}"); - $assert = function (RequestInterface $request) use ($expectedToken) { - parse_str($request->getBody()->getContents(), $param); - assertArrayNotHasKey('client_id', $param, 'request body should not contains "client_id".'); - assertArrayNotHasKey('client_secret', $param, 'request body should not contains "client_secret" too.'); - assertEquals("Basic {$expectedToken}", $request->getHeader('Authorization')[0], 'client MUST use Basic Authentication'); - throw new \Exception('OK'); // stop before send request - }; + $actualParam = []; + $actualHeader = []; - $this->expectExceptionMessage('OK'); + $capturer = function (RequestInterface $request) use (&$actualParam, &$actualHeader) { + parse_str($request->getBody()->getContents(), $paramParam); + $actualHeader = $request->getHeader('Authorization'); + throw new Rejection; // stop before send request + }; $provider = new ChatWorkProvider( - $clientId, - $clientSecret, + $clientId, + $clientSecret, 'https://example.com/', [ - 'httpClient' => $this->createSpyClient($assert) + 'httpClient' => $this->createSpyClient($capturer) ] ); - - $provider->getAccessToken(new AuthorizationCode(), ['code' => 'authorization_code']); + + try { + $provider->getAccessToken(new AuthorizationCode(), ['code' => 'authorization_code']); + } catch (Rejection $_) { + // OK + } + + $this->assertArrayNotHasKey('client_id', $actualParam, 'request body should not contains "client_id".'); + $this->assertArrayNotHasKey('client_secret', $actualParam, 'request body should not contains "client_secret" too.'); + $this->assertEquals("Basic {$expectedToken}", $actualHeader[0], 'client MUST use Basic Authentication'); } private function createSpyClient(callable $assetion) @@ -70,5 +77,5 @@ private function createSpyClient(callable $assetion) $stack->push(\GuzzleHttp\Middleware::tap($assetion)); return new \GuzzleHttp\Client(['handler' => $stack]); } - + }