diff --git a/.travis.yml b/.travis.yml index 0ece38e..0d07594 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ matrix: - php: 5.4 env: $COMPOSER_OPTIONS="--prefer-lowest --ignore-platform-reqs" - php: 5.6 - env: PACKAGES="php-http/discovery:^1.0 php-http/guzzle6-adapter:^1.0 php-http/message:^1.0" + env: PACKAGES="php-http/discovery:^1.0 php-http/guzzle6-adapter:^1.0 php-http/message:^1.0 xabbuh/oauth1-authentication:~0.1" - php: 7.0 env: xdebug="yes" diff --git a/CHANGELOG.md b/CHANGELOG.md index 096c6d2..22a02da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,9 @@ CHANGELOG You can avoid calling `setHttpClient()` and `setRequestFactory` by installing the [HTTP discovery](http://php-http.org/en/latest/discovery.html) package. +* The `xabbuh/oauth1-authentication` package now must be installed if you want + to use OAuth1 authentication. + * Bumped the required versions of all `php-xapi` packages to the `1.x` release series. diff --git a/UPGRADE.md b/UPGRADE.md index c51870e..662edcf 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -43,6 +43,9 @@ Upgrading from 0.4 to 0.5 You can avoid calling `setHttpClient()` and `setRequestFactory` by installing the [HTTP discovery](http://php-http.org/en/latest/discovery.html) package. +* The `xabbuh/oauth1-authentication` package now must be installed if you want + to use OAuth1 authentication. + * A second optional `$attachments` argument (defaulting to `true`) has been added to the `getStatement()`, `getVoidedStatement()`, and `getStatements()` methods of the `StatementsApiClient` class and the `StatementsApiClientInterface`. diff --git a/composer.json b/composer.json index 528e734..8ca7cb8 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,8 @@ }, "minimum-stability": "dev", "suggest": { - "php-http/discovery": "For automatic discovery of HTTP clients and request factories" + "php-http/discovery": "For automatic discovery of HTTP clients and request factories", + "xabbuh/oauth1-authentication": "For OAuth1 authentication support" }, "conflict": { "xabbuh/xapi-client": "*" diff --git a/spec/XApiClientBuilderSpec.php b/spec/XApiClientBuilderSpec.php index dcffa59..9031199 100644 --- a/spec/XApiClientBuilderSpec.php +++ b/spec/XApiClientBuilderSpec.php @@ -85,6 +85,33 @@ function it_throws_an_exception_if_the_base_uri_is_not_configured(HttpClient $ht $this->shouldThrow('\LogicException')->during('build'); } + function it_throws_an_exception_when_oauth_credentials_are_configured_but_the_auth_package_is_missing(HttpClient $httpClient, RequestFactory $requestFactory) + { + if (class_exists('Xabbuh\Http\Authentication\OAuth1')) { + throw new SkippingException('OAuth1 credentials can be used when the "xabbuh/oauth1-authentication" package is present.'); + } + + $this->setHttpClient($httpClient); + $this->setRequestFactory($requestFactory); + $this->setBaseUrl('http://example.com/xapi/'); + $this->setOAuthCredentials('consumer_key', 'consumer_secret', 'access_token', 'token_secret'); + + $this->shouldThrow(new \LogicException('The "xabbuh/oauth1-authentication package is needed to use OAuth1 authorization.'))->during('build'); + } + + function it_accepts_oauth_credentials_when_the_auth_package_is_present(HttpClient $httpClient, RequestFactory $requestFactory) + { + if (!class_exists('Xabbuh\Http\Authentication\OAuth1')) { + throw new SkippingException('OAuth1 credentials cannot be used when the "xabbuh/oauth1-authentication" package is missing.'); + } + + $this->setHttpClient($httpClient); + $this->setRequestFactory($requestFactory); + $this->setBaseUrl('http://example.com/xapi/'); + $this->setOAuthCredentials('consumer_key', 'consumer_secret', 'access_token', 'token_secret'); + $this->build(); + } + private function isAbleToDiscoverHttpClient() { try { diff --git a/src/XApiClientBuilder.php b/src/XApiClientBuilder.php index 1ac1c16..1e8c260 100644 --- a/src/XApiClientBuilder.php +++ b/src/XApiClientBuilder.php @@ -11,6 +11,11 @@ namespace Xabbuh\XApi\Client; +use ApiClients\Tools\Psr7\Oauth1\Definition\AccessToken; +use ApiClients\Tools\Psr7\Oauth1\Definition\ConsumerKey; +use ApiClients\Tools\Psr7\Oauth1\Definition\ConsumerSecret; +use ApiClients\Tools\Psr7\Oauth1\Definition\TokenSecret; +use ApiClients\Tools\Psr7\Oauth1\RequestSigning\RequestSigner; use Http\Client\Common\Plugin\AuthenticationPlugin; use Http\Client\Common\PluginClient; use Http\Client\HttpClient; @@ -18,6 +23,7 @@ use Http\Discovery\MessageFactoryDiscovery; use Http\Message\Authentication\BasicAuth; use Http\Message\RequestFactory; +use Xabbuh\Http\Authentication\OAuth1; use Xabbuh\XApi\Client\Request\Handler; use Xabbuh\XApi\Serializer\SerializerFactoryInterface; use Xabbuh\XApi\Serializer\SerializerRegistry; @@ -46,7 +52,10 @@ final class XApiClientBuilder implements XApiClientBuilderInterface private $version; private $username; private $password; - private $oAuthCredentials; + private $consumerKey; + private $consumerSecret; + private $accessToken; + private $tokenSecret; public function __construct(SerializerFactoryInterface $serializerFactory = null) { @@ -109,12 +118,10 @@ public function setAuth($username, $password) */ public function setOAuthCredentials($consumerKey, $consumerSecret, $token, $tokenSecret) { - $this->oAuthCredentials = array( - 'consumer_key' => $consumerKey, - 'consumer_secret' => $consumerSecret, - 'token' => $token, - 'token_secret' => $tokenSecret, - ); + $this->consumerKey = $consumerKey; + $this->consumerSecret = $consumerSecret; + $this->accessToken = $token; + $this->tokenSecret = $tokenSecret; return $this; } @@ -156,8 +163,24 @@ public function build() $serializerRegistry->setActorSerializer($this->serializerFactory->createActorSerializer()); $serializerRegistry->setDocumentDataSerializer($this->serializerFactory->createDocumentDataSerializer()); + $plugins = array(); + if (null !== $this->username && null !== $this->password) { - $httpClient = new PluginClient($httpClient, array(new AuthenticationPlugin(new BasicAuth($this->username, $this->password)))); + $plugins[] = new AuthenticationPlugin(new BasicAuth($this->username, $this->password)); + } + + if (null !== $this->consumerKey && null !== $this->consumerSecret && null !== $this->accessToken && null !== $this->tokenSecret) { + if (!class_exists('Xabbuh\Http\Authentication\OAuth1')) { + throw new \LogicException('The "xabbuh/oauth1-authentication package is needed to use OAuth1 authorization.'); + } + + $requestSigner = new RequestSigner(new ConsumerKey($this->consumerKey), new ConsumerSecret($this->consumerSecret)); + $oauth = new OAuth1($requestSigner, new AccessToken($this->accessToken), new TokenSecret($this->tokenSecret)); + $plugins[] = new AuthenticationPlugin($oauth); + } + + if (!empty($plugins)) { + $httpClient = new PluginClient($httpClient, $plugins); } $version = null === $this->version ? '1.0.1' : $this->version;