NEW Allow specifying the secure domain to Director::forceSSL()

This commit is contained in:
Sean Harvey 2013-04-03 16:53:58 +13:00
parent f0d92f7bcc
commit 6eda25a090
2 changed files with 26 additions and 3 deletions

View File

@ -693,15 +693,23 @@ class Director implements TemplateGlobalProvider {
* if(Director::isLive()) Director::forceSSL(array('/^admin/', '/^Security/'));
* </code>
*
* If you want certain parts of your site protected under a different domain, you can specify
* the domain as an argument:
* <code>
* if(Director::isLive()) Director::forceSSL(array('/^admin/', '/^Security/'), 'secure.mysite.com');
* </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.
*
* @param array $patterns Array of regex patterns to match URLs that should be HTTPS
* @param string $secureDomain Secure domain to redirect to. Defaults to the current domain
* @return boolean|string String of URL when unit tests running, boolean FALSE if patterns don't match request URI
*/
public static function forceSSL($patterns = null) {
public static function forceSSL($patterns = null, $secureDomain = null) {
if(!isset($_SERVER['REQUEST_URI'])) return false;
$matched = false;
@ -710,8 +718,9 @@ class Director implements TemplateGlobalProvider {
// Calling from the command-line?
if(!isset($_SERVER['REQUEST_URI'])) return;
// protect portions of the site based on the pattern
$relativeURL = self::makeRelative(Director::absoluteURL($_SERVER['REQUEST_URI']));
// protect portions of the site based on the pattern
foreach($patterns as $pattern) {
if(preg_match($pattern, $relativeURL)) {
$matched = true;
@ -727,7 +736,14 @@ class Director implements TemplateGlobalProvider {
&& !(isset($_SERVER['HTTP_X_FORWARDED_PROTOCOL'])
&& strtolower($_SERVER['HTTP_X_FORWARDED_PROTOCOL']) == 'https')) {
$destURL = str_replace('http:', 'https:', Director::absoluteURL($_SERVER['REQUEST_URI']));
// if an domain is specified, redirect to that instead of the current domain
if($secureDomain) {
$url = 'https://' . $secureDomain . $_SERVER['REQUEST_URI'];
} else {
$url = $_SERVER['REQUEST_URI'];
}
$destURL = str_replace('http:', 'https:', Director::absoluteURL($url));
// This coupling to SapphireTest is necessary to test the destination URL and to not interfere with tests
if(class_exists('SapphireTest', false) && SapphireTest::is_running_test()) {

View File

@ -242,6 +242,13 @@ class DirectorTest extends SapphireTest {
$this->assertFalse($output);
}
public function testForceSSLAlternateDomain() {
Director::setBaseURL('/');
$_SERVER['REQUEST_URI'] = Director::baseURL() . 'admin';
$output = Director::forceSSL(array('/^admin/'), 'secure.mysite.com');
$this->assertEquals($output, 'https://secure.mysite.com/admin');
}
/**
* @covers Director::extract_request_headers()
*/