public function preRequest(HTTPRequest $request, Session $session, DataModel $model) { // Bootstrap session so that Session::get() accesses the right instance $dummyController = new Controller(); $dummyController->setSession($session); $dummyController->setRequest($request); $dummyController->pushCurrent(); // Block non-authenticated users from setting the stage mode if (!Versioned::can_choose_site_stage($request)) { $permissionMessage = sprintf(_t("ContentController.DRAFT_SITE_ACCESS_RESTRICTION", 'You must log in with your CMS password in order to view the draft or archived content. ' . '<a href="%s">Click here to go back to the published site.</a>'), Convert::raw2xml(Controller::join_links(Director::baseURL(), $request->getURL(), "?stage=Live"))); // Force output since RequestFilter::preRequest doesn't support response overriding $response = Security::permissionFailure($dummyController, $permissionMessage); $session->inst_save(); $dummyController->popCurrent(); // Prevent output in testing if (class_exists('SilverStripe\\Dev\\SapphireTest', false) && SapphireTest::is_running_test()) { throw new HTTPResponse_Exception($response); } $response->output(); die; } Versioned::choose_site_stage(); $dummyController->popCurrent(); return true; }
public function index() { // Web mode if (!Director::is_cli()) { $renderer = DebugView::create(); echo $renderer->renderHeader(); echo $renderer->renderInfo("SilverStripe Development Tools", Director::absoluteBaseURL()); $base = Director::baseURL(); echo '<div class="options"><ul>'; $evenOdd = "odd"; foreach (self::get_links() as $action => $description) { echo "<li class=\"{$evenOdd}\"><a href=\"{$base}dev/{$action}\"><b>/dev/{$action}:</b>" . " {$description}</a></li>\n"; $evenOdd = $evenOdd == "odd" ? "even" : "odd"; } echo $renderer->renderFooter(); // CLI mode } else { echo "SILVERSTRIPE DEVELOPMENT TOOLS\n--------------------------\n\n"; echo "You can execute any of the following commands:\n\n"; foreach (self::get_links() as $action => $description) { echo " sake dev/{$action}: {$description}\n"; } echo "\n\n"; } }
/** * Provide downloadable url * * @param string $path * @return string|null */ public function getPublicUrl($path) { $rootPath = realpath(BASE_PATH); $filesPath = realpath($this->pathPrefix); if (stripos($filesPath, $rootPath) === 0) { $dir = substr($filesPath, strlen($rootPath)); return Controller::join_links(Director::baseURL(), $dir, $path); } // File outside of webroot can't be used return null; }
/** * Set a cookie * * @param string $name The name of the cookie * @param string $value The value for the cookie to hold * @param int $expiry The number of days until expiry; 0 indicates a cookie valid for the current session * @param string $path The path to save the cookie on (falls back to site base) * @param string $domain The domain to make the cookie available on * @param boolean $secure Can the cookie only be sent over SSL? * @param boolean $httpOnly Prevent the cookie being accessible by JS */ public function set($name, $value, $expiry = 90, $path = null, $domain = null, $secure = false, $httpOnly = true) { //are we setting or clearing a cookie? false values are reserved for clearing cookies (see PHP manual) $clear = false; if ($value === false || $value === '' || $expiry < 0) { $clear = true; $value = false; } //expiry === 0 is a special case where we set a cookie for the current user session if ($expiry !== 0) { //don't do the maths if we are clearing $expiry = $clear ? -1 : DBDatetime::now()->Format('U') + 86400 * $expiry; } //set the path up $path = $path ? $path : Director::baseURL(); //send the cookie $this->outputCookie($name, $value, $expiry, $path, $domain, $secure, $httpOnly); //keep our variables in check if ($clear) { unset($this->new[$name], $this->current[$name]); } else { $this->new[$name] = $this->current[$name] = $value; } }
/** * Gets the combined configuration of all LeafAndMain subclasses required by the client app. * * @return array * * WARNING: Experimental API */ public function getCombinedClientConfig() { $combinedClientConfig = ['sections' => []]; $cmsClassNames = CMSMenu::get_cms_classes('SilverStripe\\Admin\\LeftAndMain', true, CMSMenu::URL_PRIORITY); foreach ($cmsClassNames as $className) { $combinedClientConfig['sections'][$className] = Injector::inst()->get($className)->getClientConfig(); } // Pass in base url (absolute and relative) $combinedClientConfig['baseUrl'] = Director::baseURL(); $combinedClientConfig['absoluteBaseUrl'] = Director::absoluteBaseURL(); $combinedClientConfig['adminUrl'] = AdminRootController::admin_url(); // Get "global" CSRF token for use in JavaScript $token = SecurityToken::inst(); $combinedClientConfig[$token->getName()] = $token->getValue(); // Set env $combinedClientConfig['environment'] = Director::get_environment_type(); $combinedClientConfig['debugging'] = $this->config()->client_debugging; return Convert::raw2json($combinedClientConfig); }
/** * Redirect back. Uses either the HTTP-Referer or a manually set request-variable called "BackURL". * This variable is needed in scenarios where HTTP-Referer is not sent (e.g when calling a page by * location.href in IE). If none of the two variables is available, it will redirect to the base * URL (see {@link Director::baseURL()}). * * @uses redirect() * * @return bool|HTTPResponse */ public function redirectBack() { // Don't cache the redirect back ever HTTP::set_cache_age(0); $url = null; // In edge-cases, this will be called outside of a handleRequest() context; in that case, // redirect to the homepage - don't break into the global state at this stage because we'll // be calling from a test context or something else where the global state is inappropraite if ($this->getRequest()) { if ($this->getRequest()->requestVar('BackURL')) { $url = $this->getRequest()->requestVar('BackURL'); } else { if ($this->getRequest()->isAjax() && $this->getRequest()->getHeader('X-Backurl')) { $url = $this->getRequest()->getHeader('X-Backurl'); } else { if ($this->getRequest()->getHeader('Referer')) { $url = $this->getRequest()->getHeader('Referer'); } } } } if (!$url) { $url = Director::baseURL(); } // absolute redirection URLs not located on this site may cause phishing if (Director::is_site_url($url)) { $url = Director::absoluteURL($url, true); return $this->redirect($url); } else { return false; } }
/** * Check if the user has permissions to run URL debug tools, * else redirect them to log in. */ public static function require_developer_login() { if (Director::isDev()) { return; } if (isset($_SESSION['loggedInAs'])) { // We have to do some raw SQL here, because this method is called in Object::defineMethods(). // This means we have to be careful about what objects we create, as we don't want Object::defineMethods() // being called again. // This basically calls Permission::checkMember($_SESSION['loggedInAs'], 'ADMIN'); // @TODO - Rewrite safely using DataList::filter $memberID = $_SESSION['loggedInAs']; $permission = DB::prepared_query(' SELECT "ID" FROM "Permission" INNER JOIN "Group_Members" ON "Permission"."GroupID" = "Group_Members"."GroupID" WHERE "Permission"."Code" = ? AND "Permission"."Type" = ? AND "Group_Members"."MemberID" = ?', array('ADMIN', Permission::GRANT_PERMISSION, $memberID))->value(); if ($permission) { return; } } // This basically does the same as // Security::permissionFailure(null, "You need to login with developer access to make use of debugging tools.") // We have to do this because of how early this method is called in execution. $_SESSION['SilverStripe\\Security\\Security']['Message']['message'] = "You need to login with developer access to make use of debugging tools."; $_SESSION['SilverStripe\\Security\\Security']['Message']['type'] = 'warning'; $_SESSION['BackURL'] = $_SERVER['REQUEST_URI']; header($_SERVER['SERVER_PROTOCOL'] . " 302 Found"); header("Location: " . Director::baseURL() . Security::login_url()); die; }
/** * Get the URL of the logout page. * * To update the logout url use the "Security.logout_url" config setting. * * @return string */ public static function lost_password_url() { return Controller::join_links(Director::baseURL(), self::config()->lost_password_url); }
/** * Returns the Absolute URL of the site root, embedding the current basic-auth credentials into * the URL. * * @return string */ public static function absoluteBaseURLWithAuth() { $login = ""; if (isset($_SERVER['PHP_AUTH_USER'])) { $login = "******"; } return Director::protocol() . $login . $_SERVER['HTTP_HOST'] . Director::baseURL(); }
public function Link($action = null) { /** @skipUpgrade */ return Controller::join_links(Director::baseURL(), "CMSSecurity", $action); }
public function inst_destroy($removeCookie = true) { if (session_id()) { if ($removeCookie) { $path = Config::inst()->get('SilverStripe\\Control\\Session', 'cookie_path') ?: Director::baseURL(); $domain = Config::inst()->get('SilverStripe\\Control\\Session', 'cookie_domain'); $secure = Config::inst()->get('SilverStripe\\Control\\Session', 'cookie_secure'); Cookie::force_expiry(session_name(), $path, $domain, $secure, true); } session_destroy(); // Clean up the superglobal - session_destroy does not do it. // http://nz1.php.net/manual/en/function.session-destroy.php unset($_SESSION); $this->data = array(); } }
public function testRedirectBackByBackUrl() { $internalRelativeUrl = Controller::join_links(Director::baseURL(), '/some-url'); $internalAbsoluteUrl = Controller::join_links(Director::absoluteBaseURL(), '/some-url'); $response = $this->get('ControllerTest_Controller/redirectbacktest?BackURL=' . urlencode($internalRelativeUrl)); $this->assertEquals(302, $response->getStatusCode()); $this->assertEquals($internalAbsoluteUrl, $response->getHeader('Location'), "Redirects on internal relative URLs"); $internalAbsoluteUrl = Director::absoluteBaseURL() . '/some-url'; $response = $this->get('ControllerTest_Controller/redirectbacktest?BackURL=' . urlencode($internalAbsoluteUrl)); $this->assertEquals($internalAbsoluteUrl, $response->getHeader('Location')); $this->assertEquals(302, $response->getStatusCode(), "Redirects on internal absolute URLs"); $externalAbsoluteUrl = 'http://myhost.com/some-url'; $response = $this->get('ControllerTest_Controller/redirectbacktest?BackURL=' . urlencode($externalAbsoluteUrl)); $this->assertEquals(200, $response->getStatusCode(), "Doesn't redirect on external URLs"); }
/** * Provide secure downloadable * * @param string $path * @return string|null */ public function getProtectedUrl($path) { // Public URLs are handled via a request handler within /assets. // If assets are stored locally, then asset paths of protected files should be equivalent. return Controller::join_links(Director::baseURL(), ASSETS_DIR, $path); }
public function testCommentedOutScriptTagIsIgnored() { $template = '<html><head></head><body><!--<script>alert("commented out");</script>-->' . '<h1>more content</h1></body></html>'; /** @var Requirements_Backend $backend */ $backend = Injector::inst()->create('SilverStripe\\View\\Requirements_Backend'); $this->setupRequirements($backend); $backend->setSuffixRequirements(false); $src = $this->getCurrentRelativePath() . '/RequirementsTest_a.js'; $urlSrc = ControllerTest_ContainerController::join_links(Director::baseURL(), $src); $backend->javascript($src); $html = $backend->includeInHTML($template); $this->assertEquals('<html><head></head><body><!--<script>alert("commented out");</script>-->' . '<h1>more content</h1><script type="application/javascript" src="' . $urlSrc . '"></script></body></html>', $html); }
public function testForceSSLAlternateDomain() { Config::inst()->update('SilverStripe\\Control\\Director', 'alternate_base_url', '/'); $_SERVER['REQUEST_URI'] = Director::baseURL() . 'admin'; $output = Director::forceSSL(array('/^admin/'), 'secure.mysite.com'); $this->assertEquals($output, 'https://secure.mysite.com/admin'); }