diff options
author | Jaime Pérez <jaime.perez@uninett.no> | 2016-07-15 15:46:46 +0200 |
---|---|---|
committer | Jaime Pérez <jaime.perez@uninett.no> | 2016-07-15 15:47:57 +0200 |
commit | e8ee8c83ef535273428f4c330107415b8ac6050d (patch) | |
tree | 06604aab74ab43c2387a6e8e15468fa5a6612207 /tests/lib/SimpleSAML/Utils/HTTPTest.php | |
parent | e6fffdcbf4f565cdf6fc1549b89825720db2e85a (diff) | |
download | simplesamlphp-e8ee8c83ef535273428f4c330107415b8ac6050d.zip simplesamlphp-e8ee8c83ef535273428f4c330107415b8ac6050d.tar.gz simplesamlphp-e8ee8c83ef535273428f4c330107415b8ac6050d.tar.bz2 |
bugfix: Restore the capability to get our self URL when invoked from a third-party script.
Recent fixes for URL guessing and building addressed bugs in the code that were preventing the 'baseurlpath' from being used properly. However, they introduced a new issue, as the code was assuming the current URL would always point to a SimpleSAMLphp script. This is not always true, of course, as any script can invoke our API and end up trying to get its own URL (for example, when calling requireAuth()).
In order to fix this, we monitor mismatches between SimpleSAMLphp's installation path and the absolute, real path to the current script. When there's a mismatch, it means we are running a third-party script outside SimpleSAMLphp, and therefore we should NOT enforce 'baseurlpath'. This introduces an additional issue, as applications behind a reverse proxy may cause trouble to guess the right URL (we will use the URL as seen by SimpleSAMLphp in the server, which is not necessarily the same as the user sees with a reverse proxy in between). For the moment, we'll leave the responsibility to sort that issue out to implementors. It might be a good idea to add a page to the wiki explaining how to do this.
This resolves #418.
Diffstat (limited to 'tests/lib/SimpleSAML/Utils/HTTPTest.php')
-rw-r--r-- | tests/lib/SimpleSAML/Utils/HTTPTest.php | 98 |
1 files changed, 81 insertions, 17 deletions
diff --git a/tests/lib/SimpleSAML/Utils/HTTPTest.php b/tests/lib/SimpleSAML/Utils/HTTPTest.php index 92a022f..b6bfb6b 100644 --- a/tests/lib/SimpleSAML/Utils/HTTPTest.php +++ b/tests/lib/SimpleSAML/Utils/HTTPTest.php @@ -6,6 +6,31 @@ use SimpleSAML\Utils\HTTP; class HTTPTest extends \PHPUnit_Framework_TestCase { + + /** + * Set up the environment ($_SERVER) populating the typical variables from a given URL. + * + * @param string $url The URL to use as the current one. + */ + private function setupEnvFromURL($url) + { + $addr = parse_url($url); + $_SERVER['HTTP_HOST'] = $addr['host']; + $_SERVER['SERVER_NAME'] = $addr['host']; + if ($addr['scheme'] === 'https') { + $_SERVER['HTTPS'] = 'on'; + $default_port = '443'; + } else { + unset($_SERVER['HTTPS']); + $default_port = '80'; + } + $_SERVER['SERVER_PORT'] = $default_port; + if (isset($addr['port']) && strval($addr['port']) !== $default_port) { + $_SERVER['SERVER_PORT'] = strval($addr['port']); + } + $_SERVER['REQUEST_URI'] = $addr['path'].'?'.$addr['query']; + } + /** * Test SimpleSAML\Utils\HTTP::addURLParameters(). * @@ -144,71 +169,112 @@ class HTTPTest extends \PHPUnit_Framework_TestCase /** * Test SimpleSAML\Utils\HTTP::getSelfURL(). */ - public function testGetSelfURL() + public function testGetSelfURLMethods() { $original = $_SERVER; + /* + * Test a URL pointing to a script that's not part of the public interface. This allows us to test calls to + * getSelfURL() from scripts outside of SimpleSAMLphp + */ + \SimpleSAML_Configuration::loadFromArray(array( + 'baseurlpath' => 'http://example.com/simplesaml/', + ), '[ARRAY]', 'simplesaml'); + $url = 'https://example.com/app/script.php/some/path?foo=bar'; + $this->setupEnvFromURL($url); + $_SERVER['SCRIPT_FILENAME'] = '/var/www/app/script.php'; + $this->assertEquals($url, HTTP::getSelfURL()); + $this->assertEquals('https://example.com', HTTP::getSelfURLHost()); + $this->assertEquals('https://example.com/app/script.php/some/path', HTTP::getSelfURLNoQuery()); + $this->assertTrue(HTTP::isHTTPS()); + $this->assertEquals('https://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost()); + // test a valid, full URL, based on a full URL in the configuration $cfg = \SimpleSAML_Configuration::loadFromArray(array( 'baseurlpath' => 'https://example.com/simplesaml/', ), '[ARRAY]', 'simplesaml'); $baseDir = $cfg->getBaseDir(); $_SERVER['SCRIPT_FILENAME'] = $baseDir.'www/module.php'; - $_SERVER['REQUEST_URI'] = '/simplesaml/module.php/module/file.php?foo=bar#something'; + $this->setupEnvFromURL('http://www.example.org/module.php/module/file.php?foo=bar'); $this->assertEquals( - 'https://example.com/simplesaml/module.php/module/file.php?foo=bar#something', + 'https://example.com/simplesaml/module.php/module/file.php?foo=bar', HTTP::getSelfURL() ); + $this->assertEquals('https://example.com', HTTP::getSelfURLHost()); + $this->assertEquals('https://example.com/simplesaml/module.php/module/file.php', HTTP::getSelfURLNoQuery()); + $this->assertTrue(HTTP::isHTTPS()); + $this->assertEquals('https://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost()); // test a valid, full URL, based on a full URL *without* a trailing slash in the configuration \SimpleSAML_Configuration::loadFromArray(array( 'baseurlpath' => 'https://example.com/simplesaml', ), '[ARRAY]', 'simplesaml'); $this->assertEquals( - 'https://example.com/simplesaml/module.php/module/file.php?foo=bar#something', + 'https://example.com/simplesaml/module.php/module/file.php?foo=bar', HTTP::getSelfURL() ); + $this->assertEquals('https://example.com', HTTP::getSelfURLHost()); + $this->assertEquals('https://example.com/simplesaml/module.php/module/file.php', HTTP::getSelfURLNoQuery()); + $this->assertTrue(HTTP::isHTTPS()); + $this->assertEquals('https://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost()); // test a valid, full URL, based on a full URL *without* a path in the configuration \SimpleSAML_Configuration::loadFromArray(array( 'baseurlpath' => 'https://example.com', ), '[ARRAY]', 'simplesaml'); $this->assertEquals( - 'https://example.com/module.php/module/file.php?foo=bar#something', + 'https://example.com/module.php/module/file.php?foo=bar', HTTP::getSelfURL() ); + $this->assertEquals('https://example.com', HTTP::getSelfURLHost()); + $this->assertEquals('https://example.com/module.php/module/file.php', HTTP::getSelfURLNoQuery()); + $this->assertTrue(HTTP::isHTTPS()); + $this->assertEquals('https://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost()); // test a valid, full URL, based on a relative path in the configuration \SimpleSAML_Configuration::loadFromArray(array( 'baseurlpath' => '/simplesaml/', ), '[ARRAY]', 'simplesaml'); - $_SERVER['HTTP_HOST'] = 'example.org'; - unset($_SERVER['HTTPS']); - unset($_SERVER['SERVER_PORT']); + $this->setupEnvFromURL('http://www.example.org/simplesaml/module.php/module/file.php?foo=bar'); $this->assertEquals( - 'http://example.org/simplesaml/module.php/module/file.php?foo=bar#something', + 'http://www.example.org/simplesaml/module.php/module/file.php?foo=bar', HTTP::getSelfURL() ); + $this->assertEquals('http://www.example.org', HTTP::getSelfURLHost()); + $this->assertEquals('http://www.example.org/simplesaml/module.php/module/file.php', HTTP::getSelfURLNoQuery()); + $this->assertFalse(HTTP::isHTTPS()); + $this->assertEquals('http://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost()); // test a valid, full URL, based on a relative path in the configuration and a non standard port \SimpleSAML_Configuration::loadFromArray(array( 'baseurlpath' => '/simplesaml/', ), '[ARRAY]', 'simplesaml'); - $_SERVER['SERVER_PORT'] = '8080'; + $this->setupEnvFromURL('http://example.org:8080/simplesaml/module.php/module/file.php?foo=bar'); $this->assertEquals( - 'http://example.org:8080/simplesaml/module.php/module/file.php?foo=bar#something', + 'http://example.org:8080/simplesaml/module.php/module/file.php?foo=bar', HTTP::getSelfURL() ); + $this->assertEquals('http://example.org:8080', HTTP::getSelfURLHost()); + $this->assertEquals('http://example.org:8080/simplesaml/module.php/module/file.php', HTTP::getSelfURLNoQuery()); + $this->assertFalse(HTTP::isHTTPS()); + $this->assertEquals('http://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost()); // test a valid, full URL, based on a relative path in the configuration, a non standard port and HTTPS \SimpleSAML_Configuration::loadFromArray(array( 'baseurlpath' => '/simplesaml/', ), '[ARRAY]', 'simplesaml'); - $_SERVER['HTTPS'] = 'on'; + $this->setupEnvFromURL('https://example.org:8080/simplesaml/module.php/module/file.php?foo=bar'); $this->assertEquals( - 'https://example.org:8080/simplesaml/module.php/module/file.php?foo=bar#something', + 'https://example.org:8080/simplesaml/module.php/module/file.php?foo=bar', HTTP::getSelfURL() ); + $this->assertEquals('https://example.org:8080', HTTP::getSelfURLHost()); + $this->assertEquals( + 'https://example.org:8080/simplesaml/module.php/module/file.php', + HTTP::getSelfURLNoQuery() + ); + $this->assertTrue(HTTP::isHTTPS()); + $this->assertEquals('https://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost()); $_SERVER = $original; } @@ -234,8 +300,7 @@ class HTTPTest extends \PHPUnit_Framework_TestCase 'https://app.example.com/', 'http://app.example.com/', ); - foreach ($allowed as $url) - { + foreach ($allowed as $url) { $this->assertEquals(HTTP::checkURLAllowed($url), $url); } @@ -267,8 +332,7 @@ class HTTPTest extends \PHPUnit_Framework_TestCase 'https://app2.example.com/', 'http://app2.example.com/', ); - foreach ($allowed as $url) - { + foreach ($allowed as $url) { $this->assertEquals(HTTP::checkURLAllowed($url), $url); } |