XHR: Force redirect to login if session is expired

resolves #5507
This commit is contained in:
Eric Lippmann 2014-01-23 16:03:47 +01:00
parent a64c20f933
commit 2242973568
5 changed files with 65 additions and 53 deletions

View File

@ -30,11 +30,11 @@
# namespace Icinga\Application\Controllers; # namespace Icinga\Application\Controllers;
use \Icinga\Web\Controller\ActionController; use Icinga\Web\Controller\ActionController;
use \Icinga\Authentication\Credential; use Icinga\Authentication\Credential;
use \Icinga\Authentication\Manager as AuthManager; use Icinga\Authentication\Manager as AuthManager;
use \Icinga\Form\Authentication\LoginForm; use Icinga\Form\Authentication\LoginForm;
use \Icinga\Exception\ConfigurationError; use Icinga\Exception\ConfigurationError;
/** /**
* Application wide controller for authentication * Application wide controller for authentication
@ -42,7 +42,7 @@ use \Icinga\Exception\ConfigurationError;
class AuthenticationController extends ActionController class AuthenticationController extends ActionController
{ {
/** /**
* This controller handles authentication * This controller does not require authentication
* *
* @var bool * @var bool
*/ */
@ -53,33 +53,26 @@ class AuthenticationController extends ActionController
*/ */
public function loginAction() public function loginAction()
{ {
$credentials = new Credential();
$this->_helper->layout->setLayout('login'); $this->_helper->layout->setLayout('login');
$this->view->form = new LoginForm(); $this->view->form = new LoginForm();
$this->view->form->setRequest($this->_request); $this->view->form->setRequest($this->_request);
$this->view->title = "Icinga Web Login"; $this->view->title = 'Icinga Web Login';
try { try {
$redirectUrl = $this->_request->getParam('redirect', 'index?_render=body');
$auth = AuthManager::getInstance(); $auth = AuthManager::getInstance();
if ($auth->isAuthenticated()) { if ($auth->isAuthenticated()) {
$this->redirectNow('index?_render=body'); $this->redirectNow($redirectUrl);
} }
if ($this->view->form->isSubmittedAndValid()) { if ($this->view->form->isSubmittedAndValid()) {
$credentials->setUsername($this->view->form->getValue('username')); $credentials = new Credential(
$credentials->setPassword($this->view->form->getValue('password')); $this->view->form->getValue('username'),
$this->view->form->getValue('password')
);
if (!$auth->authenticate($credentials)) { if (!$auth->authenticate($credentials)) {
$this->view->form->getElement('password') $this->view->form->getElement('password')
->addError(t('Please provide a valid username and password')); ->addError(t('Please provide a valid username and password'));
} else { } else {
$redirectUrl = $this->_request->getParam('redirect'); $this->redirectNow($redirectUrl);
if ($redirectUrl == null) {
$this->redirectNow('index?_render=body');
} else {
$this->redirectNow($redirectUrl);
}
} }
} }
} catch (ConfigurationError $configError) { } catch (ConfigurationError $configError) {

View File

@ -42,7 +42,8 @@ class ErrorController extends ActionController
*/ */
public function errorAction() public function errorAction()
{ {
$error = $this->_getParam('error_handler'); $error = $this->_getParam('error_handler');
$exception = $error->exception;
switch ($error->type) { switch ($error->type) {
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE: case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE:
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER: case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
@ -52,11 +53,11 @@ class ErrorController extends ActionController
break; break;
default: default:
$this->getResponse()->setHttpResponseCode(500); $this->getResponse()->setHttpResponseCode(500);
$this->view->message = $error->exception->getMessage(); $this->view->message = $exception->getMessage();
break; break;
} }
if ($this->getInvokeArg('displayExceptions') == true) { if ($this->getInvokeArg('displayExceptions') == true) {
$this->view->stackTrace = $error->exception->getTraceAsString(); $this->view->stackTrace = $exception->getTraceAsString();
} }
$this->view->request = $error->request; $this->view->request = $error->request;
} }

View File

@ -36,13 +36,13 @@ use \Zend_Controller_Front;
use \Zend_Controller_Response_Abstract; use \Zend_Controller_Response_Abstract;
use \Zend_Controller_Action_HelperBroker; use \Zend_Controller_Action_HelperBroker;
use \Zend_Layout; use \Zend_Layout;
use \Icinga\Authentication\Manager as AuthManager; use Icinga\Authentication\Manager as AuthManager;
use \Icinga\Application\Benchmark; use Icinga\Application\Benchmark;
use \Icinga\Application\Config; use Icinga\Application\Config;
use \Icinga\Web\Notification; use Icinga\Web\Notification;
use \Icinga\Web\Widget\Tabs; use Icinga\Web\Widget\Tabs;
use \Icinga\Web\Url; use Icinga\Web\Url;
use \Icinga\Web\Request; use Icinga\Web\Request;
/** /**
* Base class for all core action controllers * Base class for all core action controllers
@ -173,14 +173,15 @@ class ActionController extends Zend_Controller_Action
protected function redirectToLogin($afterLogin = '/index') protected function redirectToLogin($afterLogin = '/index')
{ {
if ($this->getRequest()->isXmlHttpRequest()) { if ($this->getRequest()->isXmlHttpRequest()) {
$this->_response->setHttpResponseCode(401);
$this->getResponse()->setHttpResponseCode(401); $this->_helper->json(array(
$this->getResponse()->sendHeaders(); 'exception' => 'You are not logged in',
throw new Exception("You are not logged in"); 'redirectTo' => Url::fromPath('/authentication/login')->getAbsoluteUrl()
));
} }
$url = Url::fromPath('/authentication/login'); $url = Url::fromPath('/authentication/login');
$url->setParam('redirect', $afterLogin); $url->setParam('redirect', $afterLogin);
$this->redirectNow($url->getRelativeUrl()); $this->redirectNow($url);
} }
/** /**

View File

@ -29,7 +29,7 @@
define(['jquery', 'logging', 'icinga/componentLoader', 'URIjs/URI', 'URIjs/URITemplate', 'icinga/util/url'], define(['jquery', 'logging', 'icinga/componentLoader', 'URIjs/URI', 'URIjs/URITemplate', 'icinga/util/url'],
function($, logger, componentLoader, URI, Tpl, urlMgr) { function($, logger, componentLoader, URI, Tpl, urlMgr) {
"use strict"; 'use strict';
var Icinga; var Icinga;
@ -194,22 +194,29 @@ define(['jquery', 'logging', 'icinga/componentLoader', 'URIjs/URI', 'URIjs/URITe
cancelPendingRequest(); cancelPendingRequest();
this.containerDom.trigger('showLoadIndicator'); this.containerDom.trigger('showLoadIndicator');
pendingDetailRequest = $.ajax({ pendingDetailRequest = $.ajax({
'url' : url, 'url': url,
'data' : { 'data': {
'render' : 'detail' 'render': 'detail'
} },
}); 'context': this
pendingDetailRequest.done( })
(function(response) { .done(function (response) {
pendingDetailRequest = null; pendingDetailRequest = null;
this.replaceDom($(response)); this.replaceDom($(response));
}).bind(this) })
).fail( .fail(function (response, reason) {
(function(response, reason) {
if (reason === 'abort') { if (reason === 'abort') {
return; return;
} }
if (response.statusCode().status === 401) {
var error = JSON.parse(response.responseText);
window.location.replace(
URI(error.redirectTo).search({
redirect: URI(urlMgr.getUrl()).resource().replace(new RegExp('^' + window.base_url), '')
})
);
return;
}
var errorReason; var errorReason;
if (response.statusCode.toString()[0] === '4') { if (response.statusCode.toString()[0] === '4') {
errorReason = 'The Requested View Couldn\'t Be Found<br/>'; errorReason = 'The Requested View Couldn\'t Be Found<br/>';
@ -217,10 +224,10 @@ define(['jquery', 'logging', 'icinga/componentLoader', 'URIjs/URI', 'URIjs/URITe
errorReason = response.responseText; errorReason = response.responseText;
} }
this.replaceDom(response.responseText); this.replaceDom(response.responseText);
}).bind(this) })
).always((function() { .always(function () {
this.containerDom.trigger('hideLoadIndicator'); this.containerDom.trigger('hideLoadIndicator');
}).bind(this)); });
}; };
this.getUrl = function() { this.getUrl = function() {

View File

@ -31,7 +31,8 @@
* Dashboard container, uses freetile for layout * Dashboard container, uses freetile for layout
* *
*/ */
define(['jquery', 'logging', 'URIjs/URI', 'icinga/componentLoader'], function($, log, URI, components) { define(['jquery', 'logging', 'URIjs/URI', 'icinga/componentLoader', 'icinga/util/url'],
function($, log, URI, components, urlMgr) {
'use strict'; 'use strict';
return function(parent) { return function(parent) {
this.dom = $(parent); this.dom = $(parent);
@ -55,6 +56,15 @@ define(['jquery', 'logging', 'URIjs/URI', 'icinga/componentLoader'], function($,
components.load(); components.load();
}) })
.fail(function (response, reason) { .fail(function (response, reason) {
if (response.statusCode().status === 401) {
var error = JSON.parse(response.responseText);
window.location.replace(
URI(error.redirectTo).search({
redirect: URI(urlMgr.getUrl()).resource().replace(new RegExp('^' + window.base_url), '')
})
);
return;
}
this.container.html(response.responseText); this.container.html(response.responseText);
}) })
.always(function () { .always(function () {