From 795f26786bb1d21a0c4fcdb62da39c623dba5f6f Mon Sep 17 00:00:00 2001 From: Dieter Devlieghere Date: Sun, 6 Mar 2016 23:15:49 +0100 Subject: [PATCH 01/12] Started implementing Soap Header v2 session handler --- composer.lock | 20 +- src/Amadeus/Client/Session/Handler/Base.php | 193 +++++++++++++++++- .../Client/Session/Handler/Classmap.php | 9 + .../Client/Session/Handler/SoapHeader2.php | 127 ++++++++++++ .../Client/Session/Handler/SoapHeader4.php | 190 +---------------- .../Handler/UnsupportedOperationException.php | 36 ++++ 6 files changed, 381 insertions(+), 194 deletions(-) create mode 100644 src/Amadeus/Client/Session/Handler/SoapHeader2.php create mode 100644 src/Amadeus/Client/Session/Handler/UnsupportedOperationException.php diff --git a/composer.lock b/composer.lock index 7e8922953..28aaa7b35 100644 --- a/composer.lock +++ b/composer.lock @@ -698,16 +698,16 @@ }, { "name": "sebastian/environment", - "version": "1.3.3", + "version": "1.3.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "6e7133793a8e5a5714a551a8324337374be209df" + "reference": "dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6e7133793a8e5a5714a551a8324337374be209df", - "reference": "6e7133793a8e5a5714a551a8324337374be209df", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf", + "reference": "dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf", "shasum": "" }, "require": { @@ -744,7 +744,7 @@ "environment", "hhvm" ], - "time": "2015-12-02 08:37:27" + "time": "2016-02-26 18:40:46" }, { "name": "sebastian/exporter", @@ -953,16 +953,16 @@ }, { "name": "symfony/yaml", - "version": "v3.0.2", + "version": "v3.0.3", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "3cf0709d7fe936e97bee9e954382e449003f1d9a" + "reference": "b5ba64cd67ecd6887f63868fa781ca094bd1377c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/3cf0709d7fe936e97bee9e954382e449003f1d9a", - "reference": "3cf0709d7fe936e97bee9e954382e449003f1d9a", + "url": "https://api.github.com/repos/symfony/yaml/zipball/b5ba64cd67ecd6887f63868fa781ca094bd1377c", + "reference": "b5ba64cd67ecd6887f63868fa781ca094bd1377c", "shasum": "" }, "require": { @@ -998,7 +998,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2016-02-02 13:44:19" + "time": "2016-02-23 15:16:06" } ], "aliases": [], diff --git a/src/Amadeus/Client/Session/Handler/Base.php b/src/Amadeus/Client/Session/Handler/Base.php index f05a6f628..4f5a41eee 100644 --- a/src/Amadeus/Client/Session/Handler/Base.php +++ b/src/Amadeus/Client/Session/Handler/Base.php @@ -22,8 +22,10 @@ namespace Amadeus\Client\Session\Handler; +use Amadeus\Client\Params\SessionHandlerParams; use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerAwareTrait; +use Psr\Log\LogLevel; use Psr\Log\NullLogger; /** @@ -41,12 +43,200 @@ abstract class Base implements HandlerInterface, LoggerAwareInterface use LoggerAwareTrait; + /** + * XPATH query to retrieve all operations from the WSDL + * + * @var string + */ + const XPATH_ALL_OPERATIONS = '/wsdl:definitions/wsdl:portType/wsdl:operation/@name'; + /** + * XPATH query to retrieve the full operation name + version from the WSDL for a given operation. + * + * @var string + */ + const XPATH_VERSION_FOR_OPERATION = "string(/wsdl:definitions/wsdl:message[contains(./@name, '%s_')]/@name)"; + + /** + * Status variable to know if the session is currently logged in + * + * @var bool + */ + protected $isAuthenticated = false; + /** * @var \SoapClient */ protected $soapClient; + /** + * SoapClient options used during initialisation + * + * @var array + */ + protected $soapClientOptions = [ + 'trace' => 1, + 'exceptions' => 1, + 'soap_version' => SOAP_1_1 + ]; + + + /** + * @var SessionHandlerParams + */ + protected $params; + + + /** + * Dom Document where the WSDL's contents will be loaded + * + * @var \DOMDocument + */ + protected $wsdlDomDoc; + /** + * To query the WSDL contents + * + * @var \DOMXpath + */ + protected $wsdlDomXpath; + + + /** + * Get the last raw XML message that was sent out + * + * @return string|null + */ + public function getLastRequest() + { + return $this->getSoapClient()->__getLastRequest(); + } + + /** + * Get the last raw XML message that was received + * + * @return string|null + */ + public function getLastResponse() + { + return $this->getSoapClient()->__getLastResponse(); + } + + /** + * Get the office that we are using to sign in to. + * + * @return string + */ + public function getOriginatorOffice() + { + return $this->params->authParams->officeId; + } + + + /** + * Extract the Messages and versions from the loaded WSDL file. + * + * Result is an associative array: keys are message names, values are versions. + * + * @return array + */ + public function getMessagesAndVersions() + { + $this->loadWsdlXpath($this->params->wsdl); + + $msgAndVer = []; + $operations = $this->wsdlDomXpath->query(self::XPATH_ALL_OPERATIONS); + + foreach ($operations as $operation) { + if (!empty($operation->value)) { + $fullVersion = $this->wsdlDomXpath->evaluate(sprintf(self::XPATH_VERSION_FOR_OPERATION, $operation->value)); + if (!empty($fullVersion)) { + $extractedVersion = $this->extractMessageVersion($fullVersion); + $msgAndVer[$operation->value] = $extractedVersion; + } + } + } + + return $msgAndVer; + } + + /** + * extractMessageVersion + * + * extracts "4.1" from a string like "Security_SignOut_4_1" + * + * @param string $fullVersionString + * @return string + */ + protected function extractMessageVersion($fullVersionString) + { + $secondUnderscore = strpos($fullVersionString, '_', strpos($fullVersionString, '_')+1); + $num = substr($fullVersionString, $secondUnderscore+1); + + return str_replace('_', '.', $num); + } + + /** + * Load the WSDL contents to a queryable DOMXpath. + * + * @param string $wsdlFilePath + * @uses $this->wsdlDomDoc + * @uses $this->wsdlDomXpath + */ + protected function loadWsdlXpath($wsdlFilePath) + { + if (is_null($this->wsdlDomXpath)) { + $wsdlContent = file_get_contents($wsdlFilePath); + + $this->wsdlDomDoc = new \DOMDocument('1.0', 'UTF-8'); + $this->wsdlDomDoc->loadXML($wsdlContent); + $this->wsdlDomXpath = new \DOMXPath($this->wsdlDomDoc); + $this->wsdlDomXpath->registerNamespace( + 'wsdl', + 'http://schemas.xmlsoap.org/wsdl/' + ); + $this->wsdlDomXpath->registerNamespace( + 'soap', + 'http://schemas.xmlsoap.org/wsdl/soap/' + ); + } + } + + + /** + * @return \SoapClient + */ + protected function getSoapClient() + { + if (!$this->soapClient instanceof \SoapClient) { + $this->soapClient = $this->initSoapClient(); + } + + return $this->soapClient; + } + + /** + * @return \SoapClient + */ + protected abstract function initSoapClient(); + + + /** + * @param string $messageName + * @uses $this->log + */ + protected function logRequestAndResponse($messageName) + { + $this->log( + LogLevel::INFO, + 'Called ' . $messageName . ' with request: ' . $this->getSoapClient()->__getLastRequest() + ); + $this->log( + LogLevel::INFO, + 'Response: ' . $this->getSoapClient()->__getLastResponse() + ); + } + + /** * @param mixed $level * @param string $message @@ -61,5 +251,4 @@ protected function log($level, $message, $context = []) return $this->logger->log($level, $message, $context); } - -} \ No newline at end of file +} diff --git a/src/Amadeus/Client/Session/Handler/Classmap.php b/src/Amadeus/Client/Session/Handler/Classmap.php index fcd0a37cf..8eab5bcd0 100644 --- a/src/Amadeus/Client/Session/Handler/Classmap.php +++ b/src/Amadeus/Client/Session/Handler/Classmap.php @@ -43,6 +43,15 @@ class Classmap 'Session' => 'Amadeus\Client\Struct\HeaderV4\Session', ]; + /** + * The PHP -> WSDL translation classmap for Soap Header 2 specific message parts + * + * @var array + */ + public static $soapheader2map = [ + + ]; + /** * The PHP -> WSDL translation classmap for the Amadeus WS Client * diff --git a/src/Amadeus/Client/Session/Handler/SoapHeader2.php b/src/Amadeus/Client/Session/Handler/SoapHeader2.php new file mode 100644 index 000000000..23058d56c --- /dev/null +++ b/src/Amadeus/Client/Session/Handler/SoapHeader2.php @@ -0,0 +1,127 @@ + + */ +class SoapHeader2 extends Base +{ + /** + * Session information: + * - session ID + * - sequence number + * - security Token + * + * @var array + */ + protected $sessionData = [ + 'sessionId' => null, + 'sequenceNumber' => null, + 'securityToken' => null + ]; + + /** + * @param SessionHandlerParams $params + */ + public function __construct(SessionHandlerParams $params) + { + parent::__construct($params); + } + + /** + * Method to send a message to the web services server + * + * @param string $messageName The Method name to be called (from the WSDL) + * @param BaseWsMessage $messageBody The message's body to be sent to the server + * @param array $messageOptions Optional options on how to handle this particular message. + * @return string|\stdClass + */ + public function sendMessage($messageName, BaseWsMessage $messageBody, $messageOptions) + { + // TODO: Implement sendMessage() method. + } + + /** + * Cannot set stateless on Soap Header v2 + * + * @param bool $stateful + * @throws UnsupportedOperationException + */ + public function setStateful($stateful) + { + throw new UnsupportedOperationException('Stateful messages are mandatory on SoapHeader 2'); + } + + /** + * Get the session parameters of the active session + * + * @return array|null + */ + public function getSessionData() + { + return $this->sessionData; + } + + /** + * Soap Header 2 sessions are always stateful + * + * @return bool + */ + public function isStateful() + { + return true; + } + + /** + * @return \SoapClient + */ + protected function initSoapClient() + { + $client = new Client\SoapClient( + $this->params->wsdl, + $this->makeSoapClientOptions(), + $this->params->logger + ); + + return $client; + } + + /** + * @return array + */ + protected function makeSoapClientOptions() + { + $options = $this->soapClientOptions; + $options['classmap'] = array_merge(Classmap::$soapheader2map, Classmap::$map); + + return $options; + } +} diff --git a/src/Amadeus/Client/Session/Handler/SoapHeader4.php b/src/Amadeus/Client/Session/Handler/SoapHeader4.php index 47e7b99e4..4162b97ce 100644 --- a/src/Amadeus/Client/Session/Handler/SoapHeader4.php +++ b/src/Amadeus/Client/Session/Handler/SoapHeader4.php @@ -48,25 +48,7 @@ class SoapHeader4 extends Base * @var string */ const XPATH_ENDPOINT = 'string(/wsdl:definitions/wsdl:service/wsdl:port/soap:address/@location)'; - /** - * XPATH query to retrieve all operations from the WSDL - * - * @var string - */ - const XPATH_ALL_OPERATIONS = '/wsdl:definitions/wsdl:portType/wsdl:operation/@name'; - /** - * XPATH query to retrieve the full operation name + version from the WSDL for a given operation. - * - * @var string - */ - const XPATH_VERSION_FOR_OPERATION = "string(/wsdl:definitions/wsdl:message[contains(./@name, '%s_')]/@name)"; - /** - * Status variable to know if the session is currently logged in - * - * @var bool - */ - protected $isAuthenticated = false; /** * Status variable to know wether the given session is in a certain context. * @@ -99,34 +81,7 @@ class SoapHeader4 extends Base 'sequenceNumber' => null, 'securityToken' => null ]; - /** - * SoapClient options used during initialisation - * - * @var array - */ - protected $soapClientOptions = [ - 'trace' => 1, - 'exceptions' => 1, - 'soap_version' => SOAP_1_1 - ]; - - /** - * Dom Document where the WSDL's contents will be loaded - * - * @var \DOMDocument - */ - protected $wsdlDomDoc; - /** - * To query the WSDL contents - * - * @var \DOMXpath - */ - protected $wsdlDomXpath; - /** - * @var Client\Params\SessionHandlerParams - */ - protected $params; /** * @param Client\Params\SessionHandlerParams $params @@ -144,43 +99,6 @@ public function __construct(Client\Params\SessionHandlerParams $params) $this->setStateful($params->stateful); } - /** - * Get the office that we are using to sign in to. - * - * @return string - */ - public function getOriginatorOffice() - { - return $this->params->authParams->officeId; - } - - /** - * Extract the Messages and versions from the loaded WSDL file. - * - * Result is an associative array: keys are message names, values are versions. - * - * @return array - */ - public function getMessagesAndVersions() - { - $this->loadWsdlXpath($this->params->wsdl); - - $msgAndVer = []; - $operations = $this->wsdlDomXpath->query(self::XPATH_ALL_OPERATIONS); - - foreach ($operations as $operation) { - if (!empty($operation->value)) { - $fullVersion = $this->wsdlDomXpath->evaluate(sprintf(self::XPATH_VERSION_FOR_OPERATION, $operation->value)); - if (!empty($fullVersion)) { - $extractedVersion = $this->extractMessageVersion($fullVersion); - $msgAndVer[$operation->value] = $extractedVersion; - } - } - } - - return $msgAndVer; - } - /** * @param bool $stateful */ @@ -209,26 +127,6 @@ public function getSessionData() return $this->sessionData; } - /** - * Get the last raw XML message that was sent out - * - * @return string|null - */ - public function getLastRequest() - { - return $this->getSoapClient()->__getLastRequest(); - } - - /** - * Get the last raw XML message that was received - * - * @return string|null - */ - public function getLastResponse() - { - return $this->getSoapClient()->__getLastResponse(); - } - /** * @param string $messageName Method Operation name as defined in the WSDL. @@ -511,58 +409,32 @@ protected function createSoapHeaders($sessionData, $params, $messageName, $messa } /** - * Get the SOAPAction for a given message from the WSDL contents. + * Get the Web Services server Endpoint from the WSDL. * * @param string $wsdlFilePath - * @param string $messageName * @return string */ - protected function getActionFromWsdl($wsdlFilePath, $messageName) + protected function getEndpointFromWsdl($wsdlFilePath) { $this->loadWsdlXpath($wsdlFilePath); - $action = $this->wsdlDomXpath->evaluate(sprintf(self::XPATH_OPERATION_ACTION, $messageName)); - - return $action; + return $this->wsdlDomXpath->evaluate(self::XPATH_ENDPOINT); } /** - * Get the Web Services server Endpoint from the WSDL. + * Get the SOAPAction for a given message from the WSDL contents. * * @param string $wsdlFilePath + * @param string $messageName * @return string */ - protected function getEndpointFromWsdl($wsdlFilePath) + protected function getActionFromWsdl($wsdlFilePath, $messageName) { $this->loadWsdlXpath($wsdlFilePath); - return $this->wsdlDomXpath->evaluate(self::XPATH_ENDPOINT); - } + $action = $this->wsdlDomXpath->evaluate(sprintf(self::XPATH_OPERATION_ACTION, $messageName)); - /** - * Load the WSDL contents to a queryable DOMXpath. - * - * @param string $wsdlFilePath - * @uses $this->wsdlDomDoc - * @uses $this->wsdlDomXpath - */ - protected function loadWsdlXpath($wsdlFilePath) - { - if (is_null($this->wsdlDomXpath)) { - $wsdlContent = file_get_contents($wsdlFilePath); - - $this->wsdlDomDoc = new \DOMDocument('1.0', 'UTF-8'); - $this->wsdlDomDoc->loadXML($wsdlContent); - $this->wsdlDomXpath = new \DOMXPath($this->wsdlDomDoc); - $this->wsdlDomXpath->registerNamespace( - 'wsdl', - 'http://schemas.xmlsoap.org/wsdl/' - ); - $this->wsdlDomXpath->registerNamespace( - 'soap', - 'http://schemas.xmlsoap.org/wsdl/soap/' - ); - } + return $action; } /** @@ -660,35 +532,6 @@ protected function createDateTimeStringForAuth($creationDateTime, $micro) return $creationDateTime->format("Y-m-d\TH:i:s:") . $micro . 'Z'; } - /** - * extractMessageVersion - * - * extracts "4.1" from a string like "Security_SignOut_4_1" - * - * @param string $fullVersionString - * @return string - */ - protected function extractMessageVersion($fullVersionString) - { - $secondUnderscore = strpos($fullVersionString, '_', strpos($fullVersionString, '_')+1); - $num = substr($fullVersionString, $secondUnderscore+1); - - return str_replace('_', '.', $num); - } - - /** - * @return \SoapClient - */ - protected function getSoapClient() - { - if (!$this->soapClient instanceof \SoapClient) { - $this->soapClient = $this->initSoapClient(); - } - - return $this->soapClient; - } - - /** * @return \SoapClient */ @@ -713,21 +556,4 @@ protected function makeSoapClientOptions() return $options; } - - - /** - * @param string $messageName - * @uses $this->log - */ - protected function logRequestAndResponse($messageName) - { - $this->log( - LogLevel::INFO, - 'Called ' . $messageName . ' with request: ' . $this->getSoapClient()->__getLastRequest() - ); - $this->log( - LogLevel::INFO, - 'Response: ' . $this->getSoapClient()->__getLastResponse() - ); - } } diff --git a/src/Amadeus/Client/Session/Handler/UnsupportedOperationException.php b/src/Amadeus/Client/Session/Handler/UnsupportedOperationException.php new file mode 100644 index 000000000..d5b18e552 --- /dev/null +++ b/src/Amadeus/Client/Session/Handler/UnsupportedOperationException.php @@ -0,0 +1,36 @@ + + */ +class UnsupportedOperationException extends Exception +{ + +} From 28154d0b38b8aef2081d8d00914cf4408e6c7fe6 Mon Sep 17 00:00:00 2001 From: Dieter Devlieghere Date: Sun, 6 Mar 2016 23:56:22 +0100 Subject: [PATCH 02/12] moved session handler constructor to base --- src/Amadeus/Client/Session/Handler/Base.php | 18 ++++++++++++++ .../Client/Session/Handler/SoapHeader4.php | 24 +++---------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/Amadeus/Client/Session/Handler/Base.php b/src/Amadeus/Client/Session/Handler/Base.php index 4f5a41eee..a1b3653f7 100644 --- a/src/Amadeus/Client/Session/Handler/Base.php +++ b/src/Amadeus/Client/Session/Handler/Base.php @@ -25,6 +25,7 @@ use Amadeus\Client\Params\SessionHandlerParams; use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerAwareTrait; +use Psr\Log\LoggerInterface; use Psr\Log\LogLevel; use Psr\Log\NullLogger; @@ -101,6 +102,23 @@ abstract class Base implements HandlerInterface, LoggerAwareInterface protected $wsdlDomXpath; + /** + * @param SessionHandlerParams $params + */ + public function __construct(SessionHandlerParams $params) + { + $this->params = $params; + if($params->logger instanceof LoggerInterface) { + $this->setLogger($params->logger); + $this->log(LogLevel::INFO, __METHOD__. "(): Logger started."); + } + if ($params->overrideSoapClient instanceof \SoapClient) { + $this->soapClient = $params->overrideSoapClient; + } + $this->setStateful($params->stateful); + } + + /** * Get the last raw XML message that was sent out * diff --git a/src/Amadeus/Client/Session/Handler/SoapHeader4.php b/src/Amadeus/Client/Session/Handler/SoapHeader4.php index 4162b97ce..b8b4a4fe4 100644 --- a/src/Amadeus/Client/Session/Handler/SoapHeader4.php +++ b/src/Amadeus/Client/Session/Handler/SoapHeader4.php @@ -24,10 +24,8 @@ use Amadeus\Client\Struct\BaseWsMessage; use Amadeus\Client; -use Psr\Log\LoggerInterface; use Psr\Log\LogLevel; - /** * SoapHeader4: Session Handler for web service applications using Amadeus WS Soap Header v4. * @@ -55,12 +53,14 @@ class SoapHeader4 extends Base * @var bool */ protected $hasContext = false; + /** * Switch between stateful & stateless sessions. Default: stateful * * @var bool */ protected $isStateful = true; + /** * The context of the currently active session * @@ -68,6 +68,7 @@ class SoapHeader4 extends Base * @var mixed */ protected $context; + /** * Session information: * - session ID @@ -83,22 +84,6 @@ class SoapHeader4 extends Base ]; - /** - * @param Client\Params\SessionHandlerParams $params - */ - public function __construct(Client\Params\SessionHandlerParams $params) - { - $this->params = $params; - if($params->logger instanceof LoggerInterface) { - $this->setLogger($params->logger); - $this->log(LogLevel::INFO, __METHOD__. "(): Logger started."); - } - if ($params->overrideSoapClient instanceof \SoapClient) { - $this->soapClient = $params->overrideSoapClient; - } - $this->setStateful($params->stateful); - } - /** * @param bool $stateful */ @@ -127,7 +112,6 @@ public function getSessionData() return $this->sessionData; } - /** * @param string $messageName Method Operation name as defined in the WSDL. * @param BaseWsMessage $messageBody @@ -234,8 +218,6 @@ protected function handlePostMessage($messageName, $lastResponse, $messageOption } else { $this->isAuthenticated = false; } - - //TODO: check for errors in response? } /** From cca9c47218ec7e5c9f8d5ec919242b41a023d894 Mon Sep 17 00:00:00 2001 From: Dieter Devlieghere Date: Tue, 8 Mar 2016 08:18:06 +0100 Subject: [PATCH 03/12] SoapHeader V2 further impl --- src/Amadeus/Client/Session/Handler/Base.php | 73 +++++++++++++++++++ .../Client/Session/Handler/SoapHeader2.php | 27 +++++++ .../Client/Session/Handler/SoapHeader4.php | 51 ------------- 3 files changed, 100 insertions(+), 51 deletions(-) diff --git a/src/Amadeus/Client/Session/Handler/Base.php b/src/Amadeus/Client/Session/Handler/Base.php index a1b3653f7..4498685be 100644 --- a/src/Amadeus/Client/Session/Handler/Base.php +++ b/src/Amadeus/Client/Session/Handler/Base.php @@ -22,6 +22,8 @@ namespace Amadeus\Client\Session\Handler; +use Amadeus\Client; +use Amadeus\Client\Struct\BaseWsMessage; use Amadeus\Client\Params\SessionHandlerParams; use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerAwareTrait; @@ -119,6 +121,77 @@ public function __construct(SessionHandlerParams $params) } + /** + * @param string $messageName Method Operation name as defined in the WSDL. + * @param BaseWsMessage $messageBody + * @param array $messageOptions options: bool 'asString', bool 'endSession' + * @return mixed + * @throws \InvalidArgumentException + * @throws Client\Exception + * @throws \SoapFault + */ + public function sendMessage($messageName, Client\Struct\BaseWsMessage $messageBody, $messageOptions = []) + { + $result = null; + + $this->prepareForNextMessage($messageName, $messageOptions); + + try { + $result = $this->getSoapClient()->$messageName($messageBody); + + $this->logRequestAndResponse($messageName); + + $this->handlePostMessage($messageName, $this->getLastResponse(), $messageOptions, $result); + + } catch(\SoapFault $ex) { + $this->log( + LogLevel::ERROR, + "SOAPFAULT while sending message " . $messageName . ": " . + $ex->getMessage() . " code: " .$ex->getCode() . " at " . $ex->getFile() . + " line " . $ex->getLine() . ": \n" . $ex->getTraceAsString() + ); + $this->logRequestAndResponse($messageName); + //TODO We must be able to handle certain soapfaults inside the client, so maybe pass through after logging? + throw $ex; + } catch (\Exception $ex) { + $this->log( + LogLevel::ERROR, + "EXCEPTION while sending message " . $messageName . ": " . + $ex->getMessage() . " at " . $ex->getFile() . " line " . $ex->getLine() . ": \n" . + $ex->getTraceAsString() + ); + $this->logRequestAndResponse($messageName); + //TODO We must be able to handle certain exceptions inside the client, so maybe pass through after logging? + throw new Client\Exception($ex->getMessage(), $ex->getCode(), $ex); + } + + if ($messageOptions['asString'] === true) { + $result = Client\Util\MsgBodyExtractor::extract($this->getLastResponse()); + } + + return $result; + } + + /** + * Prepare to send a next message and checks if authenticated + * + * @param string $messageName + * @param array $messageOptions + */ + protected abstract function prepareForNextMessage($messageName, $messageOptions); + + /** + * Handles post message actions + * + * Handles session state based on received response + * + * @param string $messageName + * @param string $lastResponse + * @param array $messageOptions + * @param mixed $result + */ + protected abstract function handlePostMessage($messageName, $lastResponse, $messageOptions, $result); + /** * Get the last raw XML message that was sent out * diff --git a/src/Amadeus/Client/Session/Handler/SoapHeader2.php b/src/Amadeus/Client/Session/Handler/SoapHeader2.php index 23058d56c..71a275540 100644 --- a/src/Amadeus/Client/Session/Handler/SoapHeader2.php +++ b/src/Amadeus/Client/Session/Handler/SoapHeader2.php @@ -69,6 +69,33 @@ public function sendMessage($messageName, BaseWsMessage $messageBody, $messageOp // TODO: Implement sendMessage() method. } + /** + * Prepare to send a next message and checks if authenticated + * + * @param string $messageName + * @param array $messageOptions + */ + protected function prepareForNextMessage($messageName, $messageOptions) + { + // TODO: Implement prepareForNextMessage() method. + } + + /** + * Handles post message actions + * + * Handles session state based on received response + * + * @param string $messageName + * @param string $lastResponse + * @param array $messageOptions + * @param mixed $result + */ + protected function handlePostMessage($messageName, $lastResponse, $messageOptions, $result) + { + // TODO: Implement handlePostMessage() method. + } + + /** * Cannot set stateless on Soap Header v2 * diff --git a/src/Amadeus/Client/Session/Handler/SoapHeader4.php b/src/Amadeus/Client/Session/Handler/SoapHeader4.php index b8b4a4fe4..2c43aa11f 100644 --- a/src/Amadeus/Client/Session/Handler/SoapHeader4.php +++ b/src/Amadeus/Client/Session/Handler/SoapHeader4.php @@ -22,7 +22,6 @@ namespace Amadeus\Client\Session\Handler; -use Amadeus\Client\Struct\BaseWsMessage; use Amadeus\Client; use Psr\Log\LogLevel; @@ -112,56 +111,6 @@ public function getSessionData() return $this->sessionData; } - /** - * @param string $messageName Method Operation name as defined in the WSDL. - * @param BaseWsMessage $messageBody - * @param array $messageOptions options: bool 'asString', bool 'endSession' - * @return mixed - * @throws \InvalidArgumentException - * @throws Client\Exception - * @throws \SoapFault - */ - public function sendMessage($messageName, BaseWsMessage $messageBody, $messageOptions = []) - { - $result = null; - - $this->prepareForNextMessage($messageName, $messageOptions); - - try { - $result = $this->getSoapClient()->$messageName($messageBody); - - $this->logRequestAndResponse($messageName); - - $this->handlePostMessage($messageName, $this->getLastResponse(), $messageOptions, $result); - - } catch(\SoapFault $ex) { - $this->log( - LogLevel::ERROR, - "SOAPFAULT while sending message " . $messageName . ": " . - $ex->getMessage() . " code: " .$ex->getCode() . " at " . $ex->getFile() . - " line " . $ex->getLine() . ": \n" . $ex->getTraceAsString() - ); - $this->logRequestAndResponse($messageName); - //TODO We must be able to handle certain soapfaults inside the client, so maybe pass through after logging? - throw $ex; - } catch (\Exception $ex) { - $this->log( - LogLevel::ERROR, - "EXCEPTION while sending message " . $messageName . ": " . - $ex->getMessage() . " at " . $ex->getFile() . " line " . $ex->getLine() . ": \n" . - $ex->getTraceAsString() - ); - $this->logRequestAndResponse($messageName); - //TODO We must be able to handle certain exceptions inside the client, so maybe pass through after logging? - throw new Client\Exception($ex->getMessage(), $ex->getCode(), $ex); - } - - if ($messageOptions['asString'] === true) { - $result = Client\Util\MsgBodyExtractor::extract($this->getLastResponse()); - } - - return $result; - } /** * Handles authentication & sessions From 63f3443fce5be464ed155230cb3794d07139859d Mon Sep 17 00:00:00 2001 From: Dieter Devlieghere Date: Wed, 30 Mar 2016 22:41:19 +0200 Subject: [PATCH 04/12] Implemented SoapHeader V2 session handler, Unit tests ongoing --- src/Amadeus/Client.php | 37 +++++ src/Amadeus/Client/Params.php | 17 ++- src/Amadeus/Client/RequestCreator/Base.php | 12 ++ .../SecurityAuthenticateOptions.php | 114 +++++++++++++++ src/Amadeus/Client/Session/Handler/Base.php | 62 ++++++++ .../Client/Session/Handler/Classmap.php | 2 +- .../Client/Session/Handler/HandlerFactory.php | 4 +- .../Session/Handler/HandlerInterface.php | 8 ++ .../Handler/InvalidSessionException.php | 38 +++++ .../Client/Session/Handler/SoapHeader2.php | 113 +++++++++------ .../Client/Session/Handler/SoapHeader4.php | 42 +----- .../Client/Struct/HeaderV2/Session.php | 57 ++++++++ src/Amadeus/Client/Util/MsgBodyExtractor.php | 13 ++ .../Session/Handler/HandlerFactoryTest.php | 50 ++++++- .../Session/Handler/SoapHeader2Test.php | 132 ++++++++++++++++++ ...mmyPnrReplyExtractedMessageSoapHeader2.txt | 1 + .../testfiles/dummyPnrReplysoapheader2.txt | 1 + .../testfiles/dummyPnrRequestsoapheader2.txt | 2 + tests/Amadeus/ClientTest.php | 51 +++++++ 19 files changed, 670 insertions(+), 86 deletions(-) create mode 100644 src/Amadeus/Client/RequestOptions/SecurityAuthenticateOptions.php create mode 100644 src/Amadeus/Client/Session/Handler/InvalidSessionException.php create mode 100644 src/Amadeus/Client/Struct/HeaderV2/Session.php create mode 100644 tests/Amadeus/Client/Session/Handler/SoapHeader2Test.php create mode 100644 tests/Amadeus/Client/Session/Handler/testfiles/dummyPnrReplyExtractedMessageSoapHeader2.txt create mode 100644 tests/Amadeus/Client/Session/Handler/testfiles/dummyPnrReplysoapheader2.txt create mode 100644 tests/Amadeus/Client/Session/Handler/testfiles/dummyPnrRequestsoapheader2.txt diff --git a/src/Amadeus/Client.php b/src/Amadeus/Client.php index b51977ce8..49b4b5d26 100644 --- a/src/Amadeus/Client.php +++ b/src/Amadeus/Client.php @@ -97,6 +97,13 @@ class Client */ protected $responseHandler; + /** + * Authentication parameters + * + * @var Params\AuthParams + */ + protected $authParams; + /** * Set the session as stateful (true) or stateless (false) * @@ -142,6 +149,11 @@ public function getLastResponse() */ public function __construct($params) { + if ($params->authParams instanceof Params\AuthParams) { + $this->authParams = $params->authParams; + $params->sessionHandlerParams->authParams = $this->authParams; + } + $this->sessionHandler = $this->loadSessionHandler( $params->sessionHandler, $params->sessionHandlerParams @@ -160,6 +172,31 @@ public function __construct($params) ); } + /** + * Authenticate. + * + * Parameters were provided at construction time (sessionhandlerparams) + * + * @return \stdClass + * @throws Exception + */ + public function securityAuthenticate() + { + $msgName = 'Security_Authenticate'; + $messageOptions = $this->makeMessageOptions([], false, false); + + return $this->sessionHandler->sendMessage( + $msgName, + $this->requestCreator->createRequest( + $msgName, + new RequestOptions\SecurityAuthenticateOptions( + $this->authParams + ) + ), + $messageOptions + ); + } + /** * Terminate a session - only applicable to non-stateless mode. * diff --git a/src/Amadeus/Client/Params.php b/src/Amadeus/Client/Params.php index 55a045fb8..0a5da35a6 100644 --- a/src/Amadeus/Client/Params.php +++ b/src/Amadeus/Client/Params.php @@ -22,6 +22,7 @@ namespace Amadeus\Client; +use Amadeus\Client\Params\AuthParams; use Amadeus\Client\Params\RequestCreatorParams; use Amadeus\Client\Params\SessionHandlerParams; use Amadeus\Client\RequestCreator\RequestCreatorInterface; @@ -57,6 +58,13 @@ class Params */ public $responseHandler; + /** + * Parameters for authenticating to the Amadeus Web Services + * + * @var Params\AuthParams + */ + public $authParams; + /** * Parameters required to create the Session Handler * @@ -72,7 +80,6 @@ class Params public $requestCreatorParams; - /** * @param array $params */ @@ -98,6 +105,14 @@ protected function loadFromArray(array $params) { $this->responseHandler = $params['responseHandler']; } + if (isset($params['authParams'])) { + if ($params['authParams'] instanceof AuthParams) { + $this->authParams = $params['authParams']; + } elseif (is_array($params['authParams'])) { + $this->authParams = new AuthParams($params['authParams']); + } + } + if (isset($params['sessionHandlerParams'])) { if ($params['sessionHandlerParams'] instanceof SessionHandlerParams) { $this->sessionHandlerParams = $params['sessionHandlerParams']; diff --git a/src/Amadeus/Client/RequestCreator/Base.php b/src/Amadeus/Client/RequestCreator/Base.php index a042a560a..f7a8cb714 100644 --- a/src/Amadeus/Client/RequestCreator/Base.php +++ b/src/Amadeus/Client/RequestCreator/Base.php @@ -50,6 +50,7 @@ use Amadeus\Client\RequestOptions\QueuePlacePnrOptions; use Amadeus\Client\RequestOptions\QueueRemoveItemOptions; use Amadeus\Client\RequestOptions\RequestOptionsInterface; +use Amadeus\Client\RequestOptions\SecurityAuthenticateOptions; use Amadeus\Client\RequestOptions\TicketCreateTstFromPricingOptions; use Amadeus\Client\Struct; @@ -110,6 +111,17 @@ protected function createSecuritySignOut() return new Struct\Security\SignOut(); } + /** + * Create request object for Security_Authenticate message + * + * @param SecurityAuthenticateOptions $params + * @return Struct\Security\Authenticate + */ + protected function createSecurityAuthenticate(SecurityAuthenticateOptions $params) + { + return new Struct\Security\Authenticate($params); + } + /** * Create request object for PNR_Retrieve message * diff --git a/src/Amadeus/Client/RequestOptions/SecurityAuthenticateOptions.php b/src/Amadeus/Client/RequestOptions/SecurityAuthenticateOptions.php new file mode 100644 index 000000000..17269a262 --- /dev/null +++ b/src/Amadeus/Client/RequestOptions/SecurityAuthenticateOptions.php @@ -0,0 +1,114 @@ + + */ +class SecurityAuthenticateOptions extends Base +{ + /** + * The Amadeus Office ID to sign in to + * + * @var string + */ + public $officeId; + + /** + * User ID / Originator + * + * @var string + */ + public $userId; + + /** + * Originator Typecode + * + * @var string + */ + public $originatorTypeCode; + + /** + * Duty code + * + * @var string + */ + public $dutyCode; + + /** + * Organization ID + * + * @var string + */ + public $organizationId; + + /** + * Password Length of plain password. + * + * Only for SoapHeader < 4. + * + * @var int + */ + public $passwordLength; + + /** + * Password Data (base-64 encoded password) + * + * @var string + */ + public $passwordData; + + /** + * SecurityAuthenticateOptions constructor. + * + * @param AuthParams|null $authParams + */ + public function __construct(AuthParams $authParams = null) + { + if ($authParams instanceof AuthParams) { + $this->loadFromAuthParams($authParams); + } + + parent::__construct([]); + } + + /** + * Load security authenticate options from auth params + * + * @param AuthParams $authParams + */ + protected function loadFromAuthParams(AuthParams $authParams) + { + $this->officeId = $authParams->officeId; + $this->dutyCode = $authParams->dutyCode; + $this->organizationId = $authParams->organizationId; + $this->originatorTypeCode = $authParams->originatorTypeCode; + $this->userId = $authParams->userId; + $this->passwordLength = $authParams->passwordLength; + $this->passwordData = $authParams->passwordData; + } +} diff --git a/src/Amadeus/Client/Session/Handler/Base.php b/src/Amadeus/Client/Session/Handler/Base.php index 4498685be..cb9ce165e 100644 --- a/src/Amadeus/Client/Session/Handler/Base.php +++ b/src/Amadeus/Client/Session/Handler/Base.php @@ -59,6 +59,38 @@ abstract class Base implements HandlerInterface, LoggerAwareInterface */ const XPATH_VERSION_FOR_OPERATION = "string(/wsdl:definitions/wsdl:message[contains(./@name, '%s_')]/@name)"; + + /** + * Status variable to know wether the given session is in a certain context. + * + * @todo implement this feature - currently the application using the client must know the context itself. + * @var bool + */ + protected $hasContext = false; + + /** + * The context of the currently active session + * + * @todo implement this feature - currently the application using the client must know the context itself. + * @var mixed + */ + protected $context; + + + /** + * Session information: + * - session ID + * - sequence number + * - security Token + * + * @var array + */ + protected $sessionData = [ + 'sessionId' => null, + 'sequenceNumber' => null, + 'securityToken' => null + ]; + /** * Status variable to know if the session is currently logged in * @@ -103,6 +135,36 @@ abstract class Base implements HandlerInterface, LoggerAwareInterface */ protected $wsdlDomXpath; + /** + * Get the session parameters of the active session + * + * @return array|null + */ + public function getSessionData() + { + return $this->sessionData; + } + + /** + * Set the session data to continue a previously started session. + * + * @param array $sessionData + * @return bool + */ + public function setSessionData(array $sessionData) + { + if (isset($sessionData['sessionId'], $sessionData['sequenceNumber'], $sessionData['securityToken'])) { + $this->sessionData['sessionId'] = $sessionData['sessionId']; + $this->sessionData['sequenceNumber'] = $sessionData['sequenceNumber']; + $this->sessionData['securityToken'] = $sessionData['securityToken']; + $this->isAuthenticated = true; + } else { + $this->isAuthenticated = false; + } + + return $this->isAuthenticated; + } + /** * @param SessionHandlerParams $params diff --git a/src/Amadeus/Client/Session/Handler/Classmap.php b/src/Amadeus/Client/Session/Handler/Classmap.php index 8eab5bcd0..32bc32ce0 100644 --- a/src/Amadeus/Client/Session/Handler/Classmap.php +++ b/src/Amadeus/Client/Session/Handler/Classmap.php @@ -49,7 +49,7 @@ class Classmap * @var array */ public static $soapheader2map = [ - + 'Session' => 'Amadeus\Client\Struct\HeaderV2\Session', ]; /** diff --git a/src/Amadeus/Client/Session/Handler/HandlerFactory.php b/src/Amadeus/Client/Session/Handler/HandlerFactory.php index 8c4cf29de..91954ddfd 100644 --- a/src/Amadeus/Client/Session/Handler/HandlerFactory.php +++ b/src/Amadeus/Client/Session/Handler/HandlerFactory.php @@ -55,9 +55,11 @@ public static function createHandler($handlerParams) $theHandler = new SoapHeader4($handlerParams); break; case Client::HEADER_V2: + $theHandler = new SoapHeader2($handlerParams); + break; case Client::HEADER_V1: default: - //TODO implement Client::HEADER_V2 & Client::HEADER_V1 + //TODO implement Client::HEADER_V1 throw new \InvalidArgumentException( 'No Session Handler found for soapHeaderVersion ' . $handlerParams->soapHeaderVersion ); diff --git a/src/Amadeus/Client/Session/Handler/HandlerInterface.php b/src/Amadeus/Client/Session/Handler/HandlerInterface.php index 1104c3115..113aecfde 100644 --- a/src/Amadeus/Client/Session/Handler/HandlerInterface.php +++ b/src/Amadeus/Client/Session/Handler/HandlerInterface.php @@ -80,6 +80,14 @@ public function setStateful($stateful); */ public function getSessionData(); + /** + * Set the session data to continue a previously started session. + * + * @param array $sessionData + * @return bool success or failure + */ + public function setSessionData(array $sessionData); + /** * Get the current stateful mode (true is stateful, false is stateless) * diff --git a/src/Amadeus/Client/Session/Handler/InvalidSessionException.php b/src/Amadeus/Client/Session/Handler/InvalidSessionException.php new file mode 100644 index 000000000..5e73ebb3b --- /dev/null +++ b/src/Amadeus/Client/Session/Handler/InvalidSessionException.php @@ -0,0 +1,38 @@ + + */ +class InvalidSessionException extends Exception +{ + +} diff --git a/src/Amadeus/Client/Session/Handler/SoapHeader2.php b/src/Amadeus/Client/Session/Handler/SoapHeader2.php index 71a275540..b4b273f61 100644 --- a/src/Amadeus/Client/Session/Handler/SoapHeader2.php +++ b/src/Amadeus/Client/Session/Handler/SoapHeader2.php @@ -35,49 +35,51 @@ class SoapHeader2 extends Base { /** - * Session information: - * - session ID - * - sequence number - * - security Token - * - * @var array + * Namespace of SoapHeader V2 */ - protected $sessionData = [ - 'sessionId' => null, - 'sequenceNumber' => null, - 'securityToken' => null - ]; + const CORE_WS_V2_SESSION_NS = 'http://xml.amadeus.com/ws/2009/01/WBS_Session-2.0.xsd'; /** - * @param SessionHandlerParams $params + * Node for Session ID */ - public function __construct(SessionHandlerParams $params) - { - parent::__construct($params); - } - + const NODENAME_SESSIONID = "SessionId"; /** - * Method to send a message to the web services server - * - * @param string $messageName The Method name to be called (from the WSDL) - * @param BaseWsMessage $messageBody The message's body to be sent to the server - * @param array $messageOptions Optional options on how to handle this particular message. - * @return string|\stdClass + * Node for Session Sequence Number */ - public function sendMessage($messageName, BaseWsMessage $messageBody, $messageOptions) - { - // TODO: Implement sendMessage() method. - } + const NODENAME_SEQENCENR = "SequenceNumber"; + /** + * Node for Session Security Token + */ + const NODENAME_SECURITYTOKEN = "SecurityToken"; /** * Prepare to send a next message and checks if authenticated * * @param string $messageName * @param array $messageOptions + * @throws InvalidSessionException When trying to send a message without session. */ protected function prepareForNextMessage($messageName, $messageOptions) { - // TODO: Implement prepareForNextMessage() method. + if (!$this->isAuthenticated && $messageName !== 'Security_Authenticate') { + throw new InvalidSessionException('No active session'); + } + + $this->getSoapClient()->__setSoapHeaders(null); + + if ($this->isAuthenticated === true && is_int($this->sessionData['sequenceNumber'])) { + $this->sessionData['sequenceNumber']++; + + $session = new Client\Struct\HeaderV2\Session( + $this->sessionData['sessionId'], + $this->sessionData['sequenceNumber'], + $this->sessionData['securityToken'] + ); + + $this->getSoapClient()->__setSoapHeaders( + new \SoapHeader(self::CORE_WS_V2_SESSION_NS, self::NODENAME_SESSIONID, $session) + ); + } } /** @@ -92,29 +94,60 @@ protected function prepareForNextMessage($messageName, $messageOptions) */ protected function handlePostMessage($messageName, $lastResponse, $messageOptions, $result) { - // TODO: Implement handlePostMessage() method. + if ($messageName === "Security_Authenticate") { + $this->sessionData = $this->getSessionDataFromHeader($lastResponse); + $this->isAuthenticated = (!empty($this->sessionData['sessionId']) && + !empty($this->sessionData['sequenceNumber']) && + !empty($this->sessionData['securityToken'])); + } } - /** - * Cannot set stateless on Soap Header v2 - * - * @param bool $stateful - * @throws UnsupportedOperationException + * @param string $responseMsg the full response XML received. + * @return array */ - public function setStateful($stateful) + protected function getSessionDataFromHeader($responseMsg) { - throw new UnsupportedOperationException('Stateful messages are mandatory on SoapHeader 2'); + $newSessionData = [ + 'sessionId' => null, + 'sequenceNumber' => null, + 'securityToken' => null + ]; + + $responseDomDoc = new \DOMDocument('1.0', 'UTF-8'); + $ok = $responseDomDoc->loadXML($responseMsg); + + if ($ok) { + $sessionId = $responseDomDoc->getElementsByTagName(self::NODENAME_SESSIONID)->item(0)->nodeValue; + if ($sessionId) { + $newSessionData['sessionId'] = $sessionId; + } + $sequence = (int)$responseDomDoc->getElementsByTagName(self::NODENAME_SEQENCENR)->item(0)->nodeValue; + if ($sequence) { + $newSessionData['sequenceNumber'] = $sequence; + } + $securityToken = $responseDomDoc->getElementsByTagName(self::NODENAME_SECURITYTOKEN)->item(0)->nodeValue; + if ($securityToken) { + $newSessionData['securityToken'] = $securityToken; + } + } + + unset($responseDomDoc); + + return $newSessionData; } /** - * Get the session parameters of the active session + * Cannot set stateless on Soap Header v2 * - * @return array|null + * @param bool $stateful + * @throws UnsupportedOperationException */ - public function getSessionData() + public function setStateful($stateful) { - return $this->sessionData; + if ($stateful === false) { + throw new UnsupportedOperationException('Stateful messages are mandatory on SoapHeader 2'); + } } /** diff --git a/src/Amadeus/Client/Session/Handler/SoapHeader4.php b/src/Amadeus/Client/Session/Handler/SoapHeader4.php index 2c43aa11f..212391682 100644 --- a/src/Amadeus/Client/Session/Handler/SoapHeader4.php +++ b/src/Amadeus/Client/Session/Handler/SoapHeader4.php @@ -46,12 +46,6 @@ class SoapHeader4 extends Base */ const XPATH_ENDPOINT = 'string(/wsdl:definitions/wsdl:service/wsdl:port/soap:address/@location)'; - /** - * Status variable to know wether the given session is in a certain context. - * - * @var bool - */ - protected $hasContext = false; /** * Switch between stateful & stateless sessions. Default: stateful @@ -60,29 +54,6 @@ class SoapHeader4 extends Base */ protected $isStateful = true; - /** - * The context of the currently active session - * - * @todo implement this feature - currently the application using the client must know the context itself. - * @var mixed - */ - protected $context; - - /** - * Session information: - * - session ID - * - sequence number - * - security Token - * - * @var array - */ - protected $sessionData = [ - 'sessionId' => null, - 'sequenceNumber' => null, - 'securityToken' => null - ]; - - /** * @param bool $stateful */ @@ -101,17 +72,6 @@ public function isStateful() return $this->isStateful; } - /** - * Get the session parameters of the active session - * - * @return array|null - */ - public function getSessionData() - { - return $this->sessionData; - } - - /** * Handles authentication & sessions * @@ -203,6 +163,8 @@ protected function getSessionDataFromHeader($responseMsg) $newSessionData['securityToken'] = $responseDomXpath->evaluate($querySecurityToken); } + unset($responseDomDoc, $responseDomXpath); + return $newSessionData; } diff --git a/src/Amadeus/Client/Struct/HeaderV2/Session.php b/src/Amadeus/Client/Struct/HeaderV2/Session.php new file mode 100644 index 000000000..29f9b6a80 --- /dev/null +++ b/src/Amadeus/Client/Struct/HeaderV2/Session.php @@ -0,0 +1,57 @@ + + */ +class Session +{ + /** + * @var string + */ + public $sessionId; + /** + * @var int + */ + public $sequenceNumber; + /** + * @var string + */ + public $securityToken; + + /** + * @param string $sessId + * @param int $seqNr + * @param string $secTok + */ + public function __construct($sessId, $seqNr, $secTok) + { + $this->sessionId = $sessId; + $this->sequenceNumber = $seqNr; + $this->securityToken = $secTok; + } +} diff --git a/src/Amadeus/Client/Util/MsgBodyExtractor.php b/src/Amadeus/Client/Util/MsgBodyExtractor.php index c28602cf1..572ccfef0 100644 --- a/src/Amadeus/Client/Util/MsgBodyExtractor.php +++ b/src/Amadeus/Client/Util/MsgBodyExtractor.php @@ -37,6 +37,13 @@ class MsgBodyExtractor */ const REGEXP_SOAP_ENVELOPE_CONTENTS = "|\\(.*?)\\<\\/SOAP-ENV:Body\\>|"; + /** + * Regular expression for extracting the Soap Envelope Body's content - legacy format for Soap Header v2 and older + * + * @var string + */ + const REGEXP_SOAP_ENVELOPE_CONTENTS_LEGACY = "|\\(.*?)\\<\\/soap:Body\\>|"; + /** * Extracts the message content from the soap envelope (i.e. everything under the soap body) * @@ -52,6 +59,12 @@ public static function extract($soapResponse) $messageBody = $matches[1]; } + if (empty($messageBody)) { + if (preg_match(self::REGEXP_SOAP_ENVELOPE_CONTENTS_LEGACY, $soapResponse, $matches) === 1) { + $messageBody = $matches[1]; + } + } + return $messageBody; } } diff --git a/tests/Amadeus/Client/Session/Handler/HandlerFactoryTest.php b/tests/Amadeus/Client/Session/Handler/HandlerFactoryTest.php index cb05526eb..2c4797410 100644 --- a/tests/Amadeus/Client/Session/Handler/HandlerFactoryTest.php +++ b/tests/Amadeus/Client/Session/Handler/HandlerFactoryTest.php @@ -49,13 +49,33 @@ public function testCreateWithoutAuthWillThrowException() HandlerFactory::createHandler($params); } - public function testCreateSoapHeader2WillThrowException() + + public function testCreateSoapHeader4WillCreateSoapHeader4Handler() { - $this->setExpectedException('\InvalidArgumentException'); + $params = $par = new SessionHandlerParams([ + 'wsdl' => '/dummy/path', + 'soapHeaderVersion' => Client::HEADER_V4, + 'receivedFrom' => 'unittests', + 'logger' => new NullLogger(), + 'authParams' => [ + 'officeId' => 'BRUXX0000', + 'originatorTypeCode' => 'U', + 'userId' => 'DUMMYORIG', + 'organizationId' => 'DUMMYORG', + 'passwordLength' => 12, + 'passwordData' => 'dGhlIHBhc3N3b3Jk' + ] + ]); + $createdHandler = HandlerFactory::createHandler($params); + + $this->assertInstanceOf('Amadeus\Client\Session\Handler\SoapHeader4', $createdHandler); + } + + public function testCreateSoapHeader2WillCreateSoapHeader2Handler() + { $params = $par = new SessionHandlerParams([ 'wsdl' => '/dummy/path', - 'stateful' => false, 'soapHeaderVersion' => Client::HEADER_V2, 'receivedFrom' => 'unittests', 'logger' => new NullLogger(), @@ -69,6 +89,30 @@ public function testCreateSoapHeader2WillThrowException() ] ]); + $createdHandler = HandlerFactory::createHandler($params); + + $this->assertInstanceOf('Amadeus\Client\Session\Handler\SoapHeader2', $createdHandler); + } + + public function testCreateSoapHeader1WillThrowException() + { + $this->setExpectedException('\InvalidArgumentException'); + + $params = $par = new SessionHandlerParams([ + 'wsdl' => '/dummy/path', + 'soapHeaderVersion' => Client::HEADER_V1, + 'receivedFrom' => 'unittests', + 'logger' => new NullLogger(), + 'authParams' => [ + 'officeId' => 'BRUXX0000', + 'originatorTypeCode' => 'U', + 'userId' => 'DUMMYORIG', + 'organizationId' => 'DUMMYORG', + 'passwordLength' => 12, + 'passwordData' => 'dGhlIHBhc3N3b3Jk' + ] + ]); + HandlerFactory::createHandler($params); } } diff --git a/tests/Amadeus/Client/Session/Handler/SoapHeader2Test.php b/tests/Amadeus/Client/Session/Handler/SoapHeader2Test.php new file mode 100644 index 000000000..3f69d7a9c --- /dev/null +++ b/tests/Amadeus/Client/Session/Handler/SoapHeader2Test.php @@ -0,0 +1,132 @@ + + */ +class SoapHeader2Test extends BaseTestCase +{ + + public function testCanTrySendMessageWhenNotAuthenticated() + { + $this->setExpectedException('Amadeus\Client\Session\Handler\InvalidSessionException'); + + $handler = new SoapHeader2($this->makeSessionHandlerParams()); + + $handler->sendMessage( + 'PNR_Retrieve', + new Client\Struct\Pnr\Retrieve(Client\Struct\Pnr\Retrieve::RETR_TYPE_BY_RECLOC, 'ABC123'), + [ + 'asString' => false, + 'endSession' => false + ] + ); + } + + public function testCanTryPrepareNextMessageWhenAuthenticated() + { + $overrideSoapClient = $this->getMock( + 'Amadeus\Client\SoapClient', + ['__getLastRequest', '__getLastResponse', 'PNR_Retrieve'], + [], + '', + false + ); + + $dummyPnrRequest = $this->getTestFile('dummyPnrRequestsoapheader2.txt'); + $dummyPnrReply = $this->getTestFile('dummyPnrReplysoapheader2.txt'); + $dummyPnrReplyExtractedMessage = $this->getTestFile('dummyPnrReplyExtractedMessageSoapHeader2.txt'); + + $overrideSoapClient + ->expects($this->atLeastOnce()) + ->method('__getLastRequest') + ->will($this->returnValue($dummyPnrRequest)); + + $overrideSoapClient + ->expects($this->atLeastOnce()) + ->method('__getLastResponse') + ->will($this->returnValue($dummyPnrReply)); + + $overrideSoapClient + ->expects($this->any()) + ->method('PNR_Retrieve') + ->will($this->returnValue('')); + + $handler = new SoapHeader2($this->makeSessionHandlerParams( + $overrideSoapClient + )); + $handler->setSessionData([ + 'sessionId' => 'XFHZEKLRZHREJ', + 'sequenceNumber' => 12, + 'securityToken' => 'RKLERJEZLKRHZEJKLRHEZJKLREZRHEZK' + ]); + + $messageResponse = $handler->sendMessage( + 'PNR_Retrieve', + new Client\Struct\Pnr\Retrieve(Client\Struct\Pnr\Retrieve::RETR_TYPE_BY_RECLOC, 'ABC123'), + [ + 'asString' => true, + 'endSession' => false + ] + ); + + $this->assertInternalType('string', $messageResponse); + $this->assertEquals($dummyPnrReplyExtractedMessage, $messageResponse); + } + + /** + * @param \SoapClient|null $overrideSoapClient + * @return SessionHandlerParams + */ + protected function makeSessionHandlerParams($overrideSoapClient = null) + { + $wsdlpath = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'testfiles' . DIRECTORY_SEPARATOR . 'soapheader2' . DIRECTORY_SEPARATOR . 'testwsdlsoapheader2.wsdl'; + + $par = new SessionHandlerParams([ + 'wsdl' => realpath($wsdlpath), + 'soapHeaderVersion' => Client::HEADER_V2, + 'receivedFrom' => 'unittests', + 'logger' => new NullLogger(), + 'overrideSoapClient' => $overrideSoapClient, + 'authParams' => [ + 'officeId' => 'BRUXX0000', + 'originatorTypeCode' => 'U', + 'userId' => 'DUMMYORIG', + 'organizationId' => 'DUMMYORG', + 'passwordLength' => 12, + 'passwordData' => 'dGhlIHBhc3N3b3Jk' + ] + ]); + + return $par; + } +} diff --git a/tests/Amadeus/Client/Session/Handler/testfiles/dummyPnrReplyExtractedMessageSoapHeader2.txt b/tests/Amadeus/Client/Session/Handler/testfiles/dummyPnrReplyExtractedMessageSoapHeader2.txt new file mode 100644 index 000000000..45bdfda32 --- /dev/null +++ b/tests/Amadeus/Client/Session/Handler/testfiles/dummyPnrReplyExtractedMessageSoapHeader2.txt @@ -0,0 +1 @@ +1AABC123090914RPXXXXBRUBGXXXXxxxBRUBGXXXXBRUBRUBGXXXY0001AA090914000000007173P12--- TST RLR ---000000BRUBGXXXXT1ABRUBE0000000BRUBGXXXYE1ABRUBE000000000BRUBGXXXYE1ABRUBE302015311PT2NM1BOWIE1DAVID MRST1AIR210031507551003151020BRUMADIB3207NET1IBABC1231HK321024ST2AIR311031519351103152155MADBRUIB3208NET1IBABC1231HK321034OT7AP4350322112121212-BOT22TK5TL100914BRUBGXXXXOT8OS6328YYDAVIDBOWIE//AMADEUS.COMOT6RM7RMPRICING ENTRY FXP/R,UP,BRU.BRUST1ST2PT2OT9RM8RMMODETICKETOT11RM9RMTIDBOWIEXDAVOT12RM10RMTSA INFORMATION OMITTED ON PURPOSEPT2OT13RM11RMAGENT FEE OF 10.00 EUR VISIBLE IN FEEOT14RM12RMFARE197.52 EURPT2OT15RM13RMFARE :197.52 EURST1ST2OT19RM14RMCOSECONOMY RESTRICTEDST1ST2OT20RM15RMMOPINVOICING TO CORPORATIONOT21RM16RMFTYPRIVATEST1ST2PT2OT16RM17RM*BOOKED BY AMADEUS E-TRAVEL MANAGEMENTOT17RM18RM*TRP/RECBUSOT18RM19RM*TRP/RETBUSINESSOT26RM20RM*ACERMK-FEE-ETMOT4FE21310PAX 22 NOREF-NON END/NO CHGSST1ST2PT2OT23FP22316CASHOT5FV233P18PAX IBST1ST2PT2OT10AB2432A DUMMY ADDRESS \ No newline at end of file diff --git a/tests/Amadeus/Client/Session/Handler/testfiles/dummyPnrReplysoapheader2.txt b/tests/Amadeus/Client/Session/Handler/testfiles/dummyPnrReplysoapheader2.txt new file mode 100644 index 000000000..33a9f4476 --- /dev/null +++ b/tests/Amadeus/Client/Session/Handler/testfiles/dummyPnrReplysoapheader2.txt @@ -0,0 +1 @@ +XFHZEKLRZHREJ13RKLERJEZLKRHZEJKLRHEZJKLREZRHEZK1AABC123090914RPXXXXBRUBGXXXXxxxBRUBGXXXXBRUBRUBGXXXY0001AA090914000000007173P12--- TST RLR ---000000BRUBGXXXXT1ABRUBE0000000BRUBGXXXYE1ABRUBE000000000BRUBGXXXYE1ABRUBE302015311PT2NM1BOWIE1DAVID MRST1AIR210031507551003151020BRUMADIB3207NET1IBABC1231HK321024ST2AIR311031519351103152155MADBRUIB3208NET1IBABC1231HK321034OT7AP4350322112121212-BOT22TK5TL100914BRUBGXXXXOT8OS6328YYDAVIDBOWIE//AMADEUS.COMOT6RM7RMPRICING ENTRY FXP/R,UP,BRU.BRUST1ST2PT2OT9RM8RMMODETICKETOT11RM9RMTIDBOWIEXDAVOT12RM10RMTSA INFORMATION OMITTED ON PURPOSEPT2OT13RM11RMAGENT FEE OF 10.00 EUR VISIBLE IN FEEOT14RM12RMFARE197.52 EURPT2OT15RM13RMFARE :197.52 EURST1ST2OT19RM14RMCOSECONOMY RESTRICTEDST1ST2OT20RM15RMMOPINVOICING TO CORPORATIONOT21RM16RMFTYPRIVATEST1ST2PT2OT16RM17RM*BOOKED BY AMADEUS E-TRAVEL MANAGEMENTOT17RM18RM*TRP/RECBUSOT18RM19RM*TRP/RETBUSINESSOT26RM20RM*ACERMK-FEE-ETMOT4FE21310PAX 22 NOREF-NON END/NO CHGSST1ST2PT2OT23FP22316CASHOT5FV233P18PAX IBST1ST2PT2OT10AB2432A DUMMY ADDRESS \ No newline at end of file diff --git a/tests/Amadeus/Client/Session/Handler/testfiles/dummyPnrRequestsoapheader2.txt b/tests/Amadeus/Client/Session/Handler/testfiles/dummyPnrRequestsoapheader2.txt new file mode 100644 index 000000000..8f5767b6a --- /dev/null +++ b/tests/Amadeus/Client/Session/Handler/testfiles/dummyPnrRequestsoapheader2.txt @@ -0,0 +1,2 @@ + +XFHZEKLRZHREJ13RKLERJEZLKRHZEJKLRHEZJKLREZRHEZK2ABC123 \ No newline at end of file diff --git a/tests/Amadeus/ClientTest.php b/tests/Amadeus/ClientTest.php index 71c6145be..2945a2ea6 100644 --- a/tests/Amadeus/ClientTest.php +++ b/tests/Amadeus/ClientTest.php @@ -1354,6 +1354,57 @@ public function testCanDoSignOutCall() $this->assertEquals($messageResult, $response); } + public function testCanDoAuthenticateCall() + { + $mockSessionHandler = $this->getMockBuilder('Amadeus\Client\Session\Handler\HandlerInterface')->getMock(); + + $authParams = new Params\AuthParams([ + 'officeId' => 'BRUXXXXXX', + 'originatorTypeCode' => 'U', + 'userId' => 'WSXXXXXX', + 'passwordData' => base64_encode('TEST'), + 'passwordLength' => 4, + 'dutyCode' => 'SU', + 'organizationId' => 'NMC-BENELU', + ]); + + $messageResult = new \stdClass(); + $messageResult->processStatus = new \stdClass(); + $messageResult->processStatus->statusCode = 'P'; + + $expectedMessageResult = new Client\Struct\Security\Authenticate( + new Client\RequestOptions\SecurityAuthenticateOptions( + $authParams + ) + ); + + $mockSessionHandler + ->expects($this->once()) + ->method('sendMessage') + ->with('Security_Authenticate', $expectedMessageResult, ['asString' => false, 'endSession' => false]) + ->will($this->returnValue($messageResult)); + $mockSessionHandler + ->expects($this->never()) + ->method('getLastResponse'); + $mockSessionHandler + ->expects($this->once()) + ->method('getMessagesAndVersions') + ->will($this->returnValue(['Security_Authenticate' => "6.1"])); + + $par = new Params(); + $par->sessionHandler = $mockSessionHandler; + $par->requestCreatorParams = new Params\RequestCreatorParams([ + 'receivedFrom' => 'some RF string', + 'originatorOfficeId' => 'BRUXXXXXX' + ]); + + $client = new Client($par); + + $response = $client->securityAuthenticate(); + + $this->assertEquals($messageResult, $response); + } + public function dataProviderMakeMessageOptions() From 0d2f8c3bc623a6009acd4014b942e1b89ca2f54b Mon Sep 17 00:00:00 2001 From: Dieter Devlieghere Date: Wed, 30 Mar 2016 23:37:02 +0200 Subject: [PATCH 05/12] Unittest for auth --- .../Session/Handler/SoapHeader2Test.php | 79 ++++ ...riceXplorer_ExtremeSearchReply_10_3_1A.xsd | 5 + .../PriceXplorer_ExtremeSearch_10_3_1A.xsd | 5 + .../Security_AuthenticateReply_06_1_1A.xsd | 173 +++++++++ .../Security_Authenticate_06_1_1A.xsd | 367 ++++++++++++++++++ .../Security_SignOutReply_04_1_1A.xsd | 133 +++++++ .../soapheader2/Security_SignOut_04_1_1A.xsd | 59 +++ .../testfiles/soapheader2/WBS_Session-2.0.xsd | 27 ++ .../soapheader2/dummySecurityAuth.txt | 2 + .../soapheader2/dummySecurityAuthReply.txt | 1 + .../soapheader2/testwsdlsoapheader2.wsdl | 91 +++++ 11 files changed, 942 insertions(+) create mode 100644 tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/PriceXplorer_ExtremeSearchReply_10_3_1A.xsd create mode 100644 tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/PriceXplorer_ExtremeSearch_10_3_1A.xsd create mode 100644 tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/Security_AuthenticateReply_06_1_1A.xsd create mode 100644 tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/Security_Authenticate_06_1_1A.xsd create mode 100644 tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/Security_SignOutReply_04_1_1A.xsd create mode 100644 tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/Security_SignOut_04_1_1A.xsd create mode 100644 tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/WBS_Session-2.0.xsd create mode 100644 tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/dummySecurityAuth.txt create mode 100644 tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/dummySecurityAuthReply.txt create mode 100644 tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/testwsdlsoapheader2.wsdl diff --git a/tests/Amadeus/Client/Session/Handler/SoapHeader2Test.php b/tests/Amadeus/Client/Session/Handler/SoapHeader2Test.php index 3f69d7a9c..dbc8ae998 100644 --- a/tests/Amadeus/Client/Session/Handler/SoapHeader2Test.php +++ b/tests/Amadeus/Client/Session/Handler/SoapHeader2Test.php @@ -103,6 +103,85 @@ public function testCanTryPrepareNextMessageWhenAuthenticated() $this->assertEquals($dummyPnrReplyExtractedMessage, $messageResponse); } + public function testCanSendAuthCallAndStartSession() + { + $overrideSoapClient = $this->getMock( + 'Amadeus\Client\SoapClient', + ['__getLastRequest', '__getLastResponse', 'Security_Authenticate'], + [], + '', + false + ); + + $dummyRequest = $this->getTestFile('soapheader2' . DIRECTORY_SEPARATOR . 'dummySecurityAuth.txt'); + $dummyReply = $this->getTestFile('soapheader2' . DIRECTORY_SEPARATOR . 'dummySecurityAuthReply.txt'); + + $messageResult = new \stdClass(); + $messageResult->processStatus = new \stdClass(); + $messageResult->processStatus->statusCode = 'P'; + + $overrideSoapClient + ->expects($this->atLeastOnce()) + ->method('__getLastRequest') + ->will($this->returnValue($dummyRequest)); + + $overrideSoapClient + ->expects($this->atLeastOnce()) + ->method('__getLastResponse') + ->will($this->returnValue($dummyReply)); + + $overrideSoapClient + ->expects($this->any()) + ->method('Security_Authenticate') + ->will($this->returnValue($messageResult)); + + $handlerParams = $this->makeSessionHandlerParams( + $overrideSoapClient + ); + + $handler = new SoapHeader2($handlerParams); + + //SEND MESSAGE AND CHECK RESULT + $actualSendResult = $handler->sendMessage( + 'Security_Authenticate', + new Client\Struct\Security\Authenticate( + new Client\RequestOptions\SecurityAuthenticateOptions( + $handlerParams->authParams + ) + ), + [ + 'asString' => false, + 'endSession' => false + ] + ); + + $this->assertEquals($messageResult, $actualSendResult); + + //ASSERT THAT THE SESSION HAS BEEN STARTED CORRECTLY + $expectedSessionData = [ + 'sessionId' => 'IROZERIIOP', + 'sequenceNumber' => 1, + 'securityToken' => 'FDKLSDMJFSMLRJEZRHZJ' + ]; + + $this->assertEquals( + $expectedSessionData, + $handler->getSessionData() + ); + } + + public function testGetLastRequestEmptyWithNoMessages() + { + + $handlerParams = $this->makeSessionHandlerParams(); + + $handler = new SoapHeader2($handlerParams); + + $result = $handler->getLastRequest(); + + $this->assertNull($result); + } + /** * @param \SoapClient|null $overrideSoapClient * @return SessionHandlerParams diff --git a/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/PriceXplorer_ExtremeSearchReply_10_3_1A.xsd b/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/PriceXplorer_ExtremeSearchReply_10_3_1A.xsd new file mode 100644 index 000000000..7db1e9361 --- /dev/null +++ b/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/PriceXplorer_ExtremeSearchReply_10_3_1A.xsd @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/PriceXplorer_ExtremeSearch_10_3_1A.xsd b/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/PriceXplorer_ExtremeSearch_10_3_1A.xsd new file mode 100644 index 000000000..fe8fdc736 --- /dev/null +++ b/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/PriceXplorer_ExtremeSearch_10_3_1A.xsd @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/Security_AuthenticateReply_06_1_1A.xsd b/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/Security_AuthenticateReply_06_1_1A.xsd new file mode 100644 index 000000000..3d478f50b --- /dev/null +++ b/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/Security_AuthenticateReply_06_1_1A.xsd @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + Format limitations: an..5 + + + + + + + + + + + Format limitations: an..3 + + + + + + + + + + + Format limitations: an..3 + + + + + + + + + + + + + + + + + + + + + + + Format limitations: an..3 + + + + + + + + + + + Format limitations: an..4 + + + + + + + + + + + Format limitations: an..3 + + + + + + + + + + + + + + Format limitations: an..70 + + + + + + + + + + + + + + + + + + + + Format limitations: a..6 + + + + + + + + + + + + + + + + + + + + Format limitations: an..10 + + + + + + + + + + + + + + + + + + + + Format limitations: an..10 + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/Security_Authenticate_06_1_1A.xsd b/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/Security_Authenticate_06_1_1A.xsd new file mode 100644 index 000000000..31b9c6201 --- /dev/null +++ b/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/Security_Authenticate_06_1_1A.xsd @@ -0,0 +1,367 @@ + + + + + + + + + + + + + Format limitations: an..35 + + + + + + + + + + + Format limitations: an..35 + + + + + + + + + + + Format limitations: an..14 + + + + + + + + + + + Format limitations: an..14 + + + + + + + + + + + + + + + + + + + + Format limitations: an..9 + + + + + + + + + + + + + + Format limitations: an1 + + + + + + + + + + + Format limitations: an..30 + + + + + + + + + + + + + + + + + + + + Format limitations: an..3 + + + + + + + + + + + Format limitations: an..35 + + + + + + + + + + + + + + + + + + + + Format limitations: an..35 + + + + + + + + + + + + + + Format limitations: an..35 + + + + + + + + + + + + + + Format limitations: an1 + + + + + + + + + + + + + + + + + Format limitations: n..15 + + + + + + + + + Format limitations: an1 + + + + + + + + + + + Format limitations: an..99999 + + + + + + + + + + + + + + + + + + + + Format limitations: an..3 + + + + + + + + + + + + + + Format limitations: an..35 + + + + + + + + + + + Format limitations: an..17 + + + + + + + + + + + + + + + + + Format limitations: an..25 + + + + + + + + + + + Format limitations: an..17 + + + + + + + + + + + + + + + + + + + + + + + Format limitations: an..3 + + + + + + + + + + + Format limitations: an..5 + + + + + + + + + + + + + + + + + + + + + + + + + + Format limitations: an..35 + + + + + + + + + + + Format limitations: an..6 + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/Security_SignOutReply_04_1_1A.xsd b/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/Security_SignOutReply_04_1_1A.xsd new file mode 100644 index 000000000..74c9cb884 --- /dev/null +++ b/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/Security_SignOutReply_04_1_1A.xsd @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + Format limitations: an..5 + + + + + + + + + + + Format limitations: an..3 + + + + + + + + + + + Format limitations: an..3 + + + + + + + + + + + + + + + + + + + + + + + Format limitations: an..3 + + + + + + + + + + + Format limitations: an..4 + + + + + + + + + + + Format limitations: an..3 + + + + + + + + + + + + + + Format limitations: an..70 + + + + + + + + + + + + + + + + + + + + Format limitations: a..6 + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/Security_SignOut_04_1_1A.xsd b/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/Security_SignOut_04_1_1A.xsd new file mode 100644 index 000000000..b6239ab6d --- /dev/null +++ b/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/Security_SignOut_04_1_1A.xsd @@ -0,0 +1,59 @@ + + + + + + + + + + + + + Format limitations: an..35 + + + + + + + + + + + Format limitations: an..35 + + + + + + + + + + + Format limitations: an..14 + + + + + + + + + + + Format limitations: an..14 + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/WBS_Session-2.0.xsd b/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/WBS_Session-2.0.xsd new file mode 100644 index 000000000..fcf3ad6ab --- /dev/null +++ b/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/WBS_Session-2.0.xsd @@ -0,0 +1,27 @@ + + + + + + + + + + + This element defines the identifier part of the SessionId. + + + + + This element defines the sequence number of the SessionId. + + + + + This element defines the SecurityToken of the SessionId. + + + + + + \ No newline at end of file diff --git a/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/dummySecurityAuth.txt b/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/dummySecurityAuth.txt new file mode 100644 index 000000000..18cac6001 --- /dev/null +++ b/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/dummySecurityAuth.txt @@ -0,0 +1,2 @@ + +BRUXX0000UDUMMYORIGDUTSUDUMMYORG12EdGhlIHBhc3N3b3Jk \ No newline at end of file diff --git a/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/dummySecurityAuthReply.txt b/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/dummySecurityAuthReply.txt new file mode 100644 index 000000000..efd636d83 --- /dev/null +++ b/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/dummySecurityAuthReply.txt @@ -0,0 +1 @@ +IROZERIIOP1FDKLSDMJFSMLRJEZRHZJP \ No newline at end of file diff --git a/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/testwsdlsoapheader2.wsdl b/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/testwsdlsoapheader2.wsdl new file mode 100644 index 000000000..70c6a5bca --- /dev/null +++ b/tests/Amadeus/Client/Session/Handler/testfiles/soapheader2/testwsdlsoapheader2.wsdl @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 3c3ddaf0639f7749bb38746afd708f896ce6d8c5 Mon Sep 17 00:00:00 2001 From: Dieter Devlieghere Date: Wed, 30 Mar 2016 23:56:43 +0200 Subject: [PATCH 06/12] Security_Authenticate message structure --- src/Amadeus/Client.php | 4 +- .../Struct/Security/ApplicationDetails.php | 41 ++++++++++ .../Client/Struct/Security/ApplicationId.php | 37 +++++++++ .../Client/Struct/Security/Authenticate.php | 25 +++++- .../Struct/Security/ConversationClt.php | 49 ++++++++++++ .../Client/Struct/Security/DutyCode.php | 47 ++++++++++++ .../Struct/Security/DutyCodeDetails.php | 62 +++++++++++++++ .../Struct/Security/OrganizationDetails.php | 47 ++++++++++++ .../Struct/Security/OriginIdentification.php | 47 ++++++++++++ .../Client/Struct/Security/PasswordInfo.php | 76 +++++++++++++++++++ .../Client/Struct/Security/SystemDetails.php | 55 ++++++++++++++ .../Client/Struct/Security/UserIdentifier.php | 59 ++++++++++++++ .../Struct/Security/AuthenticateTest.php | 70 +++++++++++++++++ tests/Amadeus/ClientTest.php | 3 +- 14 files changed, 619 insertions(+), 3 deletions(-) create mode 100644 src/Amadeus/Client/Struct/Security/ApplicationDetails.php create mode 100644 src/Amadeus/Client/Struct/Security/ApplicationId.php create mode 100644 src/Amadeus/Client/Struct/Security/ConversationClt.php create mode 100644 src/Amadeus/Client/Struct/Security/DutyCode.php create mode 100644 src/Amadeus/Client/Struct/Security/DutyCodeDetails.php create mode 100644 src/Amadeus/Client/Struct/Security/OrganizationDetails.php create mode 100644 src/Amadeus/Client/Struct/Security/OriginIdentification.php create mode 100644 src/Amadeus/Client/Struct/Security/PasswordInfo.php create mode 100644 src/Amadeus/Client/Struct/Security/SystemDetails.php create mode 100644 src/Amadeus/Client/Struct/Security/UserIdentifier.php create mode 100644 tests/Amadeus/Client/Struct/Security/AuthenticateTest.php diff --git a/src/Amadeus/Client.php b/src/Amadeus/Client.php index 49b4b5d26..19649c833 100644 --- a/src/Amadeus/Client.php +++ b/src/Amadeus/Client.php @@ -151,7 +151,9 @@ public function __construct($params) { if ($params->authParams instanceof Params\AuthParams) { $this->authParams = $params->authParams; - $params->sessionHandlerParams->authParams = $this->authParams; + if (isset($params->sessionHandlerParams) && $params->sessionHandlerParams instanceof Params\SessionHandlerParams) { + $params->sessionHandlerParams->authParams = $this->authParams; + } } $this->sessionHandler = $this->loadSessionHandler( diff --git a/src/Amadeus/Client/Struct/Security/ApplicationDetails.php b/src/Amadeus/Client/Struct/Security/ApplicationDetails.php new file mode 100644 index 000000000..5ba6d7677 --- /dev/null +++ b/src/Amadeus/Client/Struct/Security/ApplicationDetails.php @@ -0,0 +1,41 @@ + + */ +class ApplicationDetails +{ + /** + * @var string + */ + public $internalId; + /** + * @var string + */ + public $seqNumber; +} diff --git a/src/Amadeus/Client/Struct/Security/ApplicationId.php b/src/Amadeus/Client/Struct/Security/ApplicationId.php new file mode 100644 index 000000000..7551b65f1 --- /dev/null +++ b/src/Amadeus/Client/Struct/Security/ApplicationId.php @@ -0,0 +1,37 @@ + + */ +class ApplicationId +{ + /** + * @var ApplicationDetails + */ + public $applicationDetails; +} diff --git a/src/Amadeus/Client/Struct/Security/Authenticate.php b/src/Amadeus/Client/Struct/Security/Authenticate.php index fb47964e1..cfaa638f1 100644 --- a/src/Amadeus/Client/Struct/Security/Authenticate.php +++ b/src/Amadeus/Client/Struct/Security/Authenticate.php @@ -22,12 +22,12 @@ namespace Amadeus\Client\Struct\Security; +use Amadeus\Client\RequestOptions\SecurityAuthenticateOptions; use Amadeus\Client\Struct\BaseWsMessage; /** * Authenticate * - * @todo Implement this message when we support SoapHeader v. 1 or 2 * @package Amadeus\Client\Struct\Security * @author Dieter Devlieghere */ @@ -61,4 +61,27 @@ class Authenticate extends BaseWsMessage * @var ApplicationId */ public $applicationId; + + /** + * Authenticate constructor. + * + * @param SecurityAuthenticateOptions $params + */ + public function __construct(SecurityAuthenticateOptions $params) + { + $this->userIdentifier = new UserIdentifier( + $params->officeId, + $params->originatorTypeCode, + $params->userId + ); + + $this->dutyCode = new DutyCode($params->dutyCode); + + $this->systemDetails = new SystemDetails($params->organizationId); + + $this->passwordInfo = new PasswordInfo( + $params->passwordData, + $params->passwordLength + ); + } } diff --git a/src/Amadeus/Client/Struct/Security/ConversationClt.php b/src/Amadeus/Client/Struct/Security/ConversationClt.php new file mode 100644 index 000000000..962c1c18b --- /dev/null +++ b/src/Amadeus/Client/Struct/Security/ConversationClt.php @@ -0,0 +1,49 @@ + + */ +class ConversationClt +{ + /** + * @var string + */ + public $senderIdentification = 0; + /** + * @var string + */ + public $recipientIdentification = 0; + /** + * @var string + */ + public $senderInterchangeControlReference = 0; + /** + * @var string + */ + public $recipientInterchangeControlReference = 0; +} diff --git a/src/Amadeus/Client/Struct/Security/DutyCode.php b/src/Amadeus/Client/Struct/Security/DutyCode.php new file mode 100644 index 000000000..8fb873f3a --- /dev/null +++ b/src/Amadeus/Client/Struct/Security/DutyCode.php @@ -0,0 +1,47 @@ + + */ +class DutyCode +{ + /** + * @var DutyCodeDetails + */ + public $dutyCodeDetails; + + /** + * DutyCode constructor. + * + * @param string $dutyCode + */ + public function __construct($dutyCode) + { + $this->dutyCodeDetails = new DutyCodeDetails($dutyCode); + } +} diff --git a/src/Amadeus/Client/Struct/Security/DutyCodeDetails.php b/src/Amadeus/Client/Struct/Security/DutyCodeDetails.php new file mode 100644 index 000000000..d85d458b3 --- /dev/null +++ b/src/Amadeus/Client/Struct/Security/DutyCodeDetails.php @@ -0,0 +1,62 @@ + + */ +class DutyCodeDetails +{ + /** + * Definition of Dutycode Reference qualifier "Duty Code" + * + * See Amadeus Core Webservices documentation + * [Reference qualifier codesets (Ref: 1153 IA 01.2.57)] + * @var string + */ + const RQ_DUTYCODE = "DUT"; + + /** + * @var string + */ + public $referenceQualifier; + /** + * @var string + */ + public $referenceIdentifier; + + /** + * DutyCodeDetails constructor. + * + * @param string $dutyCode + * @param string $qual + */ + public function __construct($dutyCode, $qual = self::RQ_DUTYCODE) + { + $this->referenceIdentifier = $dutyCode; + $this->referenceQualifier = $qual; + } +} diff --git a/src/Amadeus/Client/Struct/Security/OrganizationDetails.php b/src/Amadeus/Client/Struct/Security/OrganizationDetails.php new file mode 100644 index 000000000..2db829c3a --- /dev/null +++ b/src/Amadeus/Client/Struct/Security/OrganizationDetails.php @@ -0,0 +1,47 @@ + + */ +class OrganizationDetails +{ + /** + * @var string + */ + public $organizationId; + + /** + * OrganizationDetails constructor. + * + * @param string $organizationId + */ + public function __construct($organizationId) + { + $this->organizationId = $organizationId; + } +} diff --git a/src/Amadeus/Client/Struct/Security/OriginIdentification.php b/src/Amadeus/Client/Struct/Security/OriginIdentification.php new file mode 100644 index 000000000..64a4f5cb1 --- /dev/null +++ b/src/Amadeus/Client/Struct/Security/OriginIdentification.php @@ -0,0 +1,47 @@ + + */ +class OriginIdentification +{ + /** + * @var string + */ + public $sourceOffice; + + /** + * OriginIdentification constructor. + * + * @param string $officeId + */ + public function __construct($officeId) + { + $this->sourceOffice = $officeId; + } +} diff --git a/src/Amadeus/Client/Struct/Security/PasswordInfo.php b/src/Amadeus/Client/Struct/Security/PasswordInfo.php new file mode 100644 index 000000000..06af03392 --- /dev/null +++ b/src/Amadeus/Client/Struct/Security/PasswordInfo.php @@ -0,0 +1,76 @@ + + */ +class PasswordInfo +{ + /** + * Definition of Password Data type "EDIFACT DATA" + * + * See Amadeus Core Webservices documentation + * [DATA TYPE codesets (Ref: 116Z 1A 02.1.8)] + * @var string + */ + const DATA_TYPE_EDIFACT = 'E'; + /** + * Definition of Password Data type "BINARY DATA" + * + * See Amadeus Core Webservices documentation + * [DATA TYPE codesets (Ref: 116Z 1A 02.1.8)] + * @var string + */ + const DATA_TYPE_BINARY = 'B'; + + /** + * @var int + */ + public $dataLength; + /** + * @var string + */ + public $dataType; + /** + * @var string + */ + public $binaryData; + + /** + * PasswordInfo constructor. + * + * @param string $passwordData + * @param int $passwordLength + * @param string $type + */ + public function __construct($passwordData, $passwordLength, $type = self::DATA_TYPE_EDIFACT) + { + $this->binaryData = $passwordData; + $this->dataLength = $passwordLength; + $this->dataType = $type; + } +} diff --git a/src/Amadeus/Client/Struct/Security/SystemDetails.php b/src/Amadeus/Client/Struct/Security/SystemDetails.php new file mode 100644 index 000000000..71294f69b --- /dev/null +++ b/src/Amadeus/Client/Struct/Security/SystemDetails.php @@ -0,0 +1,55 @@ + + */ +class SystemDetails +{ + /** + * @var string + */ + public $workstationId; + /** + * @var OrganizationDetails + */ + public $organizationDetails; + /** + * @var string + */ + public $idQualifier; + + /** + * SystemDetails constructor. + * + * @param string $organizationId + */ + public function __construct($organizationId) + { + $this->organizationDetails = new OrganizationDetails($organizationId); + } +} diff --git a/src/Amadeus/Client/Struct/Security/UserIdentifier.php b/src/Amadeus/Client/Struct/Security/UserIdentifier.php new file mode 100644 index 000000000..c63cf9aa9 --- /dev/null +++ b/src/Amadeus/Client/Struct/Security/UserIdentifier.php @@ -0,0 +1,59 @@ + + */ +class UserIdentifier +{ + /** + * @var OriginIdentification + */ + public $originIdentification; + /** + * @var string + */ + public $originatorTypeCode; + /** + * @var string + */ + public $originator; + + /** + * UserIdentifier constructor. + * + * @param string $officeId + * @param string $originatorTypeCode + * @param string $originator + */ + public function __construct($officeId, $originatorTypeCode, $originator) + { + $this->originIdentification = new OriginIdentification($officeId); + $this->originatorTypeCode = $originatorTypeCode; + $this->originator = $originator; + } +} diff --git a/tests/Amadeus/Client/Struct/Security/AuthenticateTest.php b/tests/Amadeus/Client/Struct/Security/AuthenticateTest.php new file mode 100644 index 000000000..2d4946308 --- /dev/null +++ b/tests/Amadeus/Client/Struct/Security/AuthenticateTest.php @@ -0,0 +1,70 @@ + + */ +class AuthenticateTest extends BaseTestCase +{ + + public function testCanConstructAuthMessage() + { + $authParams = new AuthParams([ + 'officeId' => 'BRUXXXXXX', + 'originatorTypeCode' => 'U', + 'userId' => 'WSXXXXXX', + 'passwordData' => base64_encode('TEST'), + 'passwordLength' => 4, + 'dutyCode' => 'SU', + 'organizationId' => 'DUMMY-ORG', + ]); + + $reqOpt = new SecurityAuthenticateOptions($authParams); + + $message = new Authenticate($reqOpt); + + $this->assertEquals('BRUXXXXXX' , $message->userIdentifier->originIdentification->sourceOffice); + $this->assertEquals('U' , $message->userIdentifier->originatorTypeCode); + $this->assertEquals('WSXXXXXX' , $message->userIdentifier->originator); + + $this->assertEquals('DUT' , $message->dutyCode->dutyCodeDetails->referenceQualifier); + $this->assertEquals('SU' , $message->dutyCode->dutyCodeDetails->referenceIdentifier); + + $this->assertEquals('DUMMY-ORG' , $message->systemDetails->organizationDetails->organizationId); + + $this->assertEquals(PasswordInfo::DATA_TYPE_EDIFACT , $message->passwordInfo->dataType); + $this->assertEquals(4 , $message->passwordInfo->dataLength); + $this->assertEquals(base64_encode('TEST') , $message->passwordInfo->binaryData); + + } +} diff --git a/tests/Amadeus/ClientTest.php b/tests/Amadeus/ClientTest.php index 2945a2ea6..ddb0d0248 100644 --- a/tests/Amadeus/ClientTest.php +++ b/tests/Amadeus/ClientTest.php @@ -1365,7 +1365,7 @@ public function testCanDoAuthenticateCall() 'passwordData' => base64_encode('TEST'), 'passwordLength' => 4, 'dutyCode' => 'SU', - 'organizationId' => 'NMC-BENELU', + 'organizationId' => 'DUMMY-ORG', ]); $messageResult = new \stdClass(); @@ -1392,6 +1392,7 @@ public function testCanDoAuthenticateCall() ->will($this->returnValue(['Security_Authenticate' => "6.1"])); $par = new Params(); + $par->authParams = $authParams; $par->sessionHandler = $mockSessionHandler; $par->requestCreatorParams = new Params\RequestCreatorParams([ 'receivedFrom' => 'some RF string', From 32d93a9980dbdf30e27a32fe2deca0b3db473282 Mon Sep 17 00:00:00 2001 From: Dieter Devlieghere Date: Thu, 31 Mar 2016 00:16:06 +0200 Subject: [PATCH 07/12] implemented setSessionData() and improved docs to reflect support for Soap Header 2 --- README.md | 2 +- docs/about-get-started.rst | 53 +++++++++++++++++-- docs/samples.rst | 23 ++++++++ src/Amadeus/Client.php | 16 +++++- src/Amadeus/Client/Struct/SessionHeaderV2.php | 35 ------------ tests/Amadeus/ClientTest.php | 30 +++++++++++ 6 files changed, 117 insertions(+), 42 deletions(-) delete mode 100644 src/Amadeus/Client/Struct/SessionHeaderV2.php diff --git a/README.md b/README.md index 702f532c8..c3a34f2fd 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The Amadeus documentation portal can be found at https://webservices.amadeus.com * PHP 5.4+ * SOAP and XSL extensions activated -* A WSDL & authentication details from Amadeus +* A WSDL & authentication details from Amadeus _(SoapHeader 4 or SoapHeader 2)_ # Installation diff --git a/docs/about-get-started.rst b/docs/about-get-started.rst index 8727f5c72..ccd31cbe4 100644 --- a/docs/about-get-started.rst +++ b/docs/about-get-started.rst @@ -20,9 +20,11 @@ Support for Amadeus Soap Header versions **************************************** Upon receiving access, Amadeus will give you a Web Service Access Point with a specific Soap Header version to use. This will define how you can handle session management *(e.g. support for stateless calls, requiring session pooling or not)*. -This library is initially built to support the current Soap Header v4, which is the Soap Header Version you would get for a new WSAP requested today (2016). +This library is initially built to support the current **Soap Header 4** and the legacy **Soap Header 2**. +- Soap Header 4 is the Soap Header Version you would get for a new WSAP requested today (2016). +- Soap Header 2 is still in use in legacy applications. -Legacy applications using already certified WSAP's can still be running on legacy Soap Header versions - most notably Soap Header 1 & 2. This library currently doesn't support those yet, but we plan to add that in the future. +Legacy applications using already certified WSAP's can still be running on legacy Soap Header versions (Soap Header 1 & 2). This library doesn't support Soap Header 1 at the moment. ****************************************** Support for different versions of messages @@ -52,6 +54,8 @@ Install the client library in your PHP project by requiring the package with Com Set up a test client ******************** +Soap Header 4 example: + .. code-block:: php 'ABC123']) ); +Soap Header 2 example: + +.. code-block:: php + + [ + 'soapHeaderVersion' => Client::HEADER_V2, + 'wsdl' => '/home/user/mytestproject/data/amadeuswsdl/1ASIWXXXXXX_PDT_20110101_080000.wsdl', //Points to the location of the WSDL file for your WSAP. Make sure the associated XSD's are also available. + 'logger' => new Psr\Log\NullLogger(), + 'authParams' => [ + 'officeId' => 'BRUXX1111', //The Amadeus Office Id you want to sign in to - must be open on your WSAP. + 'userId' => 'WSBENXXX', //Also known as 'Originator' for Soap Header 1 & 2 WSDL's + 'passwordData' => 'dGhlIHBhc3N3b3Jk' // **base 64 encoded** password + 'passwordLength => 12, + 'dutyCode' => 'SU', + 'organizationId' => 'DUMMY-ORG', + ] + ], + 'requestCreatorParams' => [ + 'receivedFrom' => 'my test project' // The "Received From" string that will be visible in PNR History + ] + ]); + + $client = new Client($params); + + $authResult = $client->securityAuthenticate(); + + if (isset($authResult->processStatus->statusCode) && $authResult->processStatus->statusCode === 'P') { + //We are authenticated! + $pnrContent = $client->pnrRetrieve( + new PnrRetrieveOptions(['recordLocator' => 'ABC123']) + ); + } + ****************** Messages supported @@ -92,6 +138,7 @@ Messages supported This is the list of messages that are at least partially supported at this time: +- Security_Authenticate - Security_SignOut - PNR_Retrieve - PNR_RetrieveAndDisplay @@ -135,5 +182,3 @@ On the to-do list / work in progress: - Ticket_DisplayTST - Ticket_DeleteTST - SalesReports_DisplayQueryReport - -- Support for SoapHeader V2 diff --git a/docs/samples.rst b/docs/samples.rst index 57f6ebeb6..6dfdca935 100644 --- a/docs/samples.rst +++ b/docs/samples.rst @@ -59,6 +59,29 @@ After doing multiple calls with a stateful session, there are two ways to end th ['endSession' => true] ); +************************************ +Handling sessions with Soap Header 2 +************************************ + +Soap Header 2 based applications are a bit more cumbersome to handle in order to get a successful certification: +- you need to implement session pooling in order to limit the number of session creation/destruction events +- you need to enforce your maximum number of concurrent sessions +- you need to send a separate authentication message before you can do anything + +This library does not provide any session pooling mechanism, you'll have to implement this yourself. + +You can get a current session's info (for later re-use) by calling + +.. code-block:: php + + $client->getSessionData(); + +You can restore a previous current session after you retrieved it from your session pool for later re-use: + +.. code-block:: php + + $client->setSessionData($previousSessionData); + ********************* Handling the response diff --git a/src/Amadeus/Client.php b/src/Amadeus/Client.php index 19649c833..e06901cae 100644 --- a/src/Amadeus/Client.php +++ b/src/Amadeus/Client.php @@ -36,8 +36,7 @@ * Amadeus Web Service Client. * * TODO: - * - have a solution for session pooling for stateful sessions (soapheader 1 & 2) - * - support older versions of SoapHeader (1, 2) + * - support older versions of SoapHeader (1) * - implement calls for full online booking flow: * SalesReports_DisplayQueryReport * Air_MultiAvailability @@ -142,6 +141,19 @@ public function getLastResponse() return $this->sessionHandler->getLastResponse(); } + /** + * Restore a previously used session + * + * To be used when implementing your own session pooling system on legacy Soap Header 2 applications. + * + * @param array $sessionData + * @return bool + */ + public function setSessionData(array $sessionData) + { + return $this->sessionHandler->setSessionData($sessionData); + } + /** * Construct Amadeus Web Services client * diff --git a/src/Amadeus/Client/Struct/SessionHeaderV2.php b/src/Amadeus/Client/Struct/SessionHeaderV2.php deleted file mode 100644 index 15e2f28ec..000000000 --- a/src/Amadeus/Client/Struct/SessionHeaderV2.php +++ /dev/null @@ -1,35 +0,0 @@ - - */ -class SessionHeaderV2 -{ - //TODO -} diff --git a/tests/Amadeus/ClientTest.php b/tests/Amadeus/ClientTest.php index ddb0d0248..95ea4eec1 100644 --- a/tests/Amadeus/ClientTest.php +++ b/tests/Amadeus/ClientTest.php @@ -1406,6 +1406,36 @@ public function testCanDoAuthenticateCall() $this->assertEquals($messageResult, $response); } + public function testCanSetSessionData() + { + $mockSessionHandler = $this->getMockBuilder('Amadeus\Client\Session\Handler\HandlerInterface')->getMock(); + + $dummySessionData = [ + 'sessionId' => 'XFHZEKLRZHREJ', + 'sequenceNumber' => 12, + 'securityToken' => 'RKLERJEZLKRHZEJKLRHEZJKLREZRHEZK' + ]; + + $mockSessionHandler + ->expects($this->once()) + ->method('setSessionData') + ->with($dummySessionData) + ->will($this->returnValue(true)); + + $par = new Params(); + $par->sessionHandler = $mockSessionHandler; + $par->requestCreatorParams = new Params\RequestCreatorParams([ + 'receivedFrom' => 'some RF string', + 'originatorOfficeId' => 'BRUXXXXXX' + ]); + + $client = new Client($par); + + $result = $client->setSessionData($dummySessionData); + + $this->assertTrue($result); + } + public function dataProviderMakeMessageOptions() From be654c3c7bdbbb8bfa1d29103059e6f91edabbea Mon Sep 17 00:00:00 2001 From: Dieter Devlieghere Date: Thu, 31 Mar 2016 00:18:43 +0200 Subject: [PATCH 08/12] back to 100% coverage on Client --- tests/Amadeus/ClientTest.php | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/Amadeus/ClientTest.php b/tests/Amadeus/ClientTest.php index 95ea4eec1..2571cee5b 100644 --- a/tests/Amadeus/ClientTest.php +++ b/tests/Amadeus/ClientTest.php @@ -74,6 +74,29 @@ public function testCanCreateClientWithOverriddenSessionHandlerRequestCreatorAnd $this->assertInstanceOf('Amadeus\Client', $client); } + public function testCanCreateClientWithAuthOptionsAndSessionParams() + { + $par = new Params([ + 'authParams' => [ + 'officeId' => 'BRUXXXXXX', + 'originatorTypeCode' => 'U', + 'userId' => 'WSXXXXXX', + 'passwordData' => base64_encode('TEST') + ], + 'sessionHandlerParams' => [ + 'wsdl' => $this->makePathToDummyWSDL(), + 'stateful' => true, + 'logger' => new NullLogger() + ], + 'requestCreatorParams' => [ + 'receivedFrom' => 'some RF string' + ] + ]); + + $client = new Client($par); + + $this->assertTrue($client->isStateful()); + } /** * @dataProvider dataProviderMakeMessageOptions From ccc51ad3f05e3a7a7d81399395d5df9b2048d8cc Mon Sep 17 00:00:00 2001 From: Dieter Devlieghere Date: Thu, 31 Mar 2016 00:20:59 +0200 Subject: [PATCH 09/12] Fixed some words in the docs regarding Soap Header 2 --- docs/about-get-started.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/about-get-started.rst b/docs/about-get-started.rst index ccd31cbe4..346996fc0 100644 --- a/docs/about-get-started.rst +++ b/docs/about-get-started.rst @@ -11,7 +11,7 @@ See `the Amadeus Web Services website `_ for m The basic pieces of information you will need to use this library are: - **The WSDL file with all its includes**: You can just extract the ZIP file you received from Amadeus to a location on your filesystem where the client can access it. -- **The authentication information required to start a session**: Office ID's, User Id (=Originator), Password, Duty Code. *For legacy WSAP's using Soap Header 1 or 2, you'll need: Office ID, Originator, Organization ID, Password Length, Password Data. Soap Header 1 & 2 is not yet implemented in this library* +- **The authentication information required to start a session**: Office ID's, User Id (=Originator), Password, Duty Code. *For legacy WSAP's using Soap Header 1 or 2, you'll need: Office ID, Originator, Organization ID, Password Length, Password Data. Soap Header 1 is not yet implemented in this library* You usually receive this information after the project kick-off has been done and a support person has been assigned to your project. @@ -20,7 +20,8 @@ Support for Amadeus Soap Header versions **************************************** Upon receiving access, Amadeus will give you a Web Service Access Point with a specific Soap Header version to use. This will define how you can handle session management *(e.g. support for stateless calls, requiring session pooling or not)*. -This library is initially built to support the current **Soap Header 4** and the legacy **Soap Header 2**. +This library is built to support the current **Soap Header 4** and the legacy **Soap Header 2**. + - Soap Header 4 is the Soap Header Version you would get for a new WSAP requested today (2016). - Soap Header 2 is still in use in legacy applications. From 7a209dbaad6beaf70d09359065833faaea14687e Mon Sep 17 00:00:00 2001 From: Dieter Devlieghere Date: Thu, 31 Mar 2016 00:21:55 +0200 Subject: [PATCH 10/12] Fixed some words in the docs regarding Soap Header 2 --- docs/about-get-started.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/about-get-started.rst b/docs/about-get-started.rst index 346996fc0..671db84f5 100644 --- a/docs/about-get-started.rst +++ b/docs/about-get-started.rst @@ -111,7 +111,7 @@ Soap Header 2 example: 'officeId' => 'BRUXX1111', //The Amadeus Office Id you want to sign in to - must be open on your WSAP. 'userId' => 'WSBENXXX', //Also known as 'Originator' for Soap Header 1 & 2 WSDL's 'passwordData' => 'dGhlIHBhc3N3b3Jk' // **base 64 encoded** password - 'passwordLength => 12, + 'passwordLength' => 12, 'dutyCode' => 'SU', 'organizationId' => 'DUMMY-ORG', ] From 29c7b870992c257059435cc8126d1a9703c17dfe Mon Sep 17 00:00:00 2001 From: Dieter Devlieghere Date: Thu, 31 Mar 2016 00:25:30 +0200 Subject: [PATCH 11/12] Fixed some words in the docs regarding Soap Header 2 #3 --- docs/samples.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/samples.rst b/docs/samples.rst index 6dfdca935..10c072d14 100644 --- a/docs/samples.rst +++ b/docs/samples.rst @@ -4,9 +4,9 @@ EXAMPLES Here are some examples of how you can handle some problems you might encounter and how to send specific messages. -*********************************************** -Switching between stateful & stateless messages -*********************************************** +*************************************************************** +Switching between stateful & stateless messages (Soap Header 4) +*************************************************************** If you do not require an active context in your session, you're better off using stateless messages. @@ -38,9 +38,9 @@ It's also possible to specify the default stateful setting at construction time $client = new Client($params); -************************* -Ending a stateful session -************************* +***************************************** +Ending a stateful session (Soap Header 4) +***************************************** After doing multiple calls with a stateful session, there are two ways to end the session: From 50230752c04e93d353a5a8348e3479d96a90c643 Mon Sep 17 00:00:00 2001 From: Dieter Devlieghere Date: Thu, 31 Mar 2016 00:28:40 +0200 Subject: [PATCH 12/12] Fixed some words in the docs regarding Soap Header 2 #4 --- docs/samples.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/samples.rst b/docs/samples.rst index 10c072d14..cac15d1fc 100644 --- a/docs/samples.rst +++ b/docs/samples.rst @@ -64,6 +64,7 @@ Handling sessions with Soap Header 2 ************************************ Soap Header 2 based applications are a bit more cumbersome to handle in order to get a successful certification: + - you need to implement session pooling in order to limit the number of session creation/destruction events - you need to enforce your maximum number of concurrent sessions - you need to send a separate authentication message before you can do anything