Merge branch 'bugfix/logout-external-8626'

fixes #8626
This commit is contained in:
Eric Lippmann 2015-03-12 16:47:49 +01:00
commit 29d5fd351b
5 changed files with 94 additions and 96 deletions

View File

@ -102,21 +102,21 @@ class AuthenticationController extends ActionController
$this->view->form->addError(
$this->translate(
'No authentication methods available. Did you create'
. ' authentication.ini when setting up Icinga Web 2?'
. ' authentication.ini when setting up Icinga Web 2?'
)
);
} else if ($backendsTried === $backendsWithError) {
$this->view->form->addError(
$this->translate(
'All configured authentication methods failed.'
. ' Please check the system log or Icinga Web 2 log for more information.'
. ' Please check the system log or Icinga Web 2 log for more information.'
)
);
} elseif ($backendsWithError) {
$this->view->form->addError(
$this->translate(
'Please note that not all authentication methods were available.'
. ' Check the system log or Icinga Web 2 log for more information.'
. ' Check the system log or Icinga Web 2 log for more information.'
)
);
}
@ -144,7 +144,7 @@ class AuthenticationController extends ActionController
$this->view->form->addError($e->getMessage());
}
$this->view->requiresExternalAuth = $triedOnlyExternalAuth && !$auth->isAuthenticated();
$this->view->requiresExternalAuth = $triedOnlyExternalAuth && ! $auth->isAuthenticated();
$this->view->requiresSetup = Icinga::app()->requiresSetup();
}

View File

