1
0
mirror of https://github.com/ovh/php-ovh.git synced 2023-11-05 03:20:26 +01:00

Merge pull request #125 from deathiop/v2

feat: allow /v1 or /v2 prefixes in path
This commit is contained in:
Romain Beuque 2023-04-07 10:09:14 +02:00 committed by GitHub
commit 9a29f720d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 288 additions and 362 deletions

View File

@ -6,6 +6,9 @@
<property name="lineLimit" value="180"/> <property name="lineLimit" value="180"/>
</properties> </properties>
</rule> </rule>
<rule ref="PSR1.Classes.ClassDeclaration.MultipleClasses">
<exclude-pattern>*/tests/*</exclude-pattern>
</rule>
<file>src</file> <file>src</file>
<file>tests</file> <file>tests</file>
<arg name="encoding" value="utf-8"/> <arg name="encoding" value="utf-8"/>

View File

@ -211,6 +211,24 @@ class Api
return $response; return $response;
} }
/**
* getTarget returns the URL to target given an endpoint and a path.
* If the path starts with `/v1` or `/v2`, then remove the trailing `/1.0` from the endpoint.
*
* @param string path to use prefix from
* @return string
*/
protected function getTarget($path) : string
{
$endpoint = $this->endpoint;
if (substr($endpoint, -4) == '/1.0' && (
substr($path, 0, 3) == '/v1' ||
substr($path, 0, 3) == '/v2')) {
$endpoint = substr($endpoint, 0, strlen($endpoint)-4);
}
return $endpoint . $path;
}
/** /**
* This is the main method of this wrapper. It will * This is the main method of this wrapper. It will
* sign a given query and return its result. * sign a given query and return its result.
@ -238,7 +256,7 @@ class Api
} }
} }
$url = $this->endpoint . $path; $url = $this->getTarget($path);
$request = new Request($method, $url); $request = new Request($method, $url);
if (isset($content) && $method === 'GET') { if (isset($content) && $method === 'GET') {
$query_string = $request->getUri()->getQuery(); $query_string = $request->getUri()->getQuery();
@ -280,9 +298,8 @@ class Api
} }
$headers['Content-Type'] = 'application/json; charset=utf-8'; $headers['Content-Type'] = 'application/json; charset=utf-8';
$headers['X-Ovh-Application'] = $this->application_key ?? '';
if ($is_authenticated) { if ($is_authenticated) {
$headers['X-Ovh-Application'] = $this->application_key;
if (!isset($this->time_delta)) { if (!isset($this->time_delta)) {
$this->calculateTimeDelta(); $this->calculateTimeDelta();
} }

View File

@ -86,6 +86,13 @@ class ApiFunctionalTest extends TestCase
*/ */
protected function setUp() :void protected function setUp() :void
{ {
foreach (['APP_KEY', 'APP_SECRET', 'CONSUMER', 'ENDPOINT'] as $envName) {
if (!getenv($envName)) {
$this->markTestSkipped("Skip test due to missing $envName variable");
return;
}
}
$this->application_key = getenv('APP_KEY'); $this->application_key = getenv('APP_KEY');
$this->application_secret = getenv('APP_SECRET'); $this->application_secret = getenv('APP_SECRET');
$this->consumer_key = getenv('CONSUMER'); $this->consumer_key = getenv('CONSUMER');

View File

@ -29,6 +29,8 @@ namespace Ovh\tests;
use GuzzleHttp\Client; use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException; use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware; use GuzzleHttp\Middleware;
use GuzzleHttp\Psr7; use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\Response; use GuzzleHttp\Psr7\Response;
@ -37,6 +39,29 @@ use Ovh\Api;
use Ovh\Exceptions\InvalidParameterException; use Ovh\Exceptions\InvalidParameterException;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
# Mock values
const MOCK_APPLICATION_KEY = "TDPKJdwZwAQPwKX2";
const MOCK_APPLICATION_SECRET = "9ufkBmLaTQ9nz5yMUlg79taH0GNnzDjk";
const MOCK_CONSUMER_KEY = "5mBuy6SUQcRw2ZUxg0cG68BoDKpED4KY";
const MOCK_TIME = 1457018875;
class MockClient extends Client
{
public $calls = [];
public function __construct(...$responses)
{
$mock = new MockHandler($responses);
$history = Middleware::history($this->calls);
$handlerStack = HandlerStack::create($mock);
$handlerStack->push($history);
parent::__construct(['handler' => $handlerStack]);
}
}
/** /**
* Test Api class * Test Api class
* *
@ -45,60 +70,6 @@ use PHPUnit\Framework\TestCase;
*/ */
class ApiTest extends TestCase class ApiTest extends TestCase
{ {
/**
* @var Client
*/
private $client;
/**
* @var string
*/
private $application_key;
/**
* @var string
*/
private $consumer_key;
/**
* @var string
*/
private $endpoint;
/**
* @var string
*/
private $application_secret;
/**
* Define id to create object
*/
protected function setUp() :void
{
$this->application_key = 'app_key';
$this->application_secret = 'app_secret';
$this->consumer_key = 'consumer';
$this->endpoint = 'ovh-eu';
$this->client = new Client();
}
/**
* Get private and protected method to unit test it
*
* @param string $name
*
* @return \ReflectionMethod
*/
protected static function getPrivateMethod($name)
{
$class = new \ReflectionClass('Ovh\Api');
$method = $class->getMethod($name);
$method->setAccessible(true);
return $method;
}
/** /**
* Get private and protected property to unit test it * Get private and protected property to unit test it
* *
@ -121,7 +92,8 @@ class ApiTest extends TestCase
public function testMissingApplicationKey() public function testMissingApplicationKey()
{ {
$this->expectException(InvalidParameterException::class); $this->expectException(InvalidParameterException::class);
$api = new Api(null, $this->application_secret, $this->endpoint, $this->consumer_key, $this->client); $this->expectExceptionMessage('Application key parameter is empty');
$api = new Api(null, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY, new MockClient());
$api->get('/me'); $api->get('/me');
} }
@ -131,7 +103,8 @@ class ApiTest extends TestCase
public function testMissingApplicationSecret() public function testMissingApplicationSecret()
{ {
$this->expectException(InvalidParameterException::class); $this->expectException(InvalidParameterException::class);
$api = new Api($this->application_key, null, $this->endpoint, $this->consumer_key, $this->client); $this->expectExceptionMessage('Application secret parameter is empty');
$api = new Api(MOCK_APPLICATION_KEY, null, 'ovh-eu', MOCK_CONSUMER_KEY, new MockClient());
$api->get('/me'); $api->get('/me');
} }
@ -140,25 +113,18 @@ class ApiTest extends TestCase
*/ */
public function testNoCheckAppKeyForUnauthCall() public function testNoCheckAppKeyForUnauthCall()
{ {
$handlerStack = $this->client->getConfig('handler'); $client = new MockClient(new Response(200, [], '{}'));
$handlerStack->push(Middleware::mapRequest(function (Request $request) {
if ($request->getUri()->getPath() == "/1.0/unauthcall") {
return $request;
}
return null; $api = new Api(null, null, 'ovh-eu', null, $client);
})); $api->get("/me", null, null, false);
$handlerStack->push(Middleware::mapResponse(function (Response $response) {
$body = Psr7\Utils::streamFor('{}');
return $response $calls = $client->calls;
->withStatus(200) $this->assertEquals(1, count($calls));
->withHeader('Content-Type', 'application/json; charset=utf-8')
->withBody($body); $req = $calls[0]['request'];
})); $this->assertEquals('GET', $req->getMethod());
$api = new Api(null, null, $this->endpoint, $this->consumer_key, $this->client); $this->assertEquals('https://eu.api.ovh.com/1.0/me', $req->getUri()->__toString());
$api->get('/unauthcall', null, null, false); $this->assertEquals('', $req->getHeaderLine('X-Ovh-Application'));
$this->assertEquals(1, 1);
} }
/** /**
@ -167,7 +133,8 @@ class ApiTest extends TestCase
public function testMissingApiEndpoint() public function testMissingApiEndpoint()
{ {
$this->expectException(InvalidParameterException::class); $this->expectException(InvalidParameterException::class);
new Api($this->application_key, $this->application_secret, null, $this->consumer_key, $this->client); $this->expectExceptionMessage('Endpoint parameter is empty');
new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, null, MOCK_CONSUMER_KEY, new MockClient());
} }
/** /**
@ -176,7 +143,8 @@ class ApiTest extends TestCase
public function testBadApiEndpoint() public function testBadApiEndpoint()
{ {
$this->expectException(InvalidParameterException::class); $this->expectException(InvalidParameterException::class);
new Api($this->application_key, $this->application_secret, 'i_am_invalid', $this->consumer_key, $this->client); $this->expectExceptionMessage('Unknown provided endpoint');
new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'i_am_invalid', MOCK_CONSUMER_KEY, new MockClient());
} }
/** /**
@ -184,8 +152,7 @@ class ApiTest extends TestCase
*/ */
public function testClientCreation() public function testClientCreation()
{ {
$api = new Api($this->application_key, $this->application_secret, $this->endpoint, $this->consumer_key); $api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY);
$this->assertInstanceOf('\\GuzzleHttp\\Client', $api->getHttpClient()); $this->assertInstanceOf('\\GuzzleHttp\\Client', $api->getHttpClient());
} }
@ -194,28 +161,28 @@ class ApiTest extends TestCase
*/ */
public function testTimeDeltaCompute() public function testTimeDeltaCompute()
{ {
$delay = 10; $client = new MockClient(
new Response(200, [], time() - 10),
new Response(200, [], '{}'),
);
$handlerStack = $this->client->getConfig('handler'); $api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY, $client);
$handlerStack->push(Middleware::mapResponse(function (Response $response) { $api->get("/me");
$body = Psr7\Utils::streamFor(time() - 10);
return $response
->withStatus(200)
->withHeader('Content-Type', 'application/json; charset=utf-8')
->withBody($body);
}));
$invoker = self::getPrivateMethod('calculateTimeDelta');
$property = self::getPrivateProperty('time_delta'); $property = self::getPrivateProperty('time_delta');
$api = new Api($this->application_key, $this->application_secret, $this->endpoint, $this->consumer_key, $this->client);
$invoker->invokeArgs($api, []);
$time_delta = $property->getValue($api); $time_delta = $property->getValue($api);
$this->assertNotNull($time_delta); $this->assertEquals($time_delta, -10);
$this->assertEquals($time_delta, $delay * -1);
$calls = $client->calls;
$this->assertEquals(2, count($calls));
$req = $calls[0]['request'];
$this->assertEquals('GET', $req->getMethod());
$this->assertEquals('https://eu.api.ovh.com/1.0/auth/time', $req->getUri()->__toString());
$req = $calls[1]['request'];
$this->assertEquals('GET', $req->getMethod());
$this->assertEquals('https://eu.api.ovh.com/1.0/me', $req->getUri()->__toString());
} }
/** /**
@ -223,32 +190,30 @@ class ApiTest extends TestCase
*/ */
public function testIfConsumerKeyIsReplace() public function testIfConsumerKeyIsReplace()
{ {
$handlerStack = $this->client->getConfig('handler'); $client = new MockClient(
$handlerStack->push(Middleware::mapResponse(function (Response $response) { new Response(200, [], MOCK_TIME),
new Response(
200,
['Content-Type' => 'application/json; charset=utf-8'],
'{"validationUrl":"https://api.ovh.com/login/?credentialToken=token","consumerKey":"consumer_remote","state":"pendingValidation"}'
),
);
$body = Psr7\Utils::streamFor('{"validationUrl":"https://api.ovh.com/login/?credentialToken=token","consumerKey":"consumer_remote","state":"pendingValidation"}'); $api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY, $client);
$this->assertNotEquals('consumer_remote', $api->getConsumerKey());
$credentials = $api->requestCredentials(['method' => 'GET', 'path' => '/*']);
$this->assertEquals('consumer_remote', $api->getConsumerKey());
return $response $calls = $client->calls;
->withStatus(200) $this->assertEquals(2, count($calls));
->withHeader('Content-Type', 'application/json; charset=utf-8')
->withBody($body);
}));
$property = self::getPrivateProperty('consumer_key'); $req = $calls[0]['request'];
$this->assertEquals('GET', $req->getMethod());
$this->assertEquals('https://eu.api.ovh.com/1.0/auth/time', $req->getUri()->__toString());
$this->assertEquals('consumer', $this->consumer_key); $req = $calls[1]['request'];
$this->assertNotEquals('consumer_remote', $this->consumer_key); $this->assertEquals('POST', $req->getMethod());
$this->assertEquals('https://eu.api.ovh.com/1.0/auth/credential', $req->getUri()->__toString());
$api = new Api($this->application_key, $this->application_secret, $this->endpoint, $this->consumer_key, $this->client);
$accessRules = [json_decode(' { "method": "GET", "path": "/*" } ')];
$credentials = $api->requestCredentials($accessRules);
$consumer_key = $property->getValue($api);
$this->assertEquals($consumer_key, $credentials["consumerKey"]);
$this->assertEquals('consumer_remote', $credentials["consumerKey"]);
$this->assertNotEquals($consumer_key, $this->consumer_key);
} }
/** /**
@ -256,30 +221,15 @@ class ApiTest extends TestCase
*/ */
public function testInvalidApplicationKey() public function testInvalidApplicationKey()
{ {
$error = '{"class":"Client::Forbidden","message":"Invalid application key"}';
$this->expectException(ClientException::class); $this->expectException(ClientException::class);
$this->expectExceptionCode(403);
$this->expectExceptionMessage($error);
$handlerStack = $this->client->getConfig('handler'); $client = new MockClient(new Response(403, ['Content-Type' => 'application/json; charset=utf-8'], $error));
$handlerStack->push(Middleware::mapResponse(function (Response $response) {
$body = Psr7\Utils::streamFor('{\"message\":\"Invalid application key\"}'); $api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY, $client);
$api->requestCredentials(['method' => 'GET', 'path' => '/*']);
return $response
->withStatus(401, 'POUET')
->withHeader('Content-Type', 'application/json; charset=utf-8')
->withHeader('Content-Length', 37)
->withBody($body);
}));
$property = self::getPrivateProperty('consumer_key');
$api = new Api($this->application_key, $this->application_secret, $this->endpoint, $this->consumer_key, $this->client);
$accessRules = [json_decode(' { "method": "GET", "path": "/*" } ')];
$credentials = $api->requestCredentials($accessRules);
$consumer_key = $property->getValue($api);
$this->assertEquals($consumer_key, $credentials["consumerKey"]);
$this->assertNotEquals($consumer_key, $this->consumer_key);
} }
/** /**
@ -287,30 +237,21 @@ class ApiTest extends TestCase
*/ */
public function testInvalidRight() public function testInvalidRight()
{ {
$error = '{"message": "Invalid credentials"}';
$this->expectException(ClientException::class); $this->expectException(ClientException::class);
$this->expectExceptionCode(403);
$this->expectExceptionMessage($error);
$handlerStack = $this->client->getConfig('handler'); $client = new MockClient(new Response(403, ['Content-Type' => 'application/json; charset=utf-8'], $error));
$handlerStack->push(Middleware::mapResponse(function (Response $response) {
$body = Psr7\Utils::streamFor('{\"message\":\"Invalid credentials\"}'); $api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY, $client);
$api->get('/me', null, null, false);
return $response
->withStatus(403)
->withHeader('Content-Type', 'application/json; charset=utf-8')
->withHeader('Content-Length', 37)
->withBody($body);
}));
$api = new Api($this->application_key, $this->application_secret, $this->endpoint, $this->consumer_key, $this->client);
$invoker = self::getPrivateMethod('rawCall');
$invoker->invokeArgs($api, ['GET', '/me']);
} }
public function testGetConsumerKey() public function testGetConsumerKey()
{ {
$api = new Api($this->application_key, $this->application_secret, $this->endpoint, $this->consumer_key, $this->client); $api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY);
$this->assertEquals($this->consumer_key, $api->getConsumerKey()); $this->assertEquals(MOCK_CONSUMER_KEY, $api->getConsumerKey());
} }
@ -319,32 +260,17 @@ class ApiTest extends TestCase
*/ */
public function testGetQueryArgs() public function testGetQueryArgs()
{ {
$handlerStack = $this->client->getConfig('handler'); $client = new MockClient(new Response(200, [], '{}'));
$handlerStack->push(Middleware::mapRequest(function (Request $request) {
if ($request->getUri()->getPath() == "/1.0/auth/time") {
return $request;
}
$query_string = $request->getUri()->getQuery(); $api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY, $client);
$this->assertEquals($query_string, 'applicationId=49&status=pendingValidation'); $api->get('/me/api/credential?applicationId=49', ['status' => 'pendingValidation'], null, false);
$request = $request->withUri($request->getUri() $calls = $client->calls;
->withHost('httpbin.org') $this->assertEquals(1, count($calls));
->withPath('/')
->withQuery(''));
return $request;
}));
$handlerStack->push(Middleware::mapResponse(function (Response $response) {
$body = Psr7\Utils::streamFor('123456789991');
return $response $req = $calls[0]['request'];
->withStatus(200) $this->assertEquals('GET', $req->getMethod());
->withHeader('Content-Type', 'application/json; charset=utf-8') $this->assertEquals('https://eu.api.ovh.com/1.0/me/api/credential?applicationId=49&status=pendingValidation', $req->getUri()->__toString());
->withBody($body);
}));
$api = new Api($this->application_key, $this->application_secret, $this->endpoint, $this->consumer_key, $this->client);
$api->get('/me/api/credential?applicationId=49', ['status' => 'pendingValidation']);
} }
/** /**
@ -352,32 +278,17 @@ class ApiTest extends TestCase
*/ */
public function testGetOverlappingQueryArgs() public function testGetOverlappingQueryArgs()
{ {
$handlerStack = $this->client->getConfig('handler'); $client = new MockClient(new Response(200, [], '{}'));
$handlerStack->push(Middleware::mapRequest(function (Request $request) {
if ($request->getUri()->getPath() == "/1.0/auth/time") {
return $request;
}
$query_string = $request->getUri()->getQuery(); $api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY, $client);
$this->assertEquals($query_string, 'applicationId=49&status=expired&test=success'); $api->get('/me/api/credential?applicationId=49&status=pendingValidation', ['status' => 'expired', 'test' => "success"], null, false);
$request = $request->withUri($request->getUri() $calls = $client->calls;
->withHost('httpbin.org') $this->assertEquals(1, count($calls));
->withPath('/')
->withQuery(''));
return $request;
}));
$handlerStack->push(Middleware::mapResponse(function (Response $response) {
$body = Psr7\Utils::streamFor('123456789991');
return $response $req = $calls[0]['request'];
->withStatus(200) $this->assertEquals('GET', $req->getMethod());
->withHeader('Content-Type', 'application/json; charset=utf-8') $this->assertEquals('https://eu.api.ovh.com/1.0/me/api/credential?applicationId=49&status=expired&test=success', $req->getUri()->__toString());
->withBody($body);
}));
$api = new Api($this->application_key, $this->application_secret, $this->endpoint, $this->consumer_key, $this->client);
$api->get('/me/api/credential?applicationId=49&status=pendingValidation', ['status' => 'expired', 'test' => "success"]);
} }
/** /**
@ -385,149 +296,41 @@ class ApiTest extends TestCase
*/ */
public function testGetBooleanQueryArgs() public function testGetBooleanQueryArgs()
{ {
$handlerStack = $this->client->getConfig('handler'); $client = new MockClient(new Response(200, [], '{}'));
$handlerStack->push(Middleware::mapRequest(function (Request $request) {
if ($request->getUri()->getPath() == "/1.0/auth/time") {
return $request;
}
$query_string = $request->getUri()->getQuery(); $api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY, $client);
$this->assertEquals($query_string, 'dryRun=true&notDryRun=false'); $api->get('/me/api/credential', ['dryRun' => true, 'notDryRun' => false], null, false);
$request = $request->withUri($request->getUri() $calls = $client->calls;
->withHost('httpbin.org') $this->assertEquals(1, count($calls));
->withPath('/')
->withQuery(''));
return $request;
}));
$handlerStack->push(Middleware::mapResponse(function (Response $response) {
$body = Psr7\Utils::streamFor('123456789991');
return $response $req = $calls[0]['request'];
->withStatus(200) $this->assertEquals('GET', $req->getMethod());
->withHeader('Content-Type', 'application/json; charset=utf-8') $this->assertEquals('https://eu.api.ovh.com/1.0/me/api/credential?dryRun=true&notDryRun=false', $req->getUri()->__toString());
->withBody($body);
}));
$api = new Api($this->application_key, $this->application_secret, $this->endpoint, $this->consumer_key, $this->client);
$api->get('/me/api/credential', ['dryRun' => true, 'notDryRun' => false]);
} }
/** /**
* Test valid predefined endpoint * Test valid provided endpoint
*/ */
public function testPredefinedEndPoint() public function testProvidedUrl()
{ {
$handlerStack = $this->client->getConfig('handler'); foreach ([
$handlerStack->push(Middleware::mapRequest(function (Request $request) { ['endpoint' => 'http://api.ovh.com/1.0', 'expectedUrl' => 'http://api.ovh.com/1.0'],
if ($request->getUri()->getPath() == "/1.0/auth/time") { ['endpoint' => 'https://api.ovh.com/1.0', 'expectedUrl' => 'https://api.ovh.com/1.0'],
return $request; ['endpoint' => 'ovh-eu', 'expectedUrl' => 'https://eu.api.ovh.com/1.0'],
} ] as $test) {
$client = new MockClient(new Response(200, [], '{}'));
$host = $request->getUri()->getHost(); $api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, $test['endpoint'], MOCK_CONSUMER_KEY, $client);
$this->assertEquals($host, 'ca.api.ovh.com'); $api->get('/me/api/credential', null, null, false);
$resource = $request->getUri()->getPath(); $calls = $client->calls;
$this->assertEquals($resource, '/1.0/me/api/credential'); $this->assertEquals(1, count($calls));
$resource = $request->getUri()->getScheme(); $req = $calls[0]['request'];
$this->assertEquals($resource, 'https'); $this->assertEquals('GET', $req->getMethod());
$this->assertEquals($test['expectedUrl'] . '/me/api/credential', $req->getUri()->__toString());
$request = $request->withUri($request->getUri() }
->withHost('httpbin.org')
->withPath('/')
->withQuery(''));
return $request;
}));
$handlerStack->push(Middleware::mapResponse(function (Response $response) {
$body = Psr7\Utils::streamFor('123456789991');
return $response
->withStatus(200)
->withHeader('Content-Type', 'application/json; charset=utf-8')
->withBody($body);
}));
$api = new Api($this->application_key, $this->application_secret, 'ovh-ca', $this->consumer_key, $this->client);
$api->get('/me/api/credential');
}
/**
* Test valid provided HTTP endpoint
*/
public function testProvidedHttpEndPoint()
{
$handlerStack = $this->client->getConfig('handler');
$handlerStack->push(Middleware::mapRequest(function (Request $request) {
if ($request->getUri()->getPath() == "/1.0/auth/time") {
return $request;
}
$host = $request->getUri()->getHost();
$this->assertEquals($host, 'api.ovh.com');
$resource = $request->getUri()->getPath();
$this->assertEquals($resource, '/1.0/me/api/credential');
$resource = $request->getUri()->getScheme();
$this->assertEquals($resource, 'http');
$request = $request->withUri($request->getUri()
->withHost('httpbin.org')
->withPath('/')
->withQuery(''));
return $request;
}));
$handlerStack->push(Middleware::mapResponse(function (Response $response) {
$body = Psr7\Utils::streamFor('123456789991');
return $response
->withStatus(200)
->withHeader('Content-Type', 'application/json; charset=utf-8')
->withBody($body);
}));
$api = new Api($this->application_key, $this->application_secret, 'http://api.ovh.com/1.0', $this->consumer_key, $this->client);
$api->get('/me/api/credential');
}
/**
* Test valid provided HTTPS endpoint
*/
public function testProvidedHttpsEndPoint()
{
$handlerStack = $this->client->getConfig('handler');
$handlerStack->push(Middleware::mapRequest(function (Request $request) {
if ($request->getUri()->getPath() == "/1.0/auth/time") {
return $request;
}
$host = $request->getUri()->getHost();
$this->assertEquals($host, 'api.ovh.com');
$resource = $request->getUri()->getPath();
$this->assertEquals($resource, '/1.0/me/api/credential');
$resource = $request->getUri()->getScheme();
$this->assertEquals($resource, 'https');
$request = $request->withUri($request->getUri()
->withHost('httpbin.org')
->withPath('/')
->withQuery(''));
return $request;
}));
$handlerStack->push(Middleware::mapResponse(function (Response $response) {
$body = Psr7\Utils::streamFor('123456789991');
return $response
->withStatus(200)
->withHeader('Content-Type', 'application/json; charset=utf-8')
->withBody($body);
}));
$api = new Api($this->application_key, $this->application_secret, 'https://api.ovh.com/1.0', $this->consumer_key, $this->client);
$api->get('/me/api/credential');
} }
/** /**
@ -535,32 +338,128 @@ class ApiTest extends TestCase
*/ */
public function testMissingOvhApplicationHeaderOnRequestCredentials() public function testMissingOvhApplicationHeaderOnRequestCredentials()
{ {
$handlerStack = $this->client->getConfig('handler'); $client = new MockClient(
$handlerStack->push(Middleware::mapRequest(function (Request $request) { new Response(200, [], MOCK_TIME),
if ($request->getUri()->getPath() == "/1.0/auth/time") { new Response(200, [], '{"validationUrl":"https://api.ovh.com/login/?credentialToken=token","consumerKey":"consumer_remote","state":"pendingValidation"}'),
return $request; );
}
$ovhApplication = $request->getHeader('X-OVH-Application'); $api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY, $client);
$this->assertNotNull($ovhApplication);
$this->assertEquals($ovhApplication, array($this->application_key));
$request = $request->withUri($request->getUri()
->withHost('httpbin.org')
->withPath('/')
->withQuery(''));
return $request;
}));
$handlerStack->push(Middleware::mapResponse(function (Response $response) {
$body = Psr7\Utils::streamFor('{"validationUrl":"https://api.ovh.com/login/?credentialToken=token","consumerKey":"consumer_remote","state":"pendingValidation"}');
return $response
->withStatus(200)
->withHeader('Content-Type', 'application/json; charset=utf-8')
->withBody($body);
}));
$api = new Api($this->application_key, $this->application_secret, $this->endpoint, $this->consumer_key, $this->client);
$api->requestCredentials([]); $api->requestCredentials([]);
$calls = $client->calls;
$this->assertEquals(2, count($calls));
$req = $calls[0]['request'];
$this->assertEquals('GET', $req->getMethod());
$this->assertEquals('https://eu.api.ovh.com/1.0/auth/time', $req->getUri()->__toString());
$req = $calls[1]['request'];
$this->assertEquals('POST', $req->getMethod());
$this->assertEquals('https://eu.api.ovh.com/1.0/auth/credential', $req->getUri()->__toString());
$this->assertEquals(MOCK_APPLICATION_KEY, $req->getHeaderLine('X-Ovh-Application'));
$this->assertEquals(MOCK_CONSUMER_KEY, $req->getHeaderLine('X-Ovh-Consumer'));
$this->assertEquals(MOCK_TIME, $req->getHeaderLine('X-Ovh-Timestamp'));
}
public function testCallSignature()
{
// GET /auth/time
$mocks = [new Response(200, [], MOCK_TIME)];
// (GET,POST,PUT,DELETE) x (/auth,/unauth)
for ($i = 0; $i < 8; $i++) {
$mocks[] = new Response(200, [], '{}');
}
$client = new MockClient(...$mocks);
$api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY, $client);
$body = ["a" => "b", "c" => "d"];
// Authenticated calls
$api->get('/auth');
$api->post('/auth', $body);
$api->put('/auth', $body);
$api->delete('/auth');
// Unauth calls
$api->get('/unauth', null, null, false);
$api->post('/unauth', $body, null, false);
$api->put('/unauth', $body, null, false);
$api->delete('/unauth', null, null, false);
$calls = $client->calls;
$this->assertEquals(9, count($calls));
$req = $calls[0]['request'];
$this->assertEquals('GET', $req->getMethod());
$this->assertEquals('https://eu.api.ovh.com/1.0/auth/time', $req->getUri()->__toString());
foreach ([
1 => ['method' => 'GET', 'sig' => '$1$e9556054b6309771395efa467c22e627407461ad'],
2 => ['method' => 'POST', 'sig' => '$1$ec2fb5c7a81f64723c77d2e5b609ae6f58a84fc1'],
3 => ['method' => 'PUT', 'sig' => '$1$8a75a9e7c8e7296c9dbeda6a2a735eb6bd58ec4b'],
4 => ['method' => 'DELETE', 'sig' => '$1$a1eecd00b3b02b6cf5708b84b9ff42059a950d85'],
] as $i => $test) {
$req = $calls[$i]['request'];
$this->assertEquals($test['method'], $req->getMethod());
$this->assertEquals('https://eu.api.ovh.com/1.0/auth', $req->getUri()->__toString());
$this->assertEquals(MOCK_APPLICATION_KEY, $req->getHeaderLine('X-Ovh-Application'));
$this->assertEquals(MOCK_CONSUMER_KEY, $req->getHeaderLine('X-Ovh-Consumer'));
$this->assertEquals(MOCK_TIME, $req->getHeaderLine('X-Ovh-Timestamp'));
$this->assertEquals($test['sig'], $req->getHeaderLine('X-Ovh-Signature'));
if ($test['method'] == 'POST' || $test['method'] == 'PUT') {
$this->assertEquals('application/json; charset=utf-8', $req->getHeaderLine('Content-Type'));
}
}
foreach (['GET', 'POST', 'PUT', 'DELETE'] as $i => $method) {
$req = $calls[$i + 5]['request'];
$this->assertEquals($method, $req->getMethod());
$this->assertEquals('https://eu.api.ovh.com/1.0/unauth', $req->getUri()->__toString());
$this->assertEquals(MOCK_APPLICATION_KEY, $req->getHeaderLine('X-Ovh-Application'));
$this->assertNotTrue($req->hasHeader('X-Ovh-Consumer'));
$this->assertNotTrue($req->hasHeader('X-Ovh-Timestamp'));
$this->assertNotTrue($req->hasHeader('X-Ovh-Signature'));
if ($method == 'POST' || $method == 'PUT') {
$this->assertEquals('application/json; charset=utf-8', $req->getHeaderLine('Content-Type'));
}
}
}
public function testVersionInUrl()
{
// GET /auth/time
$mocks = [new Response(200, [], MOCK_TIME)];
// GET) x (/1.0/call,/v1/call,/v2/call)
for ($i = 0; $i < 3; $i++) {
$mocks[] = new Response(200, [], '{}');
}
$client = new MockClient(...$mocks);
$api = new Api(MOCK_APPLICATION_KEY, MOCK_APPLICATION_SECRET, 'ovh-eu', MOCK_CONSUMER_KEY, $client);
$api->get('/call');
$api->get('/v1/call');
$api->get('/v2/call');
$calls = $client->calls;
$this->assertEquals(4, count($calls));
$req = $calls[0]['request'];
$this->assertEquals('GET', $req->getMethod());
$this->assertEquals('https://eu.api.ovh.com/1.0/auth/time', $req->getUri()->__toString());
foreach ([
1 => ['path' => '1.0/call', 'sig' => '$1$7f2db49253edfc41891023fcd1a54cf61db05fbb'],
2 => ['path' => 'v1/call', 'sig' => '$1$e6e7906d385eb28adcbfbe6b66c1528a42d741ad'],
3 => ['path' => 'v2/call', 'sig' => '$1$bb63b132a6f84ad5433d0c534d48d3f7c3804285'],
] as $i => $test) {
$req = $calls[$i]['request'];
$this->assertEquals('GET', $req->getMethod());
$this->assertEquals('https://eu.api.ovh.com/' . $test['path'], $req->getUri()->__toString());
$this->assertEquals(MOCK_APPLICATION_KEY, $req->getHeaderLine('X-Ovh-Application'));
$this->assertEquals(MOCK_CONSUMER_KEY, $req->getHeaderLine('X-Ovh-Consumer'));
$this->assertEquals(MOCK_TIME, $req->getHeaderLine('X-Ovh-Timestamp'));
$this->assertEquals($test['sig'], $req->getHeaderLine('X-Ovh-Signature'));
}
} }
} }