mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
ENHANCEMENT #2856 Limiting of relative URLs for Director::forceSSL() using a map of PCRE regular expressions
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/branches/2.4@108428 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
248979b4c5
commit
c52529215f
@ -605,19 +605,55 @@ class Director {
|
||||
}
|
||||
|
||||
/**
|
||||
* Force the site to run on SSL. To use, call from _config.php.
|
||||
* Force the site to run on SSL.
|
||||
*
|
||||
* For example:
|
||||
* To use, call from _config.php. For example:
|
||||
* <code>
|
||||
* if(Director::isLive()) Director::forceSSL();
|
||||
* </code>
|
||||
*
|
||||
* If you don't want your entire site to be on SSL, you can pass an array of PCRE regular expression
|
||||
* patterns for matching relative URLs. For example:
|
||||
* <code>
|
||||
* if(Director::isLive()) Director::forceSSL(array('/^admin/', '/^Security/.*'));
|
||||
* </code>
|
||||
*
|
||||
* Note that the session data will be lost when moving from HTTP to HTTPS.
|
||||
* It is your responsibility to ensure that this won't cause usability problems.
|
||||
*
|
||||
* CAUTION: This does not respect the site environment mode. You should check this
|
||||
* as per the above examples using Director::isLive() or Director::isTest() for example.
|
||||
*
|
||||
* @return boolean|string String of URL when unit tests running, boolean FALSE if patterns don't match request URI
|
||||
*/
|
||||
static function forceSSL() {
|
||||
if((Director::protocol() != "https://") && !Director::isDev() && !Director::is_cli()) {
|
||||
static function forceSSL($patterns = null) {
|
||||
$matched = false;
|
||||
|
||||
if($patterns) {
|
||||
// protect portions of the site based on the pattern
|
||||
$relativeURL = self::makeRelative(Director::absoluteURL($_SERVER['REQUEST_URI']));
|
||||
foreach($patterns as $pattern) {
|
||||
if(preg_match($pattern, $relativeURL)) {
|
||||
$matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// protect the entire site
|
||||
$matched = true;
|
||||
}
|
||||
|
||||
if($matched && !isset($_SERVER['HTTPS'])) {
|
||||
$destURL = str_replace('http:', 'https:', Director::absoluteURL($_SERVER['REQUEST_URI']));
|
||||
|
||||
header("Location: $destURL", true, 301);
|
||||
die("<h1>Your browser is not accepting header redirects</h1><p>Please <a href=\"$destURL\">click here</a>");
|
||||
header("Location: $destURL");
|
||||
if(SapphireTest::is_running_test()) {
|
||||
return $destURL;
|
||||
} else {
|
||||
die("<h1>Your browser is not accepting header redirects</h1><p>Please <a href=\"$destURL\">click here</a>");
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
*
|
||||
* @todo test Director::alternateBaseFolder()
|
||||
*/
|
||||
class DirectorTest extends SapphireTest {
|
||||
class DirectorTest extends FunctionalTest {
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
@ -189,7 +189,53 @@ class DirectorTest extends SapphireTest {
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function testForceSSLProtectsEntireSite() {
|
||||
$originalURI = $_SERVER['REQUEST_URI'];
|
||||
$_SERVER['REQUEST_URI'] = Director::baseURL() . 'admin';
|
||||
$output = Director::forceSSL();
|
||||
$this->assertEquals($output, 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
|
||||
|
||||
$_SERVER['REQUEST_URI'] = $originalURI;
|
||||
$_SERVER['REQUEST_URI'] = Director::baseURL() . 'some-url';
|
||||
$output = Director::forceSSL();
|
||||
$this->assertEquals($output, 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
|
||||
|
||||
$_SERVER['REQUEST_URI'] = $originalURI;
|
||||
}
|
||||
|
||||
function testForceSSLOnTopLevelPagePattern() {
|
||||
$originalURI = $_SERVER['REQUEST_URI'];
|
||||
$_SERVER['REQUEST_URI'] = Director::baseURL() . 'admin';
|
||||
$output = Director::forceSSL(array('/^admin/'));
|
||||
$this->assertEquals($output, 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
|
||||
|
||||
$_SERVER['REQUEST_URI'] = $originalURI;
|
||||
}
|
||||
|
||||
function testForceSSLOnSubPagesPattern() {
|
||||
$originalURI = $_SERVER['REQUEST_URI'];
|
||||
$_SERVER['REQUEST_URI'] = Director::baseURL() . 'Security/login';
|
||||
$output = Director::forceSSL(array('/^Security/'));
|
||||
$this->assertEquals($output, 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
|
||||
|
||||
$_SERVER['REQUEST_URI'] = $originalURI;
|
||||
}
|
||||
|
||||
function testForceSSLWithPatternDoesNotMatchOtherPages() {
|
||||
$originalURI = $_SERVER['REQUEST_URI'];
|
||||
$_SERVER['REQUEST_URI'] = Director::baseURL() . 'normal-page';
|
||||
$output = Director::forceSSL(array('/^admin/'));
|
||||
$this->assertFalse($output);
|
||||
|
||||
$_SERVER['REQUEST_URI'] = $originalURI;
|
||||
$_SERVER['REQUEST_URI'] = Director::baseURL() . 'just-another-page/sub-url';
|
||||
$output = Director::forceSSL(array('/^admin/', '/^Security/'));
|
||||
$this->assertFalse($output);
|
||||
|
||||
$_SERVER['REQUEST_URI'] = $originalURI;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DirectorTestRequest_Controller extends Controller implements TestOnly {
|
||||
|
Loading…
Reference in New Issue
Block a user