diff --git a/.github/workflows/php-package.yml b/.github/workflows/php-package.yml index ea1b48bb..15db0165 100644 --- a/.github/workflows/php-package.yml +++ b/.github/workflows/php-package.yml @@ -51,7 +51,7 @@ jobs: php vendor/bin/pdepend --summary-xml=tests/build/logs/dependence-summary.xml --jdepend-chart=tests/build/dependences/jdepend.svg --overview-pyramid=tests/build/dependences/pyramid.svg lib/. - name: PHP Code Sniffer - run: php vendor/bin/phpcs --standard=tests/ZendModStandard lib/Saml2 demo1 demo2 demo-old endpoints tests/src + run: php vendor/bin/phpcs --standard=tests/ZendModStandard lib/Saml2 demo1 demo2 endpoints tests/src - name: Run unit tests run: vendor/bin/phpunit --verbose --debug diff --git a/README.md b/README.md index b17ec61d..053bbfa0 100644 --- a/README.md +++ b/README.md @@ -136,25 +136,6 @@ and settings file stored at `vendor/onelogin/php-saml`. Your settings are at risk of being deleted when updating packages using `composer update` or similar commands. So it is **highly** recommended that instead of using settings files, you pass the settings as an array directly to the constructor (explained later in this document). If you do not use this approach your settings are at risk of being deleted when updating packages using `composer update` or similar commands. -Compatibility -------------- - -This 2.0 version has a new library. The toolkit is still compatible. - -The old code that you used in order to add SAML support will continue working -with minor changes. You only need to load the files of the `lib/Saml` folder. -(notice that the `compatibility.php` file do that). - -The old-demo folder contains code from an old app that uses the old version of -the toolkit (v.1). Take a look. - -Sometimes the names of the classes of the old code could be a bit different -and if that is your case you must change them for `OneLogin_Saml_Settings`, -`OneLogin_Saml_Response`, `OneLogin_Saml_AuthRequest` or `OneLogin_Saml_Metadata`. - -We recommend that you migrate the old code to the new one to be able to use -the new features that the new library Saml2 carries. - Namespaces ---------- @@ -248,10 +229,6 @@ handle the sign and the encryption of xml elements. #### `lib/` #### This folder contains the heart of the toolkit, the libraries: - - * `Saml` folder contains a modified version of the toolkit v.1 and allows the - old code to keep working. (This library is provided to maintain - backward compatibility). * `Saml2` folder contains the new version of the classes and methods that are described in a later section. @@ -290,8 +267,6 @@ and support multiple languages. advanced_settings.php file which contains extra configuration info related to the security, the contact person, and the organization associated to the SP. * `_toolkit_loader.php` - This file load the toolkit libraries (The SAML2 lib). -* `compatibility` - Import that file to make compatible your old code with the - new toolkit (loads the SAML library). #### Miscellaneous #### @@ -300,8 +275,6 @@ and support multiple languages. * `demo1/` - Contains an example of a simple PHP app with SAML support. Read the `Readme.txt` inside for more info. * `demo2/` - Contains another example. -* `demo-old/` - Contains an example that uses the code of the older version of the - the toolkit to demonstrate the backwards compatibility. ### How it works ### @@ -667,10 +640,6 @@ require_once(TOOLKIT_PATH . '_toolkit_loader.php'); After that line we will be able to use the classes (and their methods) of the toolkit (because the external and the Saml2 libraries files are loaded). -If you wrote the code of your SAML app for the version 1 of the PHP-SAML toolkit -you will need to load the `compatibility.php`, file which loads the SAML library files, -in addition to the the `_toolkit_loader.php`. - That SAML library uses the new classes and methods of the latest version of the toolkits but maintain the old classes, methods, and workflow of the old process to accomplish the same things. @@ -1299,48 +1268,6 @@ Get the ID of the last processed message/assertion with the `getLastMessageId/ge Described below are the main classes and methods that can be invoked. -#### The Old Saml library #### - -Lets start describing the classes and methods of the SAML library, an evolution -of the old v.1 toolkit that is provided to keep the backward compability. -Most of them use classes and methods of the new SAML2 library. - -##### OneLogin_Saml_AuthRequest - `AuthRequest.php` ##### - -Has the protected attribute `$auth`, an `OneLogin_Saml2_Auth` object. - -* `OneLogin_Saml_AuthRequest` - Constructs `OneLogin_Saml2_Auth`, - initializing the SP SAML instance. -* `getRedirectUrl($returnTo)` - Obtains the SSO URL containing the AuthRequest - message deflated. - - -##### OneLogin_Saml_Response - `Response.php` ##### - -* `OneLogin_Saml_Response` - Constructor that process the SAML Response, - Internally initializes an SP SAML instance and an `OneLogin_Saml2_Response`. -* `get_saml_attributes` - Retrieves an Array with the logged user data. - - -##### OneLogin_Saml_Settings - `Settings.php` ##### - -A simple class used to build the Setting object used in the v1.0 of the toolkit. - -##### OneLogin_Saml_Metadata - `Metadata.php` ##### - -* `OneLogin_Saml_Metadata` - Constructor that build the Metadata XML info based - on the settings of the SP -* `getXml` - An XML with the metadata info of the SP - - -##### OneLogin_Saml_XmlSec - `XmlSec.php` ##### - -Auxiliary class that contains methods to validate the SAML Response: -`validateNumAssertions`, `validateTimestamps`, `isValid` (which -uses the other two previous methods and also validate the signature of -SAML Response). - - #### Saml2 library #### Lets describe now the classes and methods of the SAML2 library. @@ -1701,44 +1628,3 @@ demo1, only changes the targets. to the IdP (to the SLS endpoint of the IdP).The IdP receives the Logout Response, process it and close the session at of the IdP. Notice that the SLO Workflow starts and ends at the IdP. - - -## Demo Old ## - -### SP setup ### - -This demo uses the old style of the version 1 of the toolkit. -An object of the class `OneLogin_Saml_Settings` must be provided to the -constructor of the `AuthRequest`. - -You will find an `example_settings.php` file at the demo-old's folder that -could be used as a template for your `settings.php` file. - -In that template, SAML settings are divided into two parts, the application -specific (`const_assertion_consumer_service_url`, `const_issuer`, -`const_name_identifier_format`) and the user/account specific -`idp_sso_target_url`, `x509certificate`). You'll need to add your own code here -to identify the user or user origin (e.g. by `subdomain`, `ip_address` etc.). - - -### IdP setup ### - -Once the SP is configured, the metadata of the SP is published at the -`metadata.php` file. After that, configure the IdP based on that information. - - -### How it works ### - -At the `metadata.php` view is published the metadata of the SP. - -The `index.php` file acts as an initiater for the SAML conversation if it should -should be initiated by the application. This is called Service Provider -Initiated SAML. The service provider creates a SAML Authentication Request and -sends it to the identity provider (IdP). - -The `consume.php` is the ACS endpoint. Receives the SAML assertion. After Response -validation, the userdata and the nameID will be available, using `getNameId()` or -`getAttributes()` we obtain them. - -Since the version 1 of the php toolkit does not support SLO we don't show how -handle SLO in this demo-old. diff --git a/compatibility.php b/compatibility.php deleted file mode 100644 index 02a8108c..00000000 --- a/compatibility.php +++ /dev/null @@ -1,12 +0,0 @@ -isValid()) { - echo 'You are: ' . $samlResponse->getNameId() . '
'; - $attributes = $samlResponse->getAttributes(); - if (!empty($attributes)) { - echo 'You have the following attributes:
'; - echo ''; - foreach ($attributes as $attributeName => $attributeValues) { - echo ''; - } - echo '
NameValues
' . htmlentities($attributeName) . '
    '; - foreach ($attributeValues as $attributeValue) { - echo '
  • ' . htmlentities($attributeValue) . '
  • '; - } - echo '


