Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix encryption when bad response exception #110

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions src/Hyperwallet/Util/ApiClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use GuzzleHttp\Client;
use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\GuzzleException;
use Hyperwallet\Exception\HyperwalletApiException;
use Hyperwallet\Exception\HyperwalletException;
use Hyperwallet\Model\BaseModel;
Expand Down Expand Up @@ -149,6 +150,8 @@ public function doGet($partialUrl, array $uriParams, array $query) {
* @return array
*
* @throws HyperwalletApiException
* @throws HyperwalletException
* @throws GuzzleException
*/
private function doRequest($method, $url, array $urlParams, array $options) {
try {
Expand All @@ -169,10 +172,8 @@ private function doRequest($method, $url, array $urlParams, array $options) {
return array();
}
$this->checkResponseHeaderContentType($response);
$body = $this->isEncrypted ? \GuzzleHttp\json_decode(\GuzzleHttp\json_encode($this->encryption->decrypt($response->getBody())), true) :
\GuzzleHttp\json_decode($response->getBody(), true);

return $body;
return $this->getBodyFromResponse($response);
} catch (ConnectException $e) {
$errorResponse = new ErrorResponse(0, array('errors' => array(
array(
Expand All @@ -182,7 +183,7 @@ private function doRequest($method, $url, array $urlParams, array $options) {
)));
throw new HyperwalletApiException($errorResponse, $e);
} catch (BadResponseException $e) {
$body = \GuzzleHttp\json_decode($e->getResponse()->getBody(), true);
$body = $this->getBodyFromResponse($e->getResponse());
if (is_null($body) || !isset($body['errors']) || empty($body['errors'])) {
$body = array('errors' => array(
array(
Expand All @@ -196,6 +197,17 @@ private function doRequest($method, $url, array $urlParams, array $options) {
}
}

/**
* Get body from response and decrypt it if necessary
*
* @throws HyperwalletException
*/
private function getBodyFromResponse(ResponseInterface $response) {
return $this->isEncrypted
? \GuzzleHttp\json_decode(\GuzzleHttp\json_encode($this->encryption->decrypt($response->getBody())), true)
: \GuzzleHttp\json_decode($response->getBody(), true);
}

/**
* Checks whether Content-Type header is valid in response
*
Expand Down
61 changes: 61 additions & 0 deletions tests/Hyperwallet/Tests/Util/ApiClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,67 @@ public function testDoPost_throw_exception_bad_request() {
$this->validateRequest('POST', '/test', '', array('test2' => 'value2'), true);
}

/**
* @throws HyperwalletException
*/
public function testDoPost_throw_exception_bad_request_with_encryption() {
$clientPath = __DIR__ . "/../../../resources/private-jwkset1";
$hyperwalletPath = __DIR__ . "/../../../resources/public-jwkset1";
$originalMessage = array(
'errors' => array(
array(
'fieldName' => 'testField',
'code' => 'MY_CODE',
'message' => 'My test message',
'relatedResources' => array(
'trm-f3d38df1-adb7-4127-9858-e72ebe682a79', 'trm-601b1401-4464-4f3f-97b3-09079ee7723b')
),
array(
'code' => 'MY_SECOND_CODE',
'message' => 'My second test message'
)
)
);

// Setup data
$encryption = new HyperwalletEncryption($clientPath, $hyperwalletPath);
$encryptedMessage = $encryption->encrypt($originalMessage);

$mockHandler = new MockHandler(array(
new Response(400, array('Content-Type' => 'application/jose+json'), $encryptedMessage)
));
$this->createApiClientWithEncryption($mockHandler);

$model = new BaseModel(array(), array('test2' => 'value2'));

// Execute test
try {
$this->apiClient->doPost('/test', array(), $model, array());
$this->fail('HyperwalletApiException expected');
} catch (HyperwalletApiException $e) {
$this->assertEquals('My test message', $e->getMessage());
$this->assertNotNull($e->getErrorResponse());

$this->assertEquals(400, $e->getErrorResponse()->getStatusCode());
$this->assertCount(2, $e->getErrorResponse()->getErrors());

$this->assertEquals('MY_CODE', $e->getErrorResponse()->getErrors()[0]->getCode());
$this->assertEquals('My test message', $e->getErrorResponse()->getErrors()[0]->getMessage());
$this->assertEquals('testField', $e->getErrorResponse()->getErrors()[0]->getFieldName());

$this->assertEquals('MY_SECOND_CODE', $e->getErrorResponse()->getErrors()[1]->getCode());
$this->assertEquals('My second test message', $e->getErrorResponse()->getErrors()[1]->getMessage());
$this->assertNull($e->getErrorResponse()->getErrors()[1]->getFieldName());

$this->assertCount(2, $e->getRelatedResources());
$this->assertEquals('trm-f3d38df1-adb7-4127-9858-e72ebe682a79', $e->getRelatedResources()[0]);
$this->assertEquals('trm-601b1401-4464-4f3f-97b3-09079ee7723b', $e->getRelatedResources()[1]);
}

// Validate api request
$this->validateRequest('POST', '/test', '', array('test2' => 'value2'), true, array(), true);
}

public function testDoPost_throw_exception_server_error() {
// Setup data
$mockHandler = new MockHandler(array(
Expand Down