Fetch and clean user messages lazily, to ensure that only shown messages are removed

This will make the code of the ConfigController way easier, as messages can be
send from everywhere and there is no need to consider consquences of
redirections.

refs #5100
This commit is contained in:
Matthias Jentsch 2013-11-26 10:35:46 +01:00
parent 2a0add3ec3
commit cd0194e20f
4 changed files with 66 additions and 76 deletions

View File

@ -5,7 +5,6 @@
* This file is part of Icinga Web 2. * This file is part of Icinga Web 2.
* *
* Icinga Web 2 - Head for multiple monitoring backends. * Icinga Web 2 - Head for multiple monitoring backends.
* Copyright (C) 2013 Icinga Development Team
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -59,7 +58,6 @@ class ConfigController extends BaseConfigController
*/ */
private $resourceTypes = array('livestatus', 'ido', 'statusdat', 'ldap'); private $resourceTypes = array('livestatus', 'ido', 'statusdat', 'ldap');
/** /**
* Create tabs for this configuration controller * Create tabs for this configuration controller
* *
@ -113,8 +111,7 @@ class ConfigController extends BaseConfigController
*/ */
public function indexAction() public function indexAction()
{ {
$this->view->messageBox = new AlertMessageBox($this->getAndClearMessages()); $this->view->messageBox = new AlertMessageBox(true);
$form = new GeneralForm(); $form = new GeneralForm();
$form->setConfiguration(IcingaConfig::app()); $form->setConfiguration(IcingaConfig::app());
$form->setRequest($this->_request); $form->setRequest($this->_request);
@ -134,7 +131,7 @@ class ConfigController extends BaseConfigController
*/ */
public function loggingAction() public function loggingAction()
{ {
$this->view->messageBox = new AlertMessageBox($this->getAndClearMessages()); $this->view->messageBox = new AlertMessageBox(true);
$form = new LoggingForm(); $form = new LoggingForm();
$form->setConfiguration(IcingaConfig::app()); $form->setConfiguration(IcingaConfig::app());
@ -155,9 +152,8 @@ class ConfigController extends BaseConfigController
*/ */
public function moduleoverviewAction() public function moduleoverviewAction()
{ {
$this->view->messageBox = new AlertMessageBox($this->getAndClearMessages()); $this->view->messageBox = new AlertMessageBox(true);
$this->view->messages = $this->getAndClearMessages();
$this->view->modules = Icinga::app()->getModuleManager()->select() $this->view->modules = Icinga::app()->getModuleManager()->select()
->from('modules') ->from('modules')
->order('name'); ->order('name');
@ -213,7 +209,7 @@ class ConfigController extends BaseConfigController
$config = IcingaConfig::app('authentication', true); $config = IcingaConfig::app('authentication', true);
$order = array_keys($config->toArray()); $order = array_keys($config->toArray());
$this->view->backends = array(); $this->view->backends = array();
$this->view->messageBox = new AlertMessageBox($this->getAndClearMessages()); $this->view->messageBox = new AlertMessageBox(true);
foreach ($config as $backend=>$backendConfig) { foreach ($config as $backend=>$backendConfig) {
$form = new ReorderForm(); $form = new ReorderForm();
@ -243,7 +239,7 @@ class ConfigController extends BaseConfigController
*/ */
public function createauthenticationbackendAction() public function createauthenticationbackendAction()
{ {
$this->view->messageBox = new AlertMessageBox(); $this->view->messageBox = new AlertMessageBox(true);
if ($this->getRequest()->getParam('type') === 'ldap') { if ($this->getRequest()->getParam('type') === 'ldap') {
$form = new LdapBackendForm(); $form = new LdapBackendForm();
@ -263,7 +259,7 @@ class ConfigController extends BaseConfigController
foreach ($form->getConfig() as $backendName => $settings) { foreach ($form->getConfig() as $backendName => $settings) {
unset($settings->{'name'}); unset($settings->{'name'});
if (isset($backendCfg[$backendName])) { if (isset($backendCfg[$backendName])) {
$this->view->messageBox->addError('Backend name already exists'); $this->addErrorMessage('Backend name already exists');
$this->view->form = $form; $this->view->form = $form;
$this->render('authentication/create'); $this->render('authentication/create');
return; return;
@ -292,6 +288,8 @@ class ConfigController extends BaseConfigController
*/ */
public function editauthenticationbackendAction() public function editauthenticationbackendAction()
{ {
$this->view->messageBox = new AlertMessageBox(true);
$configArray = IcingaConfig::app('authentication', true)->toArray(); $configArray = IcingaConfig::app('authentication', true)->toArray();
$authBackend = $this->getParam('auth_backend'); $authBackend = $this->getParam('auth_backend');
if (!isset($configArray[$authBackend])) { if (!isset($configArray[$authBackend])) {
@ -354,21 +352,12 @@ class ConfigController extends BaseConfigController
*/ */
public function removeauthenticationbackendAction() public function removeauthenticationbackendAction()
{ {
$this->view->messageBox = new AlertMessageBox(); $this->view->messageBox = new AlertMessageBox(true);
$configArray = IcingaConfig::app('authentication', true)->toArray(); $configArray = IcingaConfig::app('authentication', true)->toArray();
$authBackend = $this->getParam('auth_backend'); $authBackend = $this->getParam('auth_backend');
if (!isset($configArray[$authBackend])) { if (!isset($configArray[$authBackend])) {
$this->view->messageBox->addMessage( $this->addSuccessMessage('Can\'t perform removal: Unknown Authentication Backend Provided');
new Message('Can\'t perform removal: Unknown Authentication Backend Provided', Zend_Log::ERR)
);
$this->render('authentication/remove');
return;
}
if (!array_key_exists('resource', $configArray[$authBackend])) {
$this->view->messageBox->addMessage(
new Message('Configuration error: Backend "' . $authBackend . '" has no Resource', Zend_Log::ERR)
);
$this->render('authentication/remove'); $this->render('authentication/remove');
return; return;
} }
@ -393,8 +382,7 @@ class ConfigController extends BaseConfigController
public function resourceAction($showOnly = false) public function resourceAction($showOnly = false)
{ {
$this->view->messageBox = new AlertMessageBox($this->getAndClearMessages()); $this->view->messageBox = new AlertMessageBox(true);
$this->view->resources = IcingaConfig::app('resources', true)->toArray(); $this->view->resources = IcingaConfig::app('resources', true)->toArray();
$this->render('resource'); $this->render('resource');
} }
@ -418,7 +406,7 @@ class ConfigController extends BaseConfigController
} }
} }
$this->view->messageBox = new AlertMessageBox($this->getAndClearMessages()); $this->view->messageBox = new AlertMessageBox(true);
$this->view->messageBox->addForm($form); $this->view->messageBox->addForm($form);
$this->view->form = $form; $this->view->form = $form;
$this->render('resource/create'); $this->render('resource/create');
@ -426,14 +414,12 @@ class ConfigController extends BaseConfigController
public function editresourceAction() public function editresourceAction()
{ {
$this->view->messageBox = new AlertMessageBox(); $this->view->messageBox = new AlertMessageBox(true);
$resources = ResourceFactory::getResourceConfigs(); $resources = ResourceFactory::getResourceConfigs();
$name = $this->getParam('resource'); $name = $this->getParam('resource');
if ($resources->get($name) === null) { if ($resources->get($name) === null) {
$this->view->messageBox->addMessage( $this->addErrorMessage('Can\'t edit: Unknown Resource Provided');
new Message('Can\'t edit: Unknown Resource Provided', Zend_Log::ERR)
);
$this->render('resource/modify'); $this->render('resource/modify');
return; return;
} }
@ -466,14 +452,12 @@ class ConfigController extends BaseConfigController
public function removeresourceAction() public function removeresourceAction()
{ {
$this->view->messageBox = new AlertMessageBox(); $this->view->messageBox = new AlertMessageBox(true);
$resources = ResourceFactory::getResourceConfigs()->toArray(); $resources = ResourceFactory::getResourceConfigs()->toArray();
$name = $this->getParam('resource'); $name = $this->getParam('resource');
if (!isset($resources[$name])) { if (!isset($resources[$name])) {
$this->view->messageBox->addMessage( $this->addSuccessMessage('Can\'t remove: Unknown resource provided');
new Message('Can\'t remove: Unknown resource provided', Zend_Log::ERR)
);
$this->render('resource/remove'); $this->render('resource/remove');
return; return;
} }
@ -481,6 +465,18 @@ class ConfigController extends BaseConfigController
$form = new ConfirmRemovalForm(); $form = new ConfirmRemovalForm();
$form->setRequest($this->getRequest()); $form->setRequest($this->getRequest());
$form->setRemoveTarget('resource', $name); $form->setRemoveTarget('resource', $name);
// Check if selected resource is currently used for authentication
$authConfig = IcingaConfig::app('authentication', true)->toArray();
foreach ($authConfig as $backendName => $config) {
if (array_key_exists('resource', $config) && $config['resource'] === $name) {
$this->addErrorMessage(
'Warning: The resource "' . $name . '" is currently used for user authentication by "' . $backendName . '". ' .
' Deleting it could eventally make login impossible.'
);
}
}
if ($form->isSubmittedAndValid()) { if ($form->isSubmittedAndValid()) {
unset($resources[$name]); unset($resources[$name]);
if ($this->writeConfigFile($resources, 'resources')) { if ($this->writeConfigFile($resources, 'resources')) {
@ -504,7 +500,7 @@ class ConfigController extends BaseConfigController
*/ */
public function configurationerrorAction() public function configurationerrorAction()
{ {
$this->view->messageBox = new AlertMessageBox($this->getAndClearMessages()); $this->view->messageBox = new AlertMessageBox(true);
$this->render('error/error'); $this->render('error/error');
} }

View File

@ -44,27 +44,6 @@ use \Icinga\User\Message;
*/ */
class BaseConfigController extends ActionController class BaseConfigController extends ActionController
{ {
/**
* @var Zend_Controller_Action_Helper_FlashMessenger
*/
protected $flashManager;
/**
* Remove all messages from the current user, return them and commit
* changes to the underlying session.
*
* @return array The messages
*/
protected function getAndClearMessages()
{
// empty all messages
$user = AuthenticationManager::getInstance()->getUser();
$messages = $user->getMessages();
$user->clearMessages();
AuthenticationManager::getInstance()->getSession()->write();
return $messages;
}
/** /**
* Send a message with the logging level Zend_Log::INFO to the current user and * Send a message with the logging level Zend_Log::INFO to the current user and
* commit the changes to the underlying session. * commit the changes to the underlying session.

View File

@ -4,18 +4,34 @@ namespace Icinga\Web\Widget;
use \Zend_Log; use \Zend_Log;
use \Zend_Form; use \Zend_Form;
use \Icinga\User;
use \Icinga\User\Message; use \Icinga\User\Message;
use \Zend_View_Abstract; use \Zend_View_Abstract;
use \Icinga\Authentication\Manager as AuthenticationManager;
/** /**
* Class AlertMessageBox
*
* Displays a set of alert messages to the user. * Displays a set of alert messages to the user.
* *
* @package Icinga\Web\Widget * The messages are fetched automatically from the current AuthenticationManager,
* but this is done lazily when render() is called, to ensure that messages will
* always be displayed before they are cleared.
*/ */
class AlertMessageBox implements \Icinga\Web\Widget\Widget { class AlertMessageBox implements \Icinga\Web\Widget\Widget {
/**
* Remove all messages from the current user, return them and commit
* changes to the underlying session.
*
* @return array The messages
*/
protected function getAndClearMessages()
{
$messages = $this->user->getMessages();
$this->user->clearMessages();
AuthenticationManager::getInstance()->getSession()->write();
return $messages;
}
/** /**
* The displayed alert messages * The displayed alert messages
* *
@ -23,6 +39,13 @@ class AlertMessageBox implements \Icinga\Web\Widget\Widget {
*/ */
private $messages = array(); private $messages = array();
/**
* The user to fetch the messages from
*
* @var User
*/
private $user;
/** /**
* The available states. * The available states.
* *
@ -50,26 +73,15 @@ class AlertMessageBox implements \Icinga\Web\Widget\Widget {
/** /**
* Create a new AlertBox * Create a new AlertBox
* *
* @param Message|array $messages The message(s) to display * @param boolean showUserMessages If the current user messages should be displayed
* in this AlertMessageBox. Defaults to false
*/ */
public function __construct($messages = array()) { public function __construct($showUserMessages = false) {
if (!is_array($messages)) { if ($showUserMessages) {
$this->messages = array($messages); $this->user = AuthenticationManager::getInstance()->getUser();
} else {
$this->messages = $messages;
} }
} }
/**
* Add a new message.
*
* @param Message $message
*/
public function addMessage(Message $message)
{
$this->messages[] = $message;
}
/** /**
* Add a new error * Add a new error
* *
@ -97,6 +109,9 @@ class AlertMessageBox implements \Icinga\Web\Widget\Widget {
*/ */
public function render(Zend_View_Abstract $view = null) { public function render(Zend_View_Abstract $view = null) {
$html = ''; $html = '';
if (isset($this->user)) {
$this->messages = array_merge($this->messages, $this->getAndClearMessages());
}
foreach ($this->messages as $message) { foreach ($this->messages as $message) {
$level = $message->getLevel(); $level = $message->getLevel();
if (!array_key_exists($level, $this->states)) { if (!array_key_exists($level, $this->states)) {

View File

@ -70,7 +70,7 @@ class Monitoring_ConfigController extends BaseConfigController {
*/ */
public function indexAction() public function indexAction()
{ {
$this->view->messageBox = new AlertMessageBox($this->getAndClearMessages()); $this->view->messageBox = new AlertMessageBox(true);
$this->view->backends = IcingaConfig::module('monitoring', 'backends')->toArray(); $this->view->backends = IcingaConfig::module('monitoring', 'backends')->toArray();
$this->view->instances = IcingaConfig::module('monitoring', 'instances')->toArray(); $this->view->instances = IcingaConfig::module('monitoring', 'instances')->toArray();
$this->render('index'); $this->render('index');