'; - echo "The v.1 of the PHP SAML Tookit does not support SLO."; - } - } else { - echo 'Invalid SAML response.'; - } -} catch (Exception $e) { - echo 'Invalid SAML response: ' . $e->getMessage(); -} diff --git a/demo-old/index.php b/demo-old/index.php deleted file mode 100755 index 2854de3d..00000000 --- a/demo-old/index.php +++ /dev/null @@ -1,19 +0,0 @@ -getRedirectUrl(); - -header("Location: $url"); diff --git a/demo-old/metadata.php b/demo-old/metadata.php deleted file mode 100644 index 10d532ec..00000000 --- a/demo-old/metadata.php +++ /dev/null @@ -1,15 +0,0 @@ -getXml(); diff --git a/demo-old/settings_example.php b/demo-old/settings_example.php deleted file mode 100644 index f33ba94f..00000000 --- a/demo-old/settings_example.php +++ /dev/null @@ -1,54 +0,0 @@ -idpSingleSignOnUrl = ''; -// Initiate the SLO process, This URL asks the IdP to SLO the user. -$settings->idpSingleLogOutUrl = ''; - -// The certificate for the users account in the IdP -$settings->idpPublicCertificate = ''; - -// The URL where to the SAML Response/SAML Assertion will be posted -$settings->spReturnUrl = ''; - -// Name of this application -$settings->spIssuer = ''; - -// Tells the IdP to return the email address of the current user -$settings->requestedNameIdFormat = OneLogin_Saml_Settings::NAMEID_EMAIL_ADDRESS; - -return $settings; diff --git a/lib/Saml/AuthRequest.php b/lib/Saml/AuthRequest.php deleted file mode 100644 index 6e242748..00000000 --- a/lib/Saml/AuthRequest.php +++ /dev/null @@ -1,63 +0,0 @@ -auth = new OneLogin_Saml2_Auth($settings); - } - - /** - * Obtains the SSO URL containing the AuthRequest - * message deflated. - * - * @param string|null $returnTo - * - * @return string - * - * @throws OneLogin_Saml2_Error - */ - public function getRedirectUrl($returnTo = null) - { - $settings = $this->auth->getSettings(); - $authnRequest = new OneLogin_Saml2_AuthnRequest($settings); - $parameters = array('SAMLRequest' => $authnRequest->getRequest()); - if (!empty($returnTo)) { - $parameters['RelayState'] = $returnTo; - } else { - $parameters['RelayState'] = OneLogin_Saml2_Utils::getSelfRoutedURLNoQuery(); - } - $url = OneLogin_Saml2_Utils::redirect($this->auth->getSSOurl(), $parameters, true); - return $url; - } - - /** - * @return string - */ - protected function _generateUniqueID() - { - return OneLogin_Saml2_Utils::generateUniqueID(); - } - - /** - * @return string - */ - protected function _getTimestamp() - { - $date = new DateTime('now', new DateTimeZone('UTC')); - $timestamp = $date->format("Y-m-d\TH:i:s\Z"); - return $timestamp; - } -} diff --git a/lib/Saml/Metadata.php b/lib/Saml/Metadata.php deleted file mode 100644 index 3b6f94dd..00000000 --- a/lib/Saml/Metadata.php +++ /dev/null @@ -1,38 +0,0 @@ -_settings = $auth->getSettings(); - } - - /** - * @return string - * - * @throws OneLogin_Saml2_Error - */ - public function getXml() - { - return $this->_settings->getSPMetadata(); - } - - /** - * @return string - */ - protected function _getMetadataValidTimestamp() - { - $timestamp = time() + self::VALIDITY_SECONDS; - $date = new DateTime("@$timestamp", new DateTimeZone('UTC')); - $time = $date->format("Y-m-d\TH:i:s\Z"); - return $time; - } -} diff --git a/lib/Saml/Response.php b/lib/Saml/Response.php deleted file mode 100644 index d9332a71..00000000 --- a/lib/Saml/Response.php +++ /dev/null @@ -1,39 +0,0 @@ -getSettings(); - parent::__construct($settings, $assertion); - } - - /** - * Retrieves an Array with the logged user data. - * - * @return array - */ - public function get_saml_attributes() - { - return $this->getAttributes(); - } - - /** - * Retrieves the nameId - * - * @return string - */ - public function get_nameid() - { - return $this->getNameId(); - } -} diff --git a/lib/Saml/Settings.php b/lib/Saml/Settings.php deleted file mode 100644 index e9dbedc8..00000000 --- a/lib/Saml/Settings.php +++ /dev/null @@ -1,80 +0,0 @@ - Values (compatibility with the new version) - */ - public function getValues() - { - $values = array(); - - $values['sp'] = array(); - $values['sp']['entityId'] = $this->spIssuer; - $values['sp']['assertionConsumerService'] = array( - 'url' => $this->spReturnUrl, - ); - $values['sp']['NameIDFormat'] = $this->requestedNameIdFormat; - - $values['idp'] = array(); - $values['idp']['entityId'] = $this->idpSingleSignOnUrl; - $values['idp']['singleSignOnService'] = array( - 'url' => $this->idpSingleSignOnUrl, - ); - $values['idp']['singleLogoutService'] = array( - 'url' => $this->idpSingleLogOutUrl, - ); - $values['idp']['x509cert'] = $this->idpPublicCertificate; - - return $values; - } -} diff --git a/lib/Saml/XmlSec.php b/lib/Saml/XmlSec.php deleted file mode 100644 index 919a62ef..00000000 --- a/lib/Saml/XmlSec.php +++ /dev/null @@ -1,110 +0,0 @@ -_settings = $settings; - $this->_document = clone $response->document; - } - - /** - * Verify that the document only contains a single Assertion - * - * @return bool TRUE if the document passes. - */ - public function validateNumAssertions() - { - $rootNode = $this->_document; - $assertionNodes = $rootNode->getElementsByTagName('Assertion'); - return ($assertionNodes->length == 1); - } - - /** - * Verify that the document is still valid according - * - * @return bool - */ - public function validateTimestamps() - { - $rootNode = $this->_document; - $timestampNodes = $rootNode->getElementsByTagName('Conditions'); - for ($i = 0; $i < $timestampNodes->length; $i++) { - $nbAttribute = $timestampNodes->item($i)->attributes->getNamedItem("NotBefore"); - $naAttribute = $timestampNodes->item($i)->attributes->getNamedItem("NotOnOrAfter"); - if ($nbAttribute && strtotime($nbAttribute->textContent) > time()) { - return false; - } - if ($naAttribute && strtotime($naAttribute->textContent) <= time()) { - return false; - } - } - return true; - } - - /** - * @return bool - * - * @throws Exception - */ - public function isValid() - { - $singleAssertion = $this->validateNumAssertions(); - if (!$singleAssertion) { - throw new Exception('Multiple assertions are not supported'); - } - - $validTimestamps = $this->validateTimestamps(); - if (!$validTimestamps) { - throw new Exception('Timing issues (please check your clock settings)'); - } - - $objXMLSecDSig = new XMLSecurityDSig(); - - $objDSig = $objXMLSecDSig->locateSignature($this->_document); - if (!$objDSig) { - throw new Exception('Cannot locate Signature Node'); - } - $objXMLSecDSig->canonicalizeSignedInfo(); - $objXMLSecDSig->idKeys = array('ID'); - - $objKey = $objXMLSecDSig->locateKey(); - if (!$objKey) { - throw new Exception('We have no idea about the key'); - } - - try { - $objXMLSecDSig->validateReference(); - } catch (Exception $e) { - throw new Exception('Reference Validation Failed'); - } - - XMLSecEnc::staticLocateKeyInfo($objKey, $objDSig); - - $objKey->loadKey($this->_settings->idpPublicCertificate, false, true); - - return ($objXMLSecDSig->verify($objKey) === 1); - } -} diff --git a/lib/Saml2/Auth.php b/lib/Saml2/Auth.php index c8a1c6f0..6399096b 100644 --- a/lib/Saml2/Auth.php +++ b/lib/Saml2/Auth.php @@ -143,7 +143,7 @@ class OneLogin_Saml2_Auth /** * Initializes the SP SAML instance. * - * @param array|object|null $oldSettings Setting data (You can provide a OneLogin_Saml_Settings, the settings object of the Saml folder implementation) + * @param array|null $oldSettings * @param bool $spValidationOnly if you only as an SP , you should set it to false if not you should set it to true * * @throws OneLogin_Saml2_Error diff --git a/lib/Saml2/Settings.php b/lib/Saml2/Settings.php index 358bf5ea..8eee79ad 100644 --- a/lib/Saml2/Settings.php +++ b/lib/Saml2/Settings.php @@ -125,12 +125,6 @@ public function __construct($settings = null, $spValidationOnly = false) array(implode(', ', $this->_errors)) ); } - } else if ($settings instanceof OneLogin_Saml2_Settings) { - throw new OneLogin_Saml2_Error( - 'Only instances of OneLogin_Saml_Settings are supported.', - OneLogin_Saml2_Error::UNSUPPORTED_SETTINGS_OBJECT, - array(implode(', ', $this->_errors)) - ); } else { if (!$this->_loadSettingsFromArray($settings->getValues())) { throw new OneLogin_Saml2_Error( diff --git a/tests/bootstrap.php b/tests/bootstrap.php index de610730..b14c231d 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -11,13 +11,6 @@ if (!defined('XMLSECLIBS_DIR')) define('XMLSECLIBS_DIR', $basePath.'/extlib/xmlseclibs/'); require_once XMLSECLIBS_DIR . 'xmlseclibs.php'; -if (!defined('ONELOGIN_SAML_DIR')) define('ONELOGIN_SAML_DIR', $basePath.'/lib/Saml/'); -require_once ONELOGIN_SAML_DIR . 'AuthRequest.php'; -require_once ONELOGIN_SAML_DIR . 'Response.php'; -require_once ONELOGIN_SAML_DIR . 'Settings.php'; -require_once ONELOGIN_SAML_DIR . 'Metadata.php'; -require_once ONELOGIN_SAML_DIR . 'XmlSec.php'; - if (!defined('ONELOGIN_CUSTOMPATH')) { define('ONELOGIN_CUSTOMPATH', __DIR__.'/data/customPath/'); } @@ -29,12 +22,12 @@ /** * In phpunit when a redirect is executed an Excepion raise, * this funcion Get the target URL of the redirection - * + * * @param array $trace Trace of the Stack when an Exception raised * * @return string $targeturl Target url of the redirection */ - function getUrlFromRedirect($trace) + function getUrlFromRedirect($trace) { $param_args = $trace[0]['args'][4]; $targeturl = $param_args['url']; @@ -45,12 +38,12 @@ function getUrlFromRedirect($trace) if (!function_exists('getParamsFromUrl')) { /** * Parsed the Query parameters of an URL. - * + * * @param string $url The URL * * @return array $parsedQuery Parsed query of the url */ - function getParamsFromUrl($url) + function getParamsFromUrl($url) { $parsedUrl = parse_url($url); $query = $parsedUrl['query']; diff --git a/tests/src/OneLogin/Saml/AuthRequestTest.php b/tests/src/OneLogin/Saml/AuthRequestTest.php deleted file mode 100644 index 1906c141..00000000 --- a/tests/src/OneLogin/Saml/AuthRequestTest.php +++ /dev/null @@ -1,109 +0,0 @@ -idpSingleSignOnUrl = 'http://stuff.com'; - $settings->spReturnUrl = 'http://sp.stuff.com'; - $cert = file_get_contents(TEST_ROOT . '/data/customPath/certs/sp.crt'); - $settings->idpPublicCertificate = $cert; - $this->_settings = $settings; - } - - /** - * Tests the OneLogin_Saml_AuthRequest Constructor and - * the getRedirectUrl method - * The creation of a deflated SAML Request - * - * @covers OneLogin_Saml_AuthRequest - * @covers OneLogin_Saml_AuthRequest::getRedirectUrl - */ - public function testCreateDeflatedSAMLRequestURLParameter() - { - $request = new OneLogin_Saml_AuthRequest($this->_settings); - $authUrl = $request->getRedirectUrl(); - $this->assertRegExp('#^http://stuff\.com\?SAMLRequest=#', $authUrl); - parse_str(parse_url($authUrl, PHP_URL_QUERY), $exploded); - // parse_url already urldecode de params so is not required. - $payload = $exploded['SAMLRequest']; - $decoded = base64_decode($payload); - $inflated = gzinflate($decoded); - $this->assertRegExp('#^_settings); - $authUrl2 = $request2->getRedirectUrl('http://sp.example.com'); - $this->assertRegExp('#^http://stuff\.com\?SAMLRequest=#', $authUrl2); - parse_str(parse_url($authUrl2, PHP_URL_QUERY), $exploded2); - // parse_url already urldecode de params so is not required. - $this->assertEquals('http://sp.example.com', $exploded2['RelayState']); - $payload2 = $exploded2['SAMLRequest']; - $decoded2 = base64_decode($payload2); - $inflated2 = gzinflate($decoded2); - $this->assertRegExp('#^getMethod('_getTimestamp'); - - if (method_exists($method, 'setAccessible')) { - $method->setAccessible(true); - - $settingsDir = TEST_ROOT .'/settings/'; - include $settingsDir.'settings1.php'; - - $metadata = new OneLogin_Saml_AuthRequest($settingsInfo); - - $time = time(); - $timestamp = $method->invoke($metadata); - $this->assertEquals(strtotime($timestamp), $time); - } - } - } - - /** - * Tests the protected method _generateUniqueID of the OneLogin_Saml_AuthRequest - * - * @covers OneLogin_Saml_AuthRequest::_generateUniqueID - */ - public function testGenerateUniqueID() - { - if (class_exists('ReflectionClass')) { - $reflectionClass = new ReflectionClass("OneLogin_Saml_AuthRequest"); - $method = $reflectionClass->getMethod('_generateUniqueID'); - - if (method_exists($method, 'setAccessible')) { - $method->setAccessible(true); - - $settingsDir = TEST_ROOT .'/settings/'; - include $settingsDir.'settings1.php'; - - $metadata = new OneLogin_Saml_AuthRequest($settingsInfo); - - $id = $method->invoke($metadata); - $id2 = $method->invoke($metadata); - $this->assertNotEmpty($id); - $this->assertNotEmpty($id2); - $this->assertNotEquals($id, $id2); - $this->assertContains('ONELOGIN', $id); - } - } - } -} diff --git a/tests/src/OneLogin/Saml/MetadataTest.php b/tests/src/OneLogin/Saml/MetadataTest.php deleted file mode 100644 index 89e78299..00000000 --- a/tests/src/OneLogin/Saml/MetadataTest.php +++ /dev/null @@ -1,102 +0,0 @@ -getXML(); - - $this->assertNotEmpty($xmlMetadata); - - $dom = new DOMDocument(); - $dom->loadXML($xmlMetadata); - - $entityDescriptor = $dom->firstChild; - $this->assertEquals('md:EntityDescriptor', $entityDescriptor->tagName); - $this->assertTrue($entityDescriptor->hasAttribute('entityID')); - $this->assertEquals('http://stuff.com/endpoints/metadata.php', $entityDescriptor->getAttribute('entityID')); - $this->assertTrue($entityDescriptor->hasAttribute('validUntil')); - $this->assertTrue($entityDescriptor->hasAttribute('cacheDuration')); - - $this->assertTrue(time() < strtotime($entityDescriptor->getAttribute('validUntil'))); - - $sspSSONodes = $entityDescriptor->getElementsByTagName('SPSSODescriptor'); - $this->assertEquals(1, $sspSSONodes->length); - $spSSODescriptor = $sspSSONodes->item(0); - - $this->assertTrue($spSSODescriptor->hasAttribute('AuthnRequestsSigned')); - $this->assertEquals("false", $spSSODescriptor->getAttribute('AuthnRequestsSigned')); - $this->assertTrue($spSSODescriptor->hasAttribute('WantAssertionsSigned')); - $this->assertEquals("false", $spSSODescriptor->getAttribute('WantAssertionsSigned')); - $this->assertTrue($spSSODescriptor->hasAttribute('protocolSupportEnumeration')); - $this->assertEquals("urn:oasis:names:tc:SAML:2.0:protocol", $spSSODescriptor->getAttribute('protocolSupportEnumeration')); - - $nameIdNodes = $entityDescriptor->getElementsByTagName('NameIDFormat'); - $this->assertEquals(1, $nameIdNodes->length); - $nameID = $nameIdNodes->item(0); - - $nameIdNodes = $entityDescriptor->getElementsByTagName('NameIDFormat'); - $this->assertEquals(1, $nameIdNodes->length); - $nameID = $nameIdNodes->item(0); - $this->assertEquals("urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified", $nameID->nodeValue); - - $assertionConsumerServiceNodes = $entityDescriptor->getElementsByTagName('AssertionConsumerService'); - $this->assertEquals(1, $assertionConsumerServiceNodes->length); - $acs = $assertionConsumerServiceNodes->item(0); - $this->assertTrue($acs->hasAttribute('Binding')); - $this->assertEquals('urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', $acs->getAttribute('Binding')); - $this->assertTrue($acs->hasAttribute('Location')); - $this->assertEquals('http://stuff.com/endpoints/endpoints/acs.php', $acs->getAttribute('Location')); - $this->assertTrue($acs->hasAttribute('index')); - $this->assertEquals('1', $acs->getAttribute('index')); - - $singleLogoutServiceNodes = $entityDescriptor->getElementsByTagName('SingleLogoutService'); - $this->assertEquals(1, $singleLogoutServiceNodes->length); - $sls = $singleLogoutServiceNodes->item(0); - $this->assertTrue($sls->hasAttribute('Binding')); - $this->assertEquals('urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect', $sls->getAttribute('Binding')); - $this->assertTrue($sls->hasAttribute('Location')); - $this->assertEquals('http://stuff.com/endpoints/endpoints/sls.php', $sls->getAttribute('Location')); - } - - /** - * Tests the protected method _getMetadataValidTimestamp of the OneLogin_Saml_Metadata - * - * @covers OneLogin_Saml_Metadata::_getMetadataValidTimestamp - */ - public function testGetMetadataValidTimestamp() - { - if (class_exists('ReflectionClass')) { - $reflectionClass = new ReflectionClass("OneLogin_Saml_Metadata"); - $method = $reflectionClass->getMethod('_getMetadataValidTimestamp'); - - if (method_exists($method, 'setAccessible')) { - $method->setAccessible(true); - - $settingsDir = TEST_ROOT .'/settings/'; - include $settingsDir.'settings1.php'; - - $metadata = new OneLogin_Saml_Metadata($settingsInfo); - - $time = time()+ OneLogin_Saml_Metadata::VALIDITY_SECONDS; - $validTimestamp = $method->invoke($metadata); - $this->assertEquals(strtotime($validTimestamp), $time); - } - } - } -} diff --git a/tests/src/OneLogin/Saml/ResponseTest.php b/tests/src/OneLogin/Saml/ResponseTest.php deleted file mode 100644 index 3ecf2e5e..00000000 --- a/tests/src/OneLogin/Saml/ResponseTest.php +++ /dev/null @@ -1,101 +0,0 @@ -_settings = new OneLogin_Saml_Settings; - - $settingsDir = TEST_ROOT .'/settings/'; - include $settingsDir.'settings1.php'; - - $this->_settings->spIssuer = $settingsInfo['sp']['entityId']; - $this->_settings->spReturnUrl = $settingsInfo['sp']['assertionConsumerService']['url']; - $this->_settings->idpSingleSignOnUrl = $settingsInfo['idp']['singleSignOnService']['url']; - $this->_settings->idpSingleLogOutUrl = $settingsInfo['idp']['singleLogoutService']['url']; - - $cert = $settingsInfo['idp']['x509cert']; - - $x509cert = str_replace(array("\x0D", "\r", "\n"), "", $cert); - if (!empty($x509cert)) { - $x509cert = str_replace('-----BEGIN CERTIFICATE-----', "", $x509cert); - $x509cert = str_replace('-----END CERTIFICATE-----', "", $x509cert); - $x509cert = str_replace(' ', '', $x509cert); - - $x509cert = "-----BEGIN CERTIFICATE-----\n".chunk_split($x509cert, 64, "\n")."-----END CERTIFICATE-----\n"; - } - - $this->_settings->idpPublicCertificate = $x509cert; - } - - public function testReturnNameId() - { - $xml = file_get_contents(TEST_ROOT . '/data/responses/response1.xml.base64'); - $response = new OneLogin_Saml_Response($this->_settings, $xml); - - $this->assertEquals('support@onelogin.com', $response->getNameId()); - - $this->assertEquals('support@onelogin.com', $response->get_nameid()); - } - - public function testGetAttributes() - { - $xml = file_get_contents(TEST_ROOT . '/data/responses/response1.xml.base64'); - $response = new OneLogin_Saml_Response($this->_settings, $xml); - - $expectedAttributes = array( - 'uid' => array( - 'demo' - ), - 'another_value' => array( - 'value' - ), - ); - $this->assertEquals($expectedAttributes, $response->getAttributes()); - - $this->assertEquals($response->getAttributes(), $response->get_saml_attributes()); - - // An assertion that has no attributes should return an empty array when asked for the attributes - $assertion = file_get_contents(TEST_ROOT . '/data/responses/response2.xml.base64'); - $response = new OneLogin_Saml_Response($this->_settings, $assertion); - - $this->assertEmpty($response->getAttributes()); - } - - public function testOnlyRetrieveAssertionWithIDThatMatchesSignatureReference() - { - $xml = file_get_contents(TEST_ROOT . '/data/responses/wrapped_response_2.xml.base64'); - $response = new OneLogin_Saml_Response($this->_settings, $xml); - try { - $nameId = $response->getNameId(); - $this->assertNotEquals('root@example.com', $nameId); - } catch (Exception $e) { - $this->assertNotEmpty($e->getMessage(), 'Trying to get NameId on an unsigned assertion fails'); - } - } - - public function testDoesNotAllowSignatureWrappingAttack() - { - $xml = file_get_contents(TEST_ROOT . '/data/responses/response4.xml.base64'); - $response = new OneLogin_Saml_Response($this->_settings, $xml); - - $this->assertEquals('test@onelogin.com', $response->getNameId()); - } - - public function testGetSessionNotOnOrAfter() - { - $xml = file_get_contents(TEST_ROOT . '/data/responses/response1.xml.base64'); - $response = new OneLogin_Saml_Response($this->_settings, $xml); - - $this->assertEquals(1290203857, $response->getSessionNotOnOrAfter()); - - // An assertion that do not specified Session timeout should return NULL - - $xml = file_get_contents(TEST_ROOT . '/data/responses/response2.xml.base64'); - $response = new OneLogin_Saml_Response($this->_settings, $xml); - - $this->assertNull($response->getSessionNotOnOrAfter()); - } -} diff --git a/tests/src/OneLogin/Saml/XmlSecTest.php b/tests/src/OneLogin/Saml/XmlSecTest.php deleted file mode 100644 index 856de332..00000000 --- a/tests/src/OneLogin/Saml/XmlSecTest.php +++ /dev/null @@ -1,145 +0,0 @@ -_settings = new OneLogin_Saml_Settings; - - $settingsDir = TEST_ROOT .'/settings/'; - include $settingsDir.'settings1.php'; - - $this->_settings->spIssuer = $settingsInfo['sp']['entityId']; - $this->_settings->spReturnUrl = $settingsInfo['sp']['assertionConsumerService']['url']; - $this->_settings->idpSingleSignOnUrl = $settingsInfo['idp']['singleSignOnService']['url']; - $this->_settings->idpSingleLogOutUrl = $settingsInfo['idp']['singleLogoutService']['url']; - - $cert = $settingsInfo['idp']['x509cert']; - - $x509cert = str_replace(array("\x0D", "\r", "\n"), "", $cert); - if (!empty($x509cert)) { - $x509cert = str_replace('-----BEGIN CERTIFICATE-----', "", $x509cert); - $x509cert = str_replace('-----END CERTIFICATE-----', "", $x509cert); - $x509cert = str_replace(' ', '', $x509cert); - - $x509cert = "-----BEGIN CERTIFICATE-----\n".chunk_split($x509cert, 64, "\n")."-----END CERTIFICATE-----\n"; - } - - $this->_settings->idpPublicCertificate = $x509cert; - } - - public function testValidateNumAssertions() - { - $assertion = file_get_contents(TEST_ROOT . '/data/responses/response1.xml.base64'); - $response = new OneLogin_Saml_Response($this->_settings, $assertion); - - $xmlSec = new OneLogin_Saml_XmlSec($this->_settings, $response); - - $this->assertTrue($xmlSec->validateNumAssertions()); - } - - public function testValidateTimestampsInvalid() - { - $assertion = file_get_contents(TEST_ROOT . '/data/responses/invalids/not_before_failed.xml.base64'); - $response = new OneLogin_Saml_Response($this->_settings, $assertion); - - $xmlSec = new OneLogin_Saml_XmlSec($this->_settings, $response); - - $this->assertFalse($xmlSec->validateTimestamps()); - - - $assertion2 = file_get_contents(TEST_ROOT . '/data/responses/invalids/not_after_failed.xml.base64'); - $response2 = new OneLogin_Saml_Response($this->_settings, $assertion2); - - $xmlSec2 = new OneLogin_Saml_XmlSec($this->_settings, $response2); - - $this->assertFalse($xmlSec2->validateTimestamps()); - } - - public function testValidateTimestampsValid() - { - $assertion = file_get_contents(TEST_ROOT . '/data/responses/valid_response.xml.base64'); - $response = new OneLogin_Saml_Response($this->_settings, $assertion); - - $xmlSec = new OneLogin_Saml_XmlSec($this->_settings, $response); - - $this->assertTrue($xmlSec->validateTimestamps()); - } - - public function testValidateAssertionUnsigned() - { - $assertionUnsigned = file_get_contents(TEST_ROOT . '/data/responses/invalids/no_signature.xml.base64'); - $responseUnsigned = new OneLogin_Saml_Response($this->_settings, $assertionUnsigned); - $xmlSecUnsigned = new OneLogin_Saml_XmlSec($this->_settings, $responseUnsigned); - try { - $this->assertFalse($xmlSecUnsigned->isValid()); - $this->assertFalse(true); - } catch (Exception $e) { - $this->assertContains('Cannot locate Signature Node', $e->getMessage()); - } - } - - public function testValidateAssertionBadReference() - { - $assertionBadReference = file_get_contents(TEST_ROOT . '/data/responses/invalids/bad_reference.xml.base64'); - $responseBadReference = new OneLogin_Saml_Response($this->_settings, $assertionBadReference); - $xmlSecBadReference = new OneLogin_Saml_XmlSec($this->_settings, $responseBadReference); - try { - $this->assertFalse($xmlSecBadReference->isValid()); - $this->assertFalse(true); - } catch (Exception $e) { - $this->assertEquals('Reference Validation Failed', $e->getMessage()); - } - } - - public function testValidateAssertionMultiple() - { - $assertionMulti = file_get_contents(TEST_ROOT . '/data/responses/invalids/multiple_assertions.xml.base64'); - $responseMulti = new OneLogin_Saml_Response($this->_settings, $assertionMulti); - $xmlSecMulti = new OneLogin_Saml_XmlSec($this->_settings, $responseMulti); - try { - $this->assertFalse($xmlSecMulti->isValid()); - $this->assertFalse(true); - } catch (Exception $e) { - $this->assertContains('Multiple assertions are not supported', $e->getMessage()); - } - } - - public function testValidateAssertionExpired() - { - $assertionExpired = file_get_contents(TEST_ROOT . '/data/responses/expired_response.xml.base64'); - $responseExpired = new OneLogin_Saml_Response($this->_settings, $assertionExpired); - $xmlSecExpired = new OneLogin_Saml_XmlSec($this->_settings, $responseExpired); - try { - $this->assertFalse($xmlSecExpired->isValid()); - $this->assertFalse(true); - } catch (Exception $e) { - $this->assertContains('Timing issues (please check your clock settings)', $e->getMessage()); - } - } - - public function testValidateAssertionNoKey() - { - $assertionNoKey = file_get_contents(TEST_ROOT . '/data/responses/invalids/no_key.xml.base64'); - $responseNoKey = new OneLogin_Saml_Response($this->_settings, $assertionNoKey); - $xmlSecNoKey = new OneLogin_Saml_XmlSec($this->_settings, $responseNoKey); - try { - $this->assertFalse($xmlSecNoKey->isValid()); - $this->assertFalse(true); - } catch (Exception $e) { - $this->assertContains('We have no idea about the key', $e->getMessage()); - } - } - - public function testValidateAssertionValid() - { - $assertion = file_get_contents(TEST_ROOT . '/data/responses/valid_response.xml.base64'); - $response = new OneLogin_Saml_Response($this->_settings, $assertion); - - $xmlSec = new OneLogin_Saml_XmlSec($this->_settings, $response); - - $this->assertTrue($xmlSec->isValid()); - } -} diff --git a/tests/src/OneLogin/Saml2/SettingsTest.php b/tests/src/OneLogin/Saml2/SettingsTest.php index be03fe76..b5727f7e 100644 --- a/tests/src/OneLogin/Saml2/SettingsTest.php +++ b/tests/src/OneLogin/Saml2/SettingsTest.php @@ -42,25 +42,6 @@ public function testLoadSettingsFromArray() $this->assertEmpty($settings3->getErrors()); } - /** - * Tests the OneLogin_Saml2_Settings Constructor. - * Case load setting from OneLogin_Saml_Settings's object - * - * @covers OneLogin_Saml2_Settings - */ - public function testLoadSettingsFromObject() - { - $settingsObj = new OneLogin_Saml_Settings; - $settingsObj->idpSingleSignOnUrl = 'http://stuff.com'; - $settingsObj->spReturnUrl = 'http://sp.stuff.com'; - $cert = file_get_contents(TEST_ROOT . '/data/customPath/certs/sp.crt'); - $settingsObj->idpPublicCertificate = $cert; - - $settings = new OneLogin_Saml2_Settings($settingsObj); - - $this->assertEmpty($settings->getErrors()); - } - /** * Tests the OneLogin_Saml2_Settings Constructor. * Case load setting from file diff --git a/tests/src/OneLogin/Saml2/SignedResponseTest.php b/tests/src/OneLogin/Saml2/SignedResponseTest.php index 6b3d4e7e..8c52756c 100644 --- a/tests/src/OneLogin/Saml2/SignedResponseTest.php +++ b/tests/src/OneLogin/Saml2/SignedResponseTest.php @@ -2,7 +2,7 @@ /** * Unit tests for Response messages signed */ -class OneLogin_Saml_SignedResponseTest extends PHPUnit_Framework_TestCase +class OneLogin_Saml2_SignedResponseTest extends PHPUnit_Framework_TestCase { private $_settings;