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>
|
* <code>
|
||||||
* if(Director::isLive()) Director::forceSSL();
|
* if(Director::isLive()) Director::forceSSL();
|
||||||
* </code>
|
* </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() {
|
static function forceSSL($patterns = null) {
|
||||||
if((Director::protocol() != "https://") && !Director::isDev() && !Director::is_cli()) {
|
$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']));
|
$destURL = str_replace('http:', 'https:', Director::absoluteURL($_SERVER['REQUEST_URI']));
|
||||||
|
|
||||||
header("Location: $destURL", true, 301);
|
header("Location: $destURL");
|
||||||
die("<h1>Your browser is not accepting header redirects</h1><p>Please <a href=\"$destURL\">click here</a>");
|
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()
|
* @todo test Director::alternateBaseFolder()
|
||||||
*/
|
*/
|
||||||
class DirectorTest extends SapphireTest {
|
class DirectorTest extends FunctionalTest {
|
||||||
|
|
||||||
function setUp() {
|
function setUp() {
|
||||||
parent::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 {
|
class DirectorTestRequest_Controller extends Controller implements TestOnly {
|
||||||
|
Loading…
Reference in New Issue
Block a user