mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
5c9044a007
API Introduce HTMLFragment as casting helper for HTMLText with shortcodes disabled API Introduce DBField::CDATA for XML file value encoding API RSSFeed now casts from the underlying model rather than by override API Introduce CustomMethods::getExtraMethodConfig() to allow metadata to be queried BUG Remove _call hack from VirtualPage API Remove FormField::$dontEscape API Introduce HTMLReadonlyField for non-editable readonly HTML API FormField::Field() now returns string in many cases rather than DBField instance. API Remove redundant *_val methods from ViewableData API ViewableData::obj() no longer has a $forceReturnObject parameter as it always returns an object BUG Fix issue with ViewableData caching incorrect field values after being modified. API Remove deprecated DB class methods API Enforce plain text left/right formfield titles
235 lines
6.0 KiB
PHP
235 lines
6.0 KiB
PHP
<?php
|
|
|
|
namespace SilverStripe\Security;
|
|
|
|
use Requirements;
|
|
use Controller;
|
|
use Director;
|
|
use Convert;
|
|
use Session;
|
|
use AdminRootController;
|
|
use SS_HTTPResponse;
|
|
|
|
|
|
/**
|
|
* Provides a security interface functionality within the cms
|
|
* @package framework
|
|
* @subpackage security
|
|
*/
|
|
class CMSSecurity extends Security {
|
|
|
|
private static $casting = array(
|
|
'Title' => 'HTMLFragment'
|
|
);
|
|
|
|
private static $allowed_actions = array(
|
|
'SilverStripe\\Security\\LoginForm',
|
|
'success'
|
|
);
|
|
|
|
/**
|
|
* Enable in-cms reauthentication
|
|
*
|
|
* @var boolean
|
|
* @config
|
|
*/
|
|
private static $reauth_enabled = true;
|
|
|
|
protected function init() {
|
|
parent::init();
|
|
|
|
// Include CMS styles and js
|
|
Requirements::css(THIRDPARTY_DIR . '/jquery-ui-themes/smoothness/jquery-ui.css');
|
|
Requirements::css(FRAMEWORK_ADMIN_DIR . '/client/dist/styles/bundle.css');
|
|
Requirements::combine_files(
|
|
'cmssecurity.js',
|
|
array(
|
|
THIRDPARTY_DIR . '/jquery/jquery.js',
|
|
THIRDPARTY_DIR . '/jquery-ui/jquery-ui.js',
|
|
THIRDPARTY_DIR . '/jquery-entwine/dist/jquery.entwine-dist.js',
|
|
FRAMEWORK_ADMIN_DIR . '/client/dist/js/sspath.js',
|
|
FRAMEWORK_ADMIN_DIR . '/client/dist/js/CMSSecurity.js'
|
|
)
|
|
);
|
|
}
|
|
|
|
public function Link($action = null) {
|
|
/** @skipUpgrade */
|
|
return Controller::join_links(Director::baseURL(), "CMSSecurity", $action);
|
|
}
|
|
|
|
/**
|
|
* Get known logged out member
|
|
*
|
|
* @return Member
|
|
*/
|
|
public function getTargetMember() {
|
|
if($tempid = $this->getRequest()->requestVar('tempid')) {
|
|
return Member::member_from_tempid($tempid);
|
|
}
|
|
}
|
|
|
|
public function getResponseController($title) {
|
|
// Use $this to prevent use of Page to render underlying templates
|
|
return $this;
|
|
}
|
|
|
|
protected function getLoginMessage(&$messageType = null) {
|
|
return parent::getLoginMessage($messageType)
|
|
?: _t(
|
|
'CMSSecurity.LoginMessage',
|
|
'<p>If you have any unsaved work you can return to where you left off by logging back in below.</p>'
|
|
);
|
|
}
|
|
|
|
public function getTitle() {
|
|
// Check if logged in already
|
|
if(Member::currentUserID()) {
|
|
return _t('CMSSecurity.SUCCESS', 'Success');
|
|
}
|
|
|
|
// Display logged-out message
|
|
$member = $this->getTargetMember();
|
|
if($member) {
|
|
return _t(
|
|
'CMSSecurity.TimedOutTitleMember',
|
|
'Hey {name}!<br />Your session has timed out.',
|
|
'Title for CMS popup login form for a known user',
|
|
array('name' => $member->FirstName)
|
|
);
|
|
} else {
|
|
return _t(
|
|
'CMSSecurity.TimedOutTitleAnonymous',
|
|
'Your session has timed out.',
|
|
'Title for CMS popup login form without a known user'
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Redirects the user to the external login page
|
|
*
|
|
* @return SS_HTTPResponse
|
|
*/
|
|
protected function redirectToExternalLogin() {
|
|
$loginURL = Security::create()->Link('login');
|
|
$loginURLATT = Convert::raw2att($loginURL);
|
|
$loginURLJS = Convert::raw2js($loginURL);
|
|
$message = _t(
|
|
'CMSSecurity.INVALIDUSER',
|
|
'<p>Invalid user. <a target="_top" href="{link}">Please re-authenticate here</a> to continue.</p>',
|
|
'Message displayed to user if their session cannot be restored',
|
|
array('link' => $loginURLATT)
|
|
);
|
|
$response = $this->getResponse();
|
|
$response->setStatusCode(200);
|
|
$response->setBody(<<<PHP
|
|
<!DOCTYPE html>
|
|
<html><body>
|
|
$message
|
|
<script type="application/javascript">
|
|
setTimeout(function(){top.location.href = "$loginURLJS";}, 0);
|
|
</script>
|
|
</body></html>
|
|
PHP
|
|
);
|
|
$this->setResponse($response);
|
|
return $response;
|
|
}
|
|
|
|
protected function preLogin() {
|
|
// If no member has been previously logged in for this session, force a redirect to the main login page
|
|
if(!$this->getTargetMember()) {
|
|
return $this->redirectToExternalLogin();
|
|
}
|
|
|
|
return parent::preLogin();
|
|
}
|
|
|
|
public function GetLoginForms() {
|
|
$forms = array();
|
|
$authenticators = Authenticator::get_authenticators();
|
|
foreach($authenticators as $authenticator) {
|
|
// Get only CMS-supporting authenticators
|
|
if($authenticator::supports_cms()) {
|
|
$forms[] = $authenticator::get_cms_login_form($this);
|
|
}
|
|
}
|
|
return $forms;
|
|
}
|
|
|
|
/**
|
|
* Determine if CMSSecurity is enabled
|
|
*
|
|
* @return bool
|
|
*/
|
|
public static function enabled() {
|
|
// Disable shortcut
|
|
if(!static::config()->reauth_enabled) return false;
|
|
|
|
// Count all cms-supported methods
|
|
$authenticators = Authenticator::get_authenticators();
|
|
foreach($authenticators as $authenticator) {
|
|
// Supported if at least one authenticator is supported
|
|
if($authenticator::supports_cms()) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public function LoginForm() {
|
|
$authenticator = $this->getAuthenticator();
|
|
if($authenticator && $authenticator::supports_cms()) {
|
|
return $authenticator::get_cms_login_form($this);
|
|
}
|
|
user_error('Passed invalid authentication method', E_USER_ERROR);
|
|
}
|
|
|
|
public function getTemplatesFor($action) {
|
|
return array("CMSSecurity_{$action}", "SilverStripe\\Security\\CMSSecurity")
|
|
+ parent::getTemplatesFor($action);
|
|
}
|
|
|
|
public function getIncludeTemplate($name) {
|
|
return array("CMSSecurity_{$name}")
|
|
+ parent::getIncludeTemplate($name);
|
|
}
|
|
|
|
/**
|
|
* Given a successful login, tell the parent frame to close the dialog
|
|
*
|
|
* @return SS_HTTPResponse
|
|
*/
|
|
public function success() {
|
|
// Ensure member is properly logged in
|
|
if(!Member::currentUserID()) {
|
|
return $this->redirectToExternalLogin();
|
|
}
|
|
|
|
// Get redirect url
|
|
$controller = $this->getResponseController(_t('CMSSecurity.SUCCESS', 'Success'));
|
|
$backURLs = array(
|
|
$this->getRequest()->requestVar('BackURL'),
|
|
Session::get('BackURL'),
|
|
Director::absoluteURL(AdminRootController::config()->url_base, true),
|
|
);
|
|
foreach ($backURLs as $backURL) {
|
|
if ($backURL && Director::is_site_url($backURL)) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Show login
|
|
$controller = $controller->customise(array(
|
|
'Content' => _t(
|
|
'CMSSecurity.SUCCESSCONTENT',
|
|
'<p>Login success. If you are not automatically redirected '.
|
|
'<a target="_top" href="{link}">click here</a></p>',
|
|
'Login message displayed in the cms popup once a user has re-authenticated themselves',
|
|
array('link' => $backURL)
|
|
)
|
|
));
|
|
|
|
return $controller->renderWith($this->getTemplatesFor('success'));
|
|
}
|
|
}
|