From b4cb712f90cdbde042f7b3d2a326558345335529 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20DELSOL?= Date: Thu, 7 Mar 2019 09:41:37 +0100 Subject: [PATCH 1/6] issue #7 - add namespce uri when necessary and among [wssu,wsse] ensure namespace uri is added to an element if its attributes uses one and is prefixed by wsse or wssu, update PHP CS Fixer rules --- .php_cs | 12 +- src/Created.php | 9 +- src/Element.php | 247 +++++++++++++++++++++++++-------------- src/Expires.php | 11 +- src/Nonce.php | 20 +++- src/Password.php | 49 +++++--- src/Security.php | 68 ++++++----- src/Timestamp.php | 55 ++++++--- src/Username.php | 9 +- src/UsernameToken.php | 73 ++++++++---- src/WsSecurity.php | 62 ++++++---- tests/TestCase.php | 4 +- tests/WsSecurityTest.php | 18 ++- 13 files changed, 427 insertions(+), 210 deletions(-) diff --git a/.php_cs b/.php_cs index 403b036..7de65ea 100755 --- a/.php_cs +++ b/.php_cs @@ -8,6 +8,7 @@ return PhpCsFixer\Config::create() ->setUsingCache(false) ->setRules(array( '@PSR2' => true, + '@PhpCsFixer' => true, 'array_syntax' => [ 'syntax' => 'short', ], @@ -15,6 +16,15 @@ return PhpCsFixer\Config::create() 'no_whitespace_in_blank_line' => true, 'ternary_operator_spaces' => true, 'cast_spaces' => true, - 'trailing_comma_in_multiline_array' => true + 'trailing_comma_in_multiline_array' => true, + 'concat_space' => [ + 'spacing' => 'one', + ], + 'blank_line_before_statement' => [ + 'statements' => [ + 'return', + 'declare', + ], + ], )) ->setFinder($finder); diff --git a/src/Created.php b/src/Created.php index 7798786..0f597bb 100644 --- a/src/Created.php +++ b/src/Created.php @@ -5,13 +5,16 @@ class Created extends Element { /** - * Element name + * Element name. + * * @var string */ const NAME = 'Created'; + /** - * Constructor for Created element - * @param int $_timestamp the timestamp value + * Constructor for Created element. + * + * @param int $_timestamp the timestamp value * @param string $_namespace the namespace */ public function __construct($_timestamp, $_namespace = self::NS_WSSU) diff --git a/src/Element.php b/src/Element.php index 1689b71..59c8bfc 100644 --- a/src/Element.php +++ b/src/Element.php @@ -11,67 +11,80 @@ class Element { /** - * Namespace for WSSE elements + * Namespace for WSSE elements. + * * @var string */ const NS_WSSE = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'; /** - * Namespace name for WSSE elements + * Namespace name for WSSE elements. + * * @var string */ const NS_WSSE_NAME = 'wsse'; /** - * Namespace for WSSU elements + * Namespace for WSSU elements. + * * @var string */ const NS_WSSU = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'; /** - * Namespace name for WSSU elements + * Namespace name for WSSU elements. + * * @var string */ const NS_WSSU_NAME = 'wssu'; /** - * Name of the element used as the WS-Security tag + * Name of the element used as the WS-Security tag. + * * @var string */ protected $name = ''; /** * Value of the element. - * It can either be a string value or a Element object - * @var string|Element + * It can either be a string value or a Element object. + * + * @var Element|string */ protected $value = ''; /** - * Array of attributes that must contains the element + * Array of attributes that must contains the element. + * * @var array */ protected $attributes = []; /** - * The namespace the element belongs to + * The namespace the element belongs to. + * * @var string */ protected $namespace = ''; /** - * Nonce used to generate digest password + * Nonce used to generate digest password. + * * @var string */ - protected $nonceValue = null; + protected $nonceValue; /** - * Timestamp used to generate digest password + * Timestamp used to generate digest password. + * * @var int */ - protected $timestampValue = null; + protected $timestampValue; /** - * Current \DOMDocument used to generate XML content + * Current \DOMDocument used to generate XML content. + * * @var \DOMDocument */ protected static $dom = null; + /** - * Generic constructor + * Generic constructor. + * * @param string $name * @param string $namespace - * @param mixed $value - * @param array $attributes + * @param mixed $value + * @param array $attributes */ public function __construct($name, $namespace, $value = null, array $attributes = []) { @@ -79,8 +92,40 @@ public function __construct($name, $namespace, $value = null, array $attributes ->setName($name) ->setNamespace($namespace) ->setValue($value) - ->setAttributes($attributes); + ->setAttributes($attributes) + ; + } + + /** + * Method called to generate the string XML request to be sent among the SOAP Header. + * + * @param bool $asDomElement returns elements as a \DOMElement or as a string + * + * @return \DOMElement|string + */ + protected function __toSend($asDomElement = false) + { + /** + * Create element tag. + */ + $element = self::getDom()->createElement($this->getNamespacedName()); + $element->setAttributeNS('http://www.w3.org/2000/xmlns/', sprintf('xmlns:%s', $this->getNamespacePrefix()), $this->getNamespace()); + /* + * Define element value + * Add attributes if there are any + */ + $this + ->appendValueToElementToSend($this->getValue(), $element) + ->appendAttributesToElementToSend($element) + ; + // Returns element content + if ($asDomElement) { + return $element; + } + + return self::getDom()->saveXML($element); } + /** * @return string */ @@ -88,15 +133,19 @@ public function getName() { return $this->name; } + /** * @param string $name + * * @return Element */ public function setName($name) { $this->name = $name; + return $this; } + /** * @return array */ @@ -104,25 +153,32 @@ public function getAttributes() { return $this->attributes; } + /** * @param array $attributes + * * @return Element */ public function setAttributes(array $attributes) { $this->attributes = $attributes; + return $this; } + /** * @param string $name - * @param mixed $value + * @param mixed $value + * * @return Element */ public function setAttribute($name, $value) { $this->attributes[$name] = $value; + return $this; } + /** * @return bool true|false */ @@ -130,6 +186,7 @@ public function hasAttributes() { return count($this->attributes) > 0; } + /** * @return string */ @@ -137,47 +194,40 @@ public function getNamespace() { return $this->namespace; } - /** - * @return string - */ - private function getNamespacePrefix() - { - $namespacePrefix = ''; - switch ($this->getNamespace()) { - case self::NS_WSSE: - $namespacePrefix = self::NS_WSSE_NAME; - break; - case self::NS_WSSU: - $namespacePrefix = self::NS_WSSU_NAME; - break; - } - return $namespacePrefix; - } + /** * @param string $namespace + * * @return Element */ public function setNamespace($namespace) { $this->namespace = $namespace; + return $this; } + /** - * @return string|Element + * @return Element|string */ public function getValue() { return $this->value; } + /** - * @param string|Element + * @param Element|string + * @param mixed $value + * * @return Element */ public function setValue($value) { $this->value = $value; + return $this; } + /** * @return string */ @@ -185,78 +235,59 @@ public function getNonceValue() { return $this->nonceValue; } + /** * @param string $nonceValue + * * @return Element */ public function setNonceValue($nonceValue) { $this->nonceValue = $nonceValue; + return $this; } + /** + * @param mixed $formated + * * @return int|string */ public function getTimestampValue($formated = false) { return ($formated && $this->timestampValue > 0) ? gmdate('Y-m-d\TH:i:s\Z', $this->timestampValue) : $this->timestampValue; } + /** * @param int $timestampValue + * * @return Element */ public function setTimestampValue($timestampValue) { $this->timestampValue = $timestampValue; + return $this; } + /** - * @return \DOMDocument - */ - private static function getDom() - { - return self::$dom; - } - /** - * @param \DOMDocument $dom - * @return \DOMDocument - */ - private static function setDom(\DOMDocument $dom) - { - self::$dom = $dom; - } - /** - * Method called to generate the string XML request to be sent among the SOAP Header - * @param bool $asDomElement returns elements as a \DOMElement or as a string - * @return string|\DOMElement + * Returns the element to send as WS-Security header. + * + * @return string */ - protected function __toSend($asDomElement = false) + public function toSend() { - /** - * Create element tag - */ - $element = self::getDom()->createElement($this->getNamespacedName()); - $element->setAttributeNS('http://www.w3.org/2000/xmlns/', sprintf('xmlns:%s', $this->getNamespacePrefix()), $this->getNamespace()); - /** - * Define element value - * Add attributes if there are any - */ - $this - ->appendValueToElementToSend($this->getValue(), $element) - ->appendAttributesToElementToSend($element); - /** - * Returns element content - */ - if ($asDomElement) { - return $element; - } else { - return self::getDom()->saveXML($element); - } + self::setDom(new \DOMDocument('1.0', 'UTF-8')); + + return $this->__toSend(); } + /** - * Handle adding value to element according to the value type - * @param mixed $value + * Handle adding value to element according to the value type. + * + * @param mixed $value * @param \DOMElement $element + * * @return Element */ protected function appendValueToElementToSend($value, \DOMElement $element) @@ -268,10 +299,12 @@ protected function appendValueToElementToSend($value, \DOMElement $element) } elseif (!empty($value)) { $element->appendChild(self::getDom()->createTextNode($value)); } + return $this; } + /** - * @param Element $element + * @param Element $element * @param \DOMElement $element */ protected function appendElementToElementToSend(Element $value, \DOMElement $element) @@ -281,8 +314,9 @@ protected function appendElementToElementToSend(Element $value, \DOMElement $ele $element->appendChild($toSend); } } + /** - * @param array $values + * @param array $values * @param \DOMElement $element */ protected function appendValuesToElementToSend(array $values, \DOMElement $element) @@ -291,34 +325,75 @@ protected function appendValuesToElementToSend(array $values, \DOMElement $eleme $this->appendValueToElementToSend($value, $element); } } + /** * @param \DOMElement $element + * * @return Element */ protected function appendAttributesToElementToSend(\DOMElement $element) { if ($this->hasAttributes()) { foreach ($this->getAttributes() as $attributeName => $attributeValue) { - $element->setAttribute($attributeName, $attributeValue); + if (false === strpos($attributeName, ':')) { + $element->setAttribute($attributeName, $attributeValue); + } else { + list($ns, $name) = explode(':', $attributeName); + if (self::NS_WSSE_NAME === $ns || self::NS_WSSU_NAME === $ns) { + $element->setAttributeNS(self::NS_WSSE_NAME === $ns ? self::NS_WSSE : self::NS_WSSU, $attributeName, $attributeValue); + } else { + $element->setAttribute($attributeName, $attributeValue); + } + } } } + return $this; } + /** - * Returns the name with its namespace + * Returns the name with its namespace. + * * @return string */ protected function getNamespacedName() { return sprintf('%s:%s', $this->getNamespacePrefix(), $this->getName()); } + /** - * Returns the element to send as WS-Security header * @return string */ - public function toSend() + private function getNamespacePrefix() { - self::setDom(new \DOMDocument('1.0', 'UTF-8')); - return $this->__toSend(); + $namespacePrefix = ''; + switch ($this->getNamespace()) { + case self::NS_WSSE: + $namespacePrefix = self::NS_WSSE_NAME; + break; + case self::NS_WSSU: + $namespacePrefix = self::NS_WSSU_NAME; + break; + } + + return $namespacePrefix; + } + + /** + * @return \DOMDocument + */ + private static function getDom() + { + return self::$dom; + } + + /** + * @param \DOMDocument $dom + * + * @return \DOMDocument + */ + private static function setDom(\DOMDocument $dom) + { + self::$dom = $dom; } } diff --git a/src/Expires.php b/src/Expires.php index 60578d5..5c2e56f 100644 --- a/src/Expires.php +++ b/src/Expires.php @@ -5,14 +5,17 @@ class Expires extends Element { /** - * Element name + * Element name. + * * @var string */ const NAME = 'Expires'; + /** - * Constructor for Expires element - * @param int $timestamp the timestamp value - * @param int $expiresIn the expires in time + * Constructor for Expires element. + * + * @param int $timestamp the timestamp value + * @param int $expiresIn the expires in time * @param string $namespace the namespace */ public function __construct($timestamp, $expiresIn = 3600, $namespace = self::NS_WSSU) diff --git a/src/Nonce.php b/src/Nonce.php index f0d40d7..394c120 100644 --- a/src/Nonce.php +++ b/src/Nonce.php @@ -5,23 +5,28 @@ class Nonce extends Element { /** - * Element name + * Element name. + * * @var string */ const NAME = 'Nonce'; /** - * Element name + * Element name. + * * @var string */ const ATTRIBUTE_ENCODING_TYPE = 'EncodingType'; /** - * Element name + * Element name. + * * @var string */ const NS_ENCODING = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary'; + /** - * Constructor for Nonce element - * @param string $nonce the nonce value + * Constructor for Nonce element. + * + * @param string $nonce the nonce value * @param string $namespace the namespace */ public function __construct($nonce, $namespace = self::NS_WSSE) @@ -30,9 +35,12 @@ public function __construct($nonce, $namespace = self::NS_WSSE) self::ATTRIBUTE_ENCODING_TYPE => self::NS_ENCODING, ]); } + /** - * Encode Nonce value + * Encode Nonce value. + * * @param string $nonce + * * @return string */ public static function encodeNonce($nonce) diff --git a/src/Password.php b/src/Password.php index 75fbdf2..9e42557 100644 --- a/src/Password.php +++ b/src/Password.php @@ -3,66 +3,80 @@ namespace WsdlToPhp\WsSecurity; /** - * Class that represents the Password element + * Class that represents the Password element. + * * @author WsdlToPhp Team */ class Password extends Element { /** - * Element name + * Element name. + * * @var string */ const NAME = 'Password'; /** - * Element attribute type name + * Element attribute type name. + * * @var string */ const ATTRIBUTE_TYPE = 'Type'; /** - * Passwor must be sent using digest + * Passwor must be sent using digest. + * * @var string */ const TYPE_PASSWORD_DIGEST = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest'; /** - * Passwor must be sent in text + * Passwor must be sent in text. + * * @var string */ const TYPE_PASSWORD_TEXT = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText'; /** - * TypeValue of password + * TypeValue of password. + * * @var string */ - protected $typeValue = null; + protected $typeValue; + /** - * Constructor for Password element - * @param string $password the password - * @param string $typeValue the typeValue + * Constructor for Password element. + * + * @param string $password the password + * @param string $typeValue the typeValue * @param string $timestampValue the timestamp to use - * @param string $namespace the namespace + * @param string $namespace the namespace */ public function __construct($password, $typeValue = self::TYPE_PASSWORD_TEXT, $timestampValue = 0, $namespace = self::NS_WSSE) { $this ->setTypeValue($typeValue) ->setTimestampValue($timestampValue ? $timestampValue : time()) - ->setNonceValue(mt_rand()); + ->setNonceValue(mt_rand()) + ; parent::__construct(self::NAME, $namespace, $this->convertPassword($password), [ self::ATTRIBUTE_TYPE => $typeValue, ]); } + /** - * Returns the converted form of the password accroding to the password typeValue + * Returns the converted form of the password accroding to the password typeValue. + * * @param string $password */ public function convertPassword($password) { - if ($this->getTypeValue() === self::TYPE_PASSWORD_DIGEST) { + if (self::TYPE_PASSWORD_DIGEST === $this->getTypeValue()) { $password = $this->digestPassword($password); } + return $password; } + /** - * When generating the password digest, we define values (nonce and timestamp) that can be used in other place + * When generating the password digest, we define values (nonce and timestamp) that can be used in other place. + * * @param string $password */ public function digestPassword($password) @@ -72,8 +86,10 @@ public function digestPassword($password) $packedPassword = pack('a*', $password); $hash = sha1($packedNonce . $packedTimestamp . $packedPassword); $packedHash = pack('H*', $hash); + return base64_encode($packedHash); } + /** * @return string */ @@ -81,13 +97,16 @@ public function getTypeValue() { return $this->typeValue; } + /** * @param string $typeValue + * * @return Password */ public function setTypeValue($typeValue) { $this->typeValue = $typeValue; + return $this; } } diff --git a/src/Security.php b/src/Security.php index 3b7e657..db00404 100644 --- a/src/Security.php +++ b/src/Security.php @@ -5,57 +5,79 @@ class Security extends Element { /** - * Element name + * Element name. + * * @var string */ const NAME = 'Security'; /** - * Element attribute mustunderstand name + * Element attribute mustunderstand name. + * * @var string */ const ATTRIBUTE_MUST_UNDERSTAND = ':mustunderstand'; /** - * Element attribute mustunderstand name + * Element attribute mustunderstand name. + * * @var string */ const ATTRIBUTE_ACTOR = ':actor'; /** - * Envelop namespace + * Envelop namespace. + * * @var string */ const ENV_NAMESPACE = 'SOAP-ENV'; /** - * UsernameToken element + * UsernameToken element. + * * @var UsernameToken */ protected $usernameToken; /** - * Timestamp element + * Timestamp element. + * * @var Timestamp */ protected $timestamp; /** - * Constructor for Nonce element + * Constructor for Nonce element. * * @param bool $mustunderstand * @param string $actor * @param string $envelopeNamespace - * @param string $namespace the namespace + * @param string $namespace the namespace */ public function __construct($mustunderstand = false, $actor = null, $namespace = self::NS_WSSE, $envelopeNamespace = self::ENV_NAMESPACE) { parent::__construct(self::NAME, $namespace); - /** - * Sets attributes - */ - if ($mustunderstand === true) { - $this->setAttribute($envelopeNamespace. self::ATTRIBUTE_MUST_UNDERSTAND, $mustunderstand); + // Sets attributes + if (true === $mustunderstand) { + $this->setAttribute($envelopeNamespace . self::ATTRIBUTE_MUST_UNDERSTAND, $mustunderstand); } if (!empty($actor)) { $this->setAttribute($envelopeNamespace . self::ATTRIBUTE_ACTOR, $actor); } } + + /** + * Overrides methods in order to set the values. + * + * @param bool $asDomElement returns elements as a DOMElement or as a string + * + * @return \DOMElement|string + */ + protected function __toSend($asDomElement = false) + { + $this->setValue([ + $this->getUsernameToken(), + $this->getTimestamp(), + ]); + + return parent::__toSend($asDomElement); + } + /** * @return UsernameToken */ @@ -63,15 +85,19 @@ public function getUsernameToken() { return $this->usernameToken; } + /** * @param UsernameToken $usernameToken + * * @return Security */ public function setUsernameToken(UsernameToken $usernameToken) { $this->usernameToken = $usernameToken; + return $this; } + /** * @return Timestamp */ @@ -79,26 +105,16 @@ public function getTimestamp() { return $this->timestamp; } + /** * @param Timestamp $timestamp + * * @return Security */ public function setTimestamp(Timestamp $timestamp) { $this->timestamp = $timestamp; + return $this; } - /** - * Overrides methods in order to set the values - * @param bool $asDomElement returns elements as a DOMElement or as a string - * @return string|\DOMElement - */ - protected function __toSend($asDomElement = false) - { - $this->setValue([ - $this->getUsernameToken(), - $this->getTimestamp(), - ]); - return parent::__toSend($asDomElement); - } } diff --git a/src/Timestamp.php b/src/Timestamp.php index 4591228..9cad401 100644 --- a/src/Timestamp.php +++ b/src/Timestamp.php @@ -5,28 +5,51 @@ class Timestamp extends Element { /** - * Element name + * Element name. + * * @var string */ const NAME = 'Timestamp'; /** - * Created element + * Created element. + * * @var Created */ - protected $created = null; + protected $created; /** - * Created element + * Created element. + * * @var Expires */ - protected $expires = null; + protected $expires; + /** - * Constructor for Timestamp element + * Constructor for Timestamp element. + * * @param string $namespace the namespace */ public function __construct($namespace = self::NS_WSSU) { parent::__construct(self::NAME, $namespace); } + + /** + * Overrides method in order to add created and expires values if they are set. + * + * @param bool $asDomElement returns elements as a DOMElement or as a string + * + * @return string + */ + protected function __toSend($asDomElement = false) + { + $this->setValue([ + $this->getCreated(), + $this->getExpires(), + ]); + + return parent::__toSend($asDomElement); + } + /** * @return Created */ @@ -34,15 +57,19 @@ public function getCreated() { return $this->created; } + /** * @param Created $created + * * @return Timestamp */ public function setCreated(Created $created) { $this->created = $created; + return $this; } + /** * @return Expires */ @@ -50,26 +77,16 @@ public function getExpires() { return $this->expires; } + /** * @param Expires $expires + * * @return Expires */ public function setExpires(Expires $expires) { $this->expires = $expires; + return $this; } - /** - * Overrides method in order to add created and expires values if they are set - * @param bool $asDomElement returns elements as a DOMElement or as a string - * @return string - */ - protected function __toSend($asDomElement = false) - { - $this->setValue([ - $this->getCreated(), - $this->getExpires(), - ]); - return parent::__toSend($asDomElement); - } } diff --git a/src/Username.php b/src/Username.php index 792ceac..637ffe0 100644 --- a/src/Username.php +++ b/src/Username.php @@ -5,13 +5,16 @@ class Username extends Element { /** - * Element name + * Element name. + * * @var string */ const NAME = 'Username'; + /** - * Constructor for Username element - * @param string $username the username + * Constructor for Username element. + * + * @param string $username the username * @param string $namespace the namespace */ public function __construct($username, $namespace = self::NS_WSSE) diff --git a/src/UsernameToken.php b/src/UsernameToken.php index f4a5675..bb1306d 100644 --- a/src/UsernameToken.php +++ b/src/UsernameToken.php @@ -5,38 +5,47 @@ class UsernameToken extends Element { /** - * Element name + * Element name. + * * @var string */ const NAME = 'UsernameToken'; /** - * Attribute id name + * Attribute id name. + * * @var string */ const ATTRIBUTE_ID = 'Id'; /** - * Username element + * Username element. + * * @var Username */ protected $username; /** - * Password element + * Password element. + * * @var Password */ protected $password; /** - * Created element + * Created element. + * * @var Created */ protected $created; /** - * Nonce element + * Nonce element. + * * @var Nonce */ protected $nonce; + /** - * Constructor for UsernameToken element + * Constructor for UsernameToken element. + * * @see Element::__construct() + * * @param string $id * @param string $namespace the namespace */ @@ -46,6 +55,26 @@ public function __construct($id = null, $namespace = self::NS_WSSE) sprintf('%s:%s', parent::NS_WSSU_NAME, self::ATTRIBUTE_ID) => $id, ]); } + + /** + * Overrides method in order to add username, password and created values if they are set. + * + * @param bool $asDomElement returns elements as a DOMElement or as a string + * + * @return string + */ + protected function __toSend($asDomElement = false) + { + $this->setValue([ + $this->getUsername(), + $this->getPassword(), + $this->getCreated(), + $this->getNonce(), + ]); + + return parent::__toSend($asDomElement); + } + /** * @return Username */ @@ -53,15 +82,19 @@ public function getUsername() { return $this->username; } + /** * @param Username $username + * * @return UsernameToken */ public function setUsername(Username $username) { $this->username = $username; + return $this; } + /** * @return Password */ @@ -69,15 +102,19 @@ public function getPassword() { return $this->password; } + /** * @param Password $password + * * @return UsernameToken */ public function setPassword($password) { $this->password = $password; + return $this; } + /** * @return Created */ @@ -85,15 +122,19 @@ public function getCreated() { return $this->created; } + /** * @param Created $created + * * @return UsernameToken */ public function setCreated($created) { $this->created = $created; + return $this; } + /** * @return Nonce */ @@ -101,28 +142,16 @@ public function getNonce() { return $this->nonce; } + /** * @param Nonce $nonce + * * @return UsernameToken */ public function setNonce($nonce) { $this->nonce = $nonce; + return $this; } - /** - * Overrides method in order to add username, password and created values if they are set - * @param bool $asDomElement returns elements as a DOMElement or as a string - * @return string - */ - protected function __toSend($asDomElement = false) - { - $this->setValue([ - $this->getUsername(), - $this->getPassword(), - $this->getCreated(), - $this->getNonce(), - ]); - return parent::__toSend($asDomElement); - } } diff --git a/src/WsSecurity.php b/src/WsSecurity.php index 200219c..4bef307 100644 --- a/src/WsSecurity.php +++ b/src/WsSecurity.php @@ -39,21 +39,10 @@ protected function __construct( ->setPassword($password, $passwordDigest, $addCreated) ->setNonce($addNonce) ->setCreated($addCreated) - ->setTimestamp($addCreated, $addExpires); + ->setTimestamp($addCreated, $addExpires) + ; } - /** - * @param bool $mustunderstand - * @param string $actor - * @param string $envelopeNamespace - * - * @return WsSecurity - */ - protected function initSecurity($mustunderstand = false, $actor = null, $envelopeNamespace = Security::ENV_NAMESPACE) - { - $this->security = new Security($mustunderstand, $actor, Security::NS_WSSE, $envelopeNamespace); - return $this; - } /** * @return Security */ @@ -96,16 +85,32 @@ public static function createWsSecuritySoapHeader( if ($returnSoapHeader) { if (!empty($actor)) { return new \SoapHeader(Element::NS_WSSE, 'Security', new \SoapVar($self->getSecurity()->toSend(), XSD_ANYXML), $mustunderstand, $actor); - } else { - return new \SoapHeader(Element::NS_WSSE, 'Security', new \SoapVar($self->getSecurity()->toSend(), XSD_ANYXML), $mustunderstand); } - } else { - return new \SoapVar($self->getSecurity()->toSend(), XSD_ANYXML); + + return new \SoapHeader(Element::NS_WSSE, 'Security', new \SoapVar($self->getSecurity()->toSend(), XSD_ANYXML), $mustunderstand); } + + return new \SoapVar($self->getSecurity()->toSend(), XSD_ANYXML); + } + + /** + * @param bool $mustunderstand + * @param string $actor + * @param string $envelopeNamespace + * + * @return WsSecurity + */ + protected function initSecurity($mustunderstand = false, $actor = null, $envelopeNamespace = Security::ENV_NAMESPACE) + { + $this->security = new Security($mustunderstand, $actor, Security::NS_WSSE, $envelopeNamespace); + + return $this; } + /** * @param string $username * @param string $usernameId + * * @return WsSecurity */ protected function setUsernameToken($username, $usernameId = null) @@ -113,21 +118,27 @@ protected function setUsernameToken($username, $usernameId = null) $usernameToken = new UsernameToken($usernameId); $usernameToken->setUsername(new Username($username)); $this->security->setUsernameToken($usernameToken); + return $this; } + /** * @param string $password - * @param bool $passwordDigest - * @param int $addCreated + * @param bool $passwordDigest + * @param int $addCreated + * * @return WsSecurity */ protected function setPassword($password, $passwordDigest = false, $addCreated = 0) { $this->getUsernameToken()->setPassword(new Password($password, $passwordDigest ? Password::TYPE_PASSWORD_DIGEST : Password::TYPE_PASSWORD_TEXT, is_bool($addCreated) ? 0 : ($addCreated > 0 ? $addCreated : 0))); + return $this; } + /** - * @param bool $addNonce + * @param bool $addNonce + * * @return WsSecurity */ protected function setNonce($addNonce) @@ -138,24 +149,30 @@ protected function setNonce($addNonce) $this->getUsernameToken()->setNonce(new Nonce($nonceValue)); } } + return $this; } + /** * @param int $addCreated + * * @return WsSecurity */ protected function setCreated($addCreated) { $passwordDigest = $this->getPassword()->getTypeValue(); $timestampValue = $this->getPassword()->getTimestampValue(); - if (($addCreated || $passwordDigest === Password::TYPE_PASSWORD_DIGEST) && $timestampValue > 0) { + if (($addCreated || Password::TYPE_PASSWORD_DIGEST === $passwordDigest) && $timestampValue > 0) { $this->getUsernameToken()->setCreated(new Created($timestampValue)); } + return $this; } + /** * @param int $addCreated * @param int $addExpires + * * @return WsSecurity */ protected function setTimestamp($addCreated = 0, $addExpires = 0) @@ -167,8 +184,10 @@ protected function setTimestamp($addCreated = 0, $addExpires = 0) $timestamp->setExpires(new Expires($timestampValue, $addExpires)); $this->security->setTimestamp($timestamp); } + return $this; } + /** * @return UsernameToken */ @@ -176,6 +195,7 @@ protected function getUsernameToken() { return $this->security->getUsernameToken(); } + /** * @return Password */ diff --git a/tests/TestCase.php b/tests/TestCase.php index 5faf2c8..738443f 100755 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -1,4 +1,5 @@ 0, $string); + return parent::assertRegExp(sprintf('/%s/', str_replace('/', '\/', $pattern)), $string); } } diff --git a/tests/WsSecurityTest.php b/tests/WsSecurityTest.php index 5678e54..5f2639e 100755 --- a/tests/WsSecurityTest.php +++ b/tests/WsSecurityTest.php @@ -1,9 +1,14 @@ '), $header->data->enc_value); } + public function testCreateWithoutExpiresIn() { $header = WsSecurity::createWsSecuritySoapHeader('foo', 'bar', false, 1459451824); @@ -38,6 +44,7 @@ public function testCreateWithoutExpiresIn() '), $header->data->enc_value); } + public function testCreateWithMustUnderstand() { $header = WsSecurity::createWsSecuritySoapHeader('foo', 'bar', false, 1459451824, 0, true, true); @@ -52,6 +59,7 @@ public function testCreateWithMustUnderstand() '), $header->data->enc_value); } + public function testCreateWithMustUnderstandAndActor() { $header = WsSecurity::createWsSecuritySoapHeader('foo', 'bar', false, 1459451824, 0, true, true, 'BAR'); @@ -66,6 +74,7 @@ public function testCreateWithMustUnderstandAndActor() '), $header->data->enc_value); } + public function testCreateSoapVar() { $header = WsSecurity::createWsSecuritySoapHeader('foo', 'bar', false, 1459451824, 0, false, true, 'BAR'); @@ -80,6 +89,7 @@ public function testCreateSoapVar() '), $header->enc_value); } + public function testCreateWithPasswordDigest() { $header = WsSecurity::createWsSecuritySoapHeader('foo', 'bar', true, 1459451824, 0, false, true, 'BAR'); @@ -94,13 +104,14 @@ public function testCreateWithPasswordDigest() '), $header->enc_value); } + public function testCreateWithUsernameId() { $header = WsSecurity::createWsSecuritySoapHeader('foo', 'bar', false, 1459451824, 0, true, true, 'BAR', 'X90I3u8'); $this->assertInstanceOf('\SoapHeader', $header); $this->assertMatches(self::innerTrim(' - + foo bar 2016-03-31T19:17:04Z @@ -108,13 +119,14 @@ public function testCreateWithUsernameId() '), $header->data->enc_value); } + public function testCreateWithoutNonce() { $header = WsSecurity::createWsSecuritySoapHeader('foo', 'bar', false, 1459451824, 0, true, true, 'BAR', 'X90I3u8', false); $this->assertInstanceOf('\SoapHeader', $header); $this->assertMatches(self::innerTrim(' - + foo bar 2016-03-31T19:17:04Z From bcdf28481009b5fed92e7196ed249c73add2c438 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20DELSOL?= Date: Thu, 7 Mar 2019 09:47:25 +0100 Subject: [PATCH 2/6] fix minor insights --- .gitignore | 1 - docker-compose.yml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index a5f714a..c49a5d8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ vendor/ composer.lock phpunit.xml -.idea \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 58d917e..b6975ab 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,4 +7,4 @@ services: dockerfile: .docker/Dockerfile volumes: - .:/var/www/html:rw - container_name: ws_security \ No newline at end of file + container_name: ws_security From ac92bc95f1a27c60b133864e40b8b36379ca3042 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20DELSOL?= Date: Thu, 7 Mar 2019 09:53:36 +0100 Subject: [PATCH 3/6] issue #7 - fix unit test, remove useless Travis commans --- .travis.yml | 3 --- tests/WsSecurityTest.php | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5155480..5bf4cd7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,9 +10,6 @@ php: - 7.1 - 7.2 -before_install: - - composer self-update - install: - composer install diff --git a/tests/WsSecurityTest.php b/tests/WsSecurityTest.php index 5f2639e..fb49428 100755 --- a/tests/WsSecurityTest.php +++ b/tests/WsSecurityTest.php @@ -5,7 +5,7 @@ use WsdlToPhp\WsSecurity\WsSecurity; /** - * @covers \WsSecurity creations + * @covers \WsdlToPhp\WsSecurity\WsSecurity * * @internal */ From 9d75a723c7c0171f719b283f07d9b468d4308969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20DELSOL?= Date: Thu, 7 Mar 2019 09:56:47 +0100 Subject: [PATCH 4/6] issue #7 - remove unused variable --- src/Element.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Element.php b/src/Element.php index 59c8bfc..d712111 100644 --- a/src/Element.php +++ b/src/Element.php @@ -338,7 +338,7 @@ protected function appendAttributesToElementToSend(\DOMElement $element) if (false === strpos($attributeName, ':')) { $element->setAttribute($attributeName, $attributeValue); } else { - list($ns, $name) = explode(':', $attributeName); + list($ns) = explode(':', $attributeName); if (self::NS_WSSE_NAME === $ns || self::NS_WSSU_NAME === $ns) { $element->setAttributeNS(self::NS_WSSE_NAME === $ns ? self::NS_WSSE : self::NS_WSSU, $attributeName, $attributeValue); } else { From 1ff64b039249a0dc30315b4a03b5996c7e8d46a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20DELSOL?= Date: Thu, 7 Mar 2019 10:03:42 +0100 Subject: [PATCH 5/6] review PHP CS fixer for tests --- .php_cs | 1 + tests/WsSecurityTest.php | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.php_cs b/.php_cs index 7de65ea..ff7c6b0 100755 --- a/.php_cs +++ b/.php_cs @@ -26,5 +26,6 @@ return PhpCsFixer\Config::create() 'declare', ], ], + 'php_unit_test_class_requires_covers' => false, )) ->setFinder($finder); diff --git a/tests/WsSecurityTest.php b/tests/WsSecurityTest.php index fb49428..3b95a22 100755 --- a/tests/WsSecurityTest.php +++ b/tests/WsSecurityTest.php @@ -5,11 +5,9 @@ use WsdlToPhp\WsSecurity\WsSecurity; /** - * @covers \WsdlToPhp\WsSecurity\WsSecurity - * * @internal */ -class WsSecurityTest extends TestCase +final class WsSecurityTest extends TestCase { public function testCreateWithExpiresIn() { From c1a8e787e67f30cfe0609a18e78e1b6edcfdc7dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20DELSOL?= Date: Thu, 7 Mar 2019 10:11:11 +0100 Subject: [PATCH 6/6] issue #7 - refactor attribute namespace detection and usage try to improve Scrutinizer note :) --- src/Element.php | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/Element.php b/src/Element.php index d712111..ca74ba8 100644 --- a/src/Element.php +++ b/src/Element.php @@ -335,15 +335,11 @@ protected function appendAttributesToElementToSend(\DOMElement $element) { if ($this->hasAttributes()) { foreach ($this->getAttributes() as $attributeName => $attributeValue) { - if (false === strpos($attributeName, ':')) { + $matches = []; + if (0 === preg_match(sprintf('/(%s|%s):/', self::NS_WSSU_NAME, self::NS_WSSE_NAME), $attributeName, $matches)) { $element->setAttribute($attributeName, $attributeValue); } else { - list($ns) = explode(':', $attributeName); - if (self::NS_WSSE_NAME === $ns || self::NS_WSSU_NAME === $ns) { - $element->setAttributeNS(self::NS_WSSE_NAME === $ns ? self::NS_WSSE : self::NS_WSSU, $attributeName, $attributeValue); - } else { - $element->setAttribute($attributeName, $attributeValue); - } + $element->setAttributeNS(self::NS_WSSE_NAME === $matches[1] ? self::NS_WSSE : self::NS_WSSU, $attributeName, $attributeValue); } } }