diff --git a/src/Api.php b/src/Api.php index 376aa92..77b4435 100644 --- a/src/Api.php +++ b/src/Api.php @@ -126,14 +126,6 @@ class Api $consumer_key = null, Client $http_client = null ) { - if (!isset($application_key)) { - throw new Exceptions\InvalidParameterException("Application key parameter is empty"); - } - - if (!isset($application_secret)) { - throw new Exceptions\InvalidParameterException("Application secret parameter is empty"); - } - if (!isset($api_endpoint)) { throw new Exceptions\InvalidParameterException("Endpoint parameter is empty"); } @@ -236,6 +228,17 @@ class Api */ protected function rawCall($method, $path, $content = null, $is_authenticated = true, $headers = null) { + if ( $is_authenticated ) + { + if (!isset($this->application_key)) { + throw new Exceptions\InvalidParameterException("Application key parameter is empty"); + } + + if (!isset($this->application_secret)) { + throw new Exceptions\InvalidParameterException("Application secret parameter is empty"); + } + } + $url = $this->endpoint . $path; $request = new Request($method, $url); if (isset($content) && $method == 'GET') { @@ -278,9 +281,11 @@ class Api $headers = []; } $headers['Content-Type'] = 'application/json; charset=utf-8'; - $headers['X-Ovh-Application'] = $this->application_key; if ($is_authenticated) { + + $headers['X-Ovh-Application'] = $this->application_key; + if (!isset($this->time_delta)) { $this->calculateTimeDelta(); } @@ -318,15 +323,27 @@ class Api * * @param string $path path ask inside api * @param array $content content to send inside body of request + * @param array headers custom HTTP headers to add on the request + * @param bool is_authenticated if the request need to be authenticated * * @return array * @throws \GuzzleHttp\Exception\ClientException if http request is an error */ - public function get($path, $content = null, $headers = null) + public function get($path, $content = null, $headers = null, $is_authenticated = true) { - return $this->decodeResponse( - $this->rawCall("GET", $path, $content, true, $headers) - ); + if(preg_match('/^\/[^\/]+\.json$/', $path)) + { + // Schema description must be access without authentication + return $this->decodeResponse( + $this->rawCall("GET", $path, $content, false, $headers) + ); + } + else + { + return $this->decodeResponse( + $this->rawCall("GET", $path, $content, $is_authenticated, $headers) + ); + } } /** @@ -334,14 +351,16 @@ class Api * * @param string $path path ask inside api * @param array $content content to send inside body of request + * @param array headers custom HTTP headers to add on the request + * @param bool is_authenticated if the request need to be authenticated * * @return array * @throws \GuzzleHttp\Exception\ClientException if http request is an error */ - public function post($path, $content = null, $headers = null) + public function post($path, $content = null, $headers = null, $is_authenticated = true) { return $this->decodeResponse( - $this->rawCall("POST", $path, $content, true, $headers) + $this->rawCall("POST", $path, $content, $is_authenticated, $headers) ); } @@ -350,14 +369,16 @@ class Api * * @param string $path path ask inside api * @param array $content content to send inside body of request + * @param array headers custom HTTP headers to add on the request + * @param bool is_authenticated if the request need to be authenticated * * @return array * @throws \GuzzleHttp\Exception\ClientException if http request is an error */ - public function put($path, $content, $headers = null) + public function put($path, $content, $headers = null, $is_authenticated = true) { return $this->decodeResponse( - $this->rawCall("PUT", $path, $content, true, $headers) + $this->rawCall("PUT", $path, $content, $is_authenticated, $headers) ); } @@ -366,14 +387,16 @@ class Api * * @param string $path path ask inside api * @param array $content content to send inside body of request + * @param array headers custom HTTP headers to add on the request + * @param bool is_authenticated if the request need to be authenticated * * @return array * @throws \GuzzleHttp\Exception\ClientException if http request is an error */ - public function delete($path, $content = null, $headers = null) + public function delete($path, $content = null, $headers = null, $is_authenticated = true) { return $this->decodeResponse( - $this->rawCall("DELETE", $path, $content, true, $headers) + $this->rawCall("DELETE", $path, $content, $is_authenticated, $headers) ); } diff --git a/tests/ApiFunctionalTest.php b/tests/ApiFunctionalTest.php index a1b9883..59d3954 100644 --- a/tests/ApiFunctionalTest.php +++ b/tests/ApiFunctionalTest.php @@ -250,4 +250,13 @@ class ApiFunctionalTest extends \PHPUnit_Framework_TestCase { $this->api->get('/me/api/credential', ['status' => 'pendingValidation']); } + + /** + * Test APi::get without authentication + */ + public function testApiGetWithoutAuthentication() + { + $api = new Api(NULL,NULL, $this->endpoint, null, $this->client); + $api->get('/hosting/web/moduleList',null,null,false); + } } diff --git a/tests/ApiTest.php b/tests/ApiTest.php index fdb464e..e9790b8 100644 --- a/tests/ApiTest.php +++ b/tests/ApiTest.php @@ -117,7 +117,8 @@ class ApiTest extends \PHPUnit_Framework_TestCase public function testMissingApplicationKey() { $this->setExpectedException('\\Ovh\\Exceptions\\InvalidParameterException', 'Application key'); - new Api(null, $this->application_secret, $this->endpoint, $this->consumer_key, $this->client); + $api = new Api(null, $this->application_secret, $this->endpoint, $this->consumer_key, $this->client); + $api->get('/me'); } /** @@ -126,7 +127,29 @@ class ApiTest extends \PHPUnit_Framework_TestCase public function testMissingApplicationSecret() { $this->setExpectedException('\\Ovh\\Exceptions\\InvalidParameterException', 'Application secret'); - new Api($this->application_key, null, $this->endpoint, $this->consumer_key, $this->client); + $api = new Api($this->application_key, null, $this->endpoint, $this->consumer_key, $this->client); + $api->get('/me'); + } + + /** + * Test we don't check Application Key for unauthenticated call + */ + public function testNoCheckAppKeyForUnauthCall() + { + $handlerStack = $this->client->getConfig('handler'); + $handlerStack->push(Middleware::mapRequest(function (Request $request) { + if($request->getUri()->getPath() == "/1.0/unauthcall") { + return $request; + } + + $request = $request->withUri($request->getUri() + ->withHost('httpbin.org') + ->withPath('/') + ->withQuery('')); + return $request; + })); + $api = new Api(NULL, NULL, $this->endpoint, $this->consumer_key, $this->client); + $api->get('/1.0/unauthcall', null, null, false); } /**