@ -9,39 +9,39 @@
-->
<div class="content">
<div class="alert alert-warning" id="logout-status">
<b> <?= t('Logging out...'); ?> </b> <br />
<?= t(
'If this message does not disappear, it might be necessary to quit the ' .
'current session manually by clearing the cache, or by closing the current ' .
'browser session.'
<b><?= $this->translate('Logging out...'); ?></b>
<br>
<?= $this->translate(
'If this message does not disappear, it might be necessary to quit the'
. ' current session manually by clearing the cache, or by closing the current'
. ' browser session.'
); ?>
</div>
<div class="container" >
<a href="<?= $this->href('dashboard/index'); ?>"> <?= t('Login'); ?></a>
<div class="container">
<a href="<?= $this->href('dashboard/index?renderLayout'); ?>"><?= $this->translate('Login'); ?></a>
</div>
</div>
<script type="text/javascript">
/**
/*
* When JavaScript is available, trigger an XmlHTTPRequest with the non-existing user 'logout' and abort it
* before it is able to finish. This will cause the browser to show a new authentication prompt in the next
* request.
*/
$(document).ready(function() {
msg = $('#logout-status');
document.addEventListener('DOMContentLoaded', function () {
var msg = document.getElementById('logout-status');
try {
if (navigator.userAgent.toLowerCase().indexOf('msie') !== -1) {
document.execCommand('ClearAuthenticationCache');
} else {
var xhttp = getXMLHttpRequest();
var xhttp = new XMLHttpRequest();
xhttp.open('GET', 'arbitrary url', true, 'logout', 'logout');
xhttp.send('');
xhttp.abort();
}
} catch (e) {
}
msg.html('<?= t('Logout successful!'); ?>');
msg.removeClass();
msg.addClass('alert alert-success');
msg.innerHTML = '<?= $this->translate('Logout successful!'); ?>';
msg.className = 'alert alert-success';
});
</script>

View File

@ -5,28 +5,22 @@ namespace Icinga\Application;
require_once __DIR__ . '/ApplicationBootstrap.php';
use Icinga\Authentication\Manager as AuthenticationManager;
use Icinga\Authentication\Manager;
use Icinga\Exception\ConfigurationError;
use Icinga\Exception\NotReadableError;
use Icinga\Application\Logger;
use Icinga\Util\TimezoneDetect;
use Icinga\Web\Request;
use Icinga\Web\Response;
use Icinga\Web\View;
use Icinga\Web\Session\Session as BaseSession;
use Icinga\Web\Session;
use Icinga\User;
use Icinga\Util\Translator;
use Icinga\Util\DateTimeFactory;
use DateTimeZone;
use Exception;
use Zend_Controller_Action_HelperBroker;
use Zend_Controller_Front;
use Zend_Controller_Router_Route;
use Zend_Layout;
use Zend_Paginator;
use Zend_View_Helper_PaginationControl;
use Zend_Controller_Action_HelperBroker as ActionHelperBroker;
use Zend_Controller_Router_Route;
use Zend_Controller_Front;
use Icinga\Application\Logger;
use Icinga\Authentication\Manager;
use Icinga\User;
use Icinga\Util\TimezoneDetect;
use Icinga\Util\Translator;
use Icinga\Web\Request;
use Icinga\Web\Response;
use Icinga\Web\Session;
use Icinga\Web\Session\Session as BaseSession;
use Icinga\Web\View;
/**
* Use this if you want to make use of Icinga functionality in other web projects
@ -84,7 +78,7 @@ class Web extends ApplicationBootstrap
/**
* Initialize all together
*
* @return self
* @return $this
*/
protected function bootstrap()
{
@ -112,7 +106,7 @@ class Web extends ApplicationBootstrap
/**
* Prepare routing
*
* @return self
* @return $this
*/
private function setupRoute()
{
@ -161,44 +155,39 @@ class Web extends ApplicationBootstrap
/**
* Prepare Zend MVC Base
*
* @return self
* @return $this
*/
private function setupZendMvc()
{
// TODO: Replace Zend_Application:
Zend_Layout::startMvc(
array(
'layout' => 'layout',
'layoutPath' => $this->getApplicationDir('/layouts/scripts')
)
);
$this->setupFrontController();
$this->setupViewRenderer();
return $this;
}
/**
* Create user object
*
* @return self
* @return $this
*/
private function setupUser()
{
$authenticationManager = AuthenticationManager::getInstance();
if ($authenticationManager->isAuthenticated() === true) {
$this->user = $authenticationManager->getUser();
$auth = Manager::getInstance();
if ($auth->isAuthenticated()) {
$this->user = $auth->getUser();
}
return $this;
}
/**
* Initialize a session provider
*
* @return self
* @return $this
*/
private function setupSession()
{
@ -209,82 +198,68 @@ class Web extends ApplicationBootstrap
/**
* Inject dependencies into request
*
* @return self
* @return $this
*/
private function setupRequest()
{
$this->request = new Request();
if ($this->user instanceof User) {
$this->request->setUser($this->user);
}
return $this;
}
/**
* Instantiate front controller
*
* @return self
* @return $this
*/
private function setupFrontController()
{
$this->frontController = Zend_Controller_Front::getInstance();
$this->frontController->setRequest($this->request);
$this->frontController->setControllerDirectory($this->getApplicationDir('/controllers'));
$this->frontController->setParams(
array(
'displayExceptions' => true
)
);
return $this;
}
/**
* Register helper paths and views for renderer
*
* @return self
* @return $this
*/
private function setupViewRenderer()
{
$view = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
/** @var \Zend_Controller_Action_Helper_ViewRenderer $view */
$view = ActionHelperBroker::getStaticHelper('viewRenderer');
$view->setView(new View());
$view->view->addHelperPath($this->getApplicationDir('/views/helpers'));
$view->view->setEncoding('UTF-8');
$view->view->headTitle()->prepend($this->config->get('global', 'project', 'Icinga'));
$view->view->headTitle()->setSeparator(' :: ');
$this->viewRenderer = $view;
return $this;
}
/**
* Configure pagination settings
*
* @return self
* @return $this
*/
private function setupPagination()
{
Zend_Paginator::addScrollingStylePrefixPath(
'Icinga_Web_Paginator_ScrollingStyle',
'Icinga/Web/Paginator/ScrollingStyle'
);
Zend_Paginator::setDefaultScrollingStyle('SlidingWithBorder');
Zend_View_Helper_PaginationControl::setDefaultViewPartial(
array('mixedPagination.phtml', 'default')
);
return $this;
}
@ -330,7 +305,7 @@ class Web extends ApplicationBootstrap
/**
* Setup an autoloader namespace for Icinga\Forms
*
* @return self
* @return $this
*/
private function setupFormNamespace()
{
@ -341,4 +316,3 @@ class Web extends ApplicationBootstrap
return $this;
}
}
// @codeCoverageIgnoreEnd

View File

@ -293,34 +293,31 @@ class ActionController extends Zend_Controller_Action
}
/**
* Redirect to the login path
* Redirect to login
*
* @param Url $afterLogin The action to call when the login was successful. Defaults to '/index/welcome'
* XHR will always redirect to __SELF__ if an URL to redirect to after successful login is set. __SELF__ instructs
* JavaScript to redirect to the current window's URL if it's an auto-refresh request or to redirect to the URL
* which required login if it's not an auto-refreshing one.
*
* @throws \Exception
* XHR will respond with HTTP status code 403 Forbidden.
*
* @param Url|string $redirect URL to redirect to after successful login
*/
protected function redirectToLogin($afterLogin = null)
protected function redirectToLogin($redirect = null)
{
$redir = null;
if ($afterLogin !== null) {
if (! $afterLogin instanceof Url) {
$afterLogin = Url::fromPath($afterLogin);
$login = Url::fromPath('authentication/login');
if ($this->isXhr()) {
if ($redirect !== null) {
$login->setParam('redirect', '__SELF__');
}
if ($this->isXhr()) {
$redir = '__SELF__';
} else {
// TODO: Ignore /?
$redir = $afterLogin->getRelativeUrl();
$this->_response->setHttpResponseCode(403);
} elseif ($redirect !== null) {
if (! $redirect instanceof Url) {
$redirect = Url::fromPath($redirect);
}
$login->setParam('redirect', $redirect->getRelativeUrl());
}
$url = Url::fromPath('authentication/login');
if ($redir) {
$url->setParam('redirect', $redir);
}
$this->rerenderLayout()->redirectNow($url);
$this->rerenderLayout()->redirectNow($login);
}
protected function rerenderLayout()

View File

@ -245,14 +245,41 @@
}
},
/**
* Process the X-Icinga-Redirect HTTP Response Header
*
* If the response includes the X-Icinga-Redirect header, redirects to the URL associated with the header.
*
* @param {object} req Current request
*
* @returns {boolean} Whether we're about to redirect
*/
processRedirectHeader: function(req) {
var icinga = this.icinga;
var redirect = req.getResponseHeader('X-Icinga-Redirect');
if (! redirect) return false;
var icinga = this.icinga,
redirect = req.getResponseHeader('X-Icinga-Redirect');
if (! redirect) {
return false;
}
redirect = decodeURIComponent(redirect);
if (redirect.match(/__SELF__/)) {
redirect = redirect.replace(/__SELF__/, encodeURIComponent(document.location.pathname + document.location.search + document.location.hash));
if (req.autorefresh) {
// Redirect to the current window's URL in case it's an auto-refresh request. If authenticated
// externally this ensures seamless re-login if the session's expired
redirect = redirect.replace(
/__SELF__/,
encodeURIComponent(
document.location.pathname + document.location.search + document.location.hash
)
);
} else {
// Redirect to the URL which required authentication. When clicking a link this ensures that we
// redirect to the link's URL instead of the current window's URL (see above)
redirect = redirect.replace(/__SELF__/, req.url);
}
}
icinga.logger.debug(
'Got redirect for ', req.$target, ', URL was ' + redirect
);