diff --git a/src/Core/OAuth1Provider.php b/src/Core/OAuth1Provider.php index 44c2cca..69a94ec 100644 --- a/src/Core/OAuth1Provider.php +++ b/src/Core/OAuth1Provider.php @@ -195,25 +195,58 @@ public function getAccessToken(string $requestToken, string $verifier):AccessTok throw new ProviderException('request token mismatch'); } - $response = $this->sendAccessTokenRequest($verifier); + $params = $this->getAccessTokenRequestHeaderParams($token, $verifier); + $response = $this->sendAccessTokenRequest($params); return $this->parseTokenResponse($response); } + /** + * Prepares the header params for the access token request + */ + protected function getAccessTokenRequestHeaderParams(AccessToken $requestToken, string $verifier):array{ + + $params = [ + 'oauth_consumer_key' => $this->options->key, + 'oauth_nonce' => $this->nonce(), + 'oauth_signature_method' => 'HMAC-SHA1', + 'oauth_timestamp' => time(), + 'oauth_token' => $requestToken->accessToken, + 'oauth_version' => '1.0', + 'oauth_verifier' => $verifier, + ]; + + $params['oauth_signature'] = $this->getSignature( + $this->accessTokenURL, + $params, + 'POST', + $requestToken->accessTokenSecret, + ); + + return $params; + } + + /** + * Adds the "Authorization" header to the given `RequestInterface` using the given array or parameters + */ + protected function setAuthorizationHeader(RequestInterface $request, array $params):RequestInterface{ + return $request->withHeader('Authorization', sprintf('OAuth %s', QueryUtil::build($params, null, ', ', '"'))); + } + /** * Sends the access token request * * @see \chillerlan\OAuth\Core\OAuth1Provider::getAccessToken() */ - protected function sendAccessTokenRequest(string $verifier):ResponseInterface{ + protected function sendAccessTokenRequest(array $headerParams):ResponseInterface{ $request = $this->requestFactory - ->createRequest('POST', QueryUtil::merge($this->accessTokenURL, ['oauth_verifier' => $verifier])) + ->createRequest('POST', $this->accessTokenURL) ->withHeader('Accept-Encoding', 'identity') ->withHeader('Content-Length', '0') ; - $request = $this->getRequestAuthorization($request); + $request = $this->setAuthorizationHeader($request, $headerParams); return $this->http->sendRequest($request); } @@ -245,7 +278,7 @@ public function getRequestAuthorization(RequestInterface $request, AccessToken|n $token->accessTokenSecret, ); - return $request->withHeader('Authorization', sprintf('OAuth %s', QueryUtil::build($params, null, ', ', '"'))); + return $this->setAuthorizationHeader($request, $params); } } diff --git a/tests/Providers/Unit/OAuth1ProviderUnitTestAbstract.php b/tests/Providers/Unit/OAuth1ProviderUnitTestAbstract.php index 71934ce..adaf7e0 100644 --- a/tests/Providers/Unit/OAuth1ProviderUnitTestAbstract.php +++ b/tests/Providers/Unit/OAuth1ProviderUnitTestAbstract.php @@ -155,6 +155,30 @@ public function testParseTokenResponseConfirmCallbackException():void{ * access token */ + public function testGetAccessTokenRequestHeaderParams():void{ + + $testRequestToken = $this->getTestToken([ + 'accessToken' => 'test_request_token', + 'accessTokenSecret' => 'test_request_token_secret', + ]); + + $testVerifier = '*verifier*'; + + $headerParams = $this->invokeReflectionMethod('getAccessTokenRequestHeaderParams', [$testRequestToken, $testVerifier]); + + $this::assertArrayHasKey('oauth_verifier', $headerParams); + $this::assertSame($testVerifier, $headerParams['oauth_verifier']); + + $this::assertArrayHasKey('oauth_token', $headerParams); + $this::assertSame($testRequestToken->accessToken, $headerParams['oauth_token']); + + $this::assertArrayHasKey('oauth_consumer_key', $headerParams); + $this::assertArrayHasKey('oauth_nonce', $headerParams); + $this::assertArrayHasKey('oauth_signature_method', $headerParams); + $this::assertArrayHasKey('oauth_timestamp', $headerParams); + $this::assertArrayHasKey('oauth_signature', $headerParams); + } + public function testGetAccessToken():void{ $this->setMockResponse($this->streamFactory->createStream($this::TEST_ACCESS_TOKEN)); @@ -179,16 +203,12 @@ public function testSendAccessTokenRequest():void{ 'expires' => AccessToken::NEVER_EXPIRES, ]); - $this->provider->storeAccessToken($requestToken); - $response = $this->invokeReflectionMethod('sendAccessTokenRequest', ['*verifier*']); + $response = $this->invokeReflectionMethod('sendAccessTokenRequest', [['foo' => 'bar']]); $json = MessageUtil::decodeJSON($response); - // check if the verifier is set - $this::assertSame('*verifier*', $json->request->params->{'oauth_verifier'}); - - $this::assertTrue(str_starts_with($json->headers->{'Authorization'}, 'OAuth ')); + $this::assertSame('OAuth foo="bar"', $json->headers->{'Authorization'}); $this::assertSame('identity', $json->headers->{'Accept-Encoding'}); $this::assertSame('0', $json->headers->{'Content-Length'}); $this::assertSame('POST', $json->request->method);