Adjust authentication backend forms to suit.. some form implementation

refs #5525
This commit is contained in:
Johannes Meyer 2014-08-29 15:16:13 +02:00
parent 364c7c0858
commit ae35650c7e
13 changed files with 591 additions and 449 deletions

View File

@ -6,19 +6,16 @@ use Icinga\Web\Controller\BaseConfigController;
use Icinga\Web\Widget\AlertMessageBox;
use Icinga\Web\Notification;
use Icinga\Application\Modules\Module;
use Icinga\Web\Form;
use Icinga\Web\Widget;
use Icinga\Application\Icinga;
use Icinga\Application\Config as IcingaConfig;
use Icinga\Form\Config\GeneralForm;
use Icinga\Form\Config\Authentication\LdapBackendForm;
use Icinga\Form\Config\Authentication\DbBackendForm;
use Icinga\Form\Config\Authentication\AutologinBackendForm;
use Icinga\Form\Config\AuthenticationBackendReorderForm;
use Icinga\Form\Config\AuthenticationBackendConfigForm;
use Icinga\Form\Config\ResourceForm;
use Icinga\Form\Config\LoggingForm;
use Icinga\Form\Config\ConfirmRemovalForm;
use Icinga\Config\PreservingIniWriter;
use Icinga\Exception\ConfigurationError;
use Icinga\Data\ResourceFactory;
/**
@ -142,47 +139,17 @@ class ConfigController extends BaseConfigController
}
/**
* Action for reordering authentication backends
* Action for listing and reordering authentication backends
*/
public function authenticationAction()
{
$this->view->messageBox = new AlertMessageBox(true);
$form = new AuthenticationBackendReorderForm();
$form->setConfig(IcingaConfig::app('authentication'));
$form->handleRequest();
$this->view->form = $form;
$this->view->tabs->activate('authentication');
$config = IcingaConfig::app('authentication');
$backendOrder = array_keys($config->toArray());
$form = new Form();
$form->setName('form_reorder_authbackend');
$request = $this->getRequest();
if ($request->isPost()) {
$requestData = $request->getPost();
if ($form->isValid($requestData)) { // Validate the CSRF token
$reordered = false;
foreach ($backendOrder as $backendName) {
if (isset($requestData[$backendName])) {
array_splice($backendOrder, array_search($backendName, $backendOrder), 1);
array_splice($backendOrder, $requestData[$backendName], 0, $backendName);
$reordered = true;
break;
}
}
if ($reordered) {
$reorderedConfig = array();
foreach ($backendOrder as $backendName) {
$reorderedConfig[$backendName] = $config->{$backendName};
}
if ($this->writeAuthenticationFile($reorderedConfig)) {
Notification::success($this->translate('Authentication order updated!'));
$this->redirectNow('config/authentication');
}
}
}
}
$this->view->form = $form->create(); // Necessary in case its a GET request
$this->view->backendNames = $backendOrder;
$this->render('authentication/reorder');
}
/**
@ -190,172 +157,66 @@ class ConfigController extends BaseConfigController
*/
public function createauthenticationbackendAction()
{
$this->view->messageBox = new AlertMessageBox(true);
$this->view->tabs->activate('authentication');
$form = new AuthenticationBackendConfigForm();
$form->setConfig(IcingaConfig::app('authentication'));
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
$form->setRedirectUrl('config/authentication');
$form->handleRequest();
$backendType = $this->getRequest()->getParam('type');
$authenticationConfig = IcingaConfig::app('authentication')->toArray();
try {
switch ($backendType) {
case 'ldap':
$form = new LdapBackendForm();
break;
case 'db':
$form = new DbBackendForm();
break;
case 'autologin':
foreach ($authenticationConfig as $ac) {
if (array_key_exists('backend', $ac) && $ac['backend'] === 'autologin') {
throw new ConfigurationError(
$this->translate('An autologin backend already exists')
);
}
}
$form = new AutologinBackendForm();
break;
default:
$this->addErrorMessage(sprintf(
$this->translate('There is no backend type `%s\''),
$backendType
));
$this->redirectNow('config/configurationerror');
}
} catch (ConfigurationError $e) {
$this->addErrorMessage($e->getMessage());
$this->redirectNow('config/configurationerror');
}
$request = $this->getRequest();
if ($request->isPost() && $form->isValid($request->getPost())) {
list($backendName, $backendConfig) = $form->getBackendConfig();
if (isset($authenticationConfig[$backendName])) {
$this->addErrorMessage(
$this->translate('Backend name already exists')
);
} else {
$authenticationConfig[$backendName] = $backendConfig;
if ($this->writeConfigFile($authenticationConfig, 'authentication')) {
$this->addSuccessMessage(
$this->translate('Backend Modification Written.')
);
$this->redirectNow('config/authentication');
}
}
}
$this->view->messageBox->addForm($form);
$this->view->form = $form;
$this->view->tabs->activate('authentication');
$this->render('authentication/create');
}
/**
* Form for editing backends
*
* Mostly the same like the createAuthenticationBackendAction, but with additional checks for backend existence
* and form population
* Action for editing authentication backends
*/
public function editauthenticationbackendAction()
{
$this->view->messageBox = new AlertMessageBox(true);
$form = new AuthenticationBackendConfigForm();
$form->setConfig(IcingaConfig::app('authentication'));
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
$form->setRedirectUrl('config/authentication');
$form->handleRequest();
$configArray = IcingaConfig::app('authentication', true)->toArray();
$authBackend = $this->getParam('auth_backend');
if (false === isset($configArray[$authBackend])) {
$this->addErrorMessage(
$this->translate('Can\'t edit: Unknown Authentication Backend Provided')
);
$this->redirectNow('config/configurationerror');
}
if (false === array_key_exists('backend', $configArray[$authBackend])) {
$this->addErrorMessage(sprintf(
$this->translate('Backend "%s" has no `backend\' setting'),
$authBackend
));
$this->redirectNow('config/configurationerror');
}
$type = $configArray[$authBackend]['backend'];
switch ($type) {
case 'ldap':
$form = new LdapBackendForm();
break;
case 'db':
$form = new DbBackendForm();
break;
case 'autologin':
$form = new AutologinBackendForm();
break;
default:
$this->addErrorMessage(sprintf(
$this->translate('Can\'t edit: backend type "%s" of given resource not supported.'),
$type
));
$this->redirectNow('config/configurationerror');
}
$request = $this->getRequest();
if ($request->isPost()) {
if ($form->isValid($request->getPost())) {
list($backendName, $backendConfig) = $form->getBackendConfig();
$configArray[$backendName] = $backendConfig;
if ($backendName != $authBackend) {
unset($configArray[$authBackend]);
}
if ($this->writeAuthenticationFile($configArray)) {
// redirect to overview with success message
Notification::success(sprintf(
$this->translate('Backend "%s" saved'),
$backendName
));
$this->redirectNow('config/authentication');
}
return;
}
} else {
$form->setBackendConfig($authBackend, $configArray[$authBackend]);
}
$this->view->messageBox->addForm($form);
$this->view->name = $authBackend;
$this->view->form = $form;
$this->view->tabs->activate('authentication');
$this->render('authentication/modify');
}
/**
* Action for removing a backend from the authentication list.
*
* Redirects to the overview after removal is finished
* Action for removing a backend from the authentication list
*/
public function removeauthenticationbackendAction()
{
$this->view->messageBox = new AlertMessageBox(true);
$form = new ConfirmRemovalForm(array(
'onSuccess' => function ($request) {
$configForm = new AuthenticationBackendConfigForm();
$configForm->setConfig(IcingaConfig::app('authentication'));
$authBackend = $request->getQuery('auth_backend');
$configArray = IcingaConfig::app('authentication', true)->toArray();
$authBackend = $this->getParam('auth_backend');
if (false === array_key_exists($authBackend, $configArray)) {
$this->addErrorMessage(
$this->translate('Can\'t perform removal: Unknown authentication backend provided')
);
$this->redirectNow('config/configurationerror');
}
try {
$configForm->remove($authBackend);
} catch (InvalidArgumentException $e) {
Notification::error($e->getMessage());
return;
}
$form = new ConfirmRemovalForm();
$request = $this->getRequest();
if ($request->isPost() && $form->isValid($request->getPost())) {
unset($configArray[$authBackend]);
if ($this->writeAuthenticationFile($configArray)) {
Notification::success(sprintf(
$this->translate('Authentication Backend "%s" Removed'),
$authBackend
));
$this->redirectNow('config/authentication');
if ($configForm->save()) {
Notification::success(sprintf(
t('Authentication backend "%s" has been successfully removed'),
$authBackend
));
} else {
return false;
}
}
}
));
$form->setRedirectUrl('config/authentication');
$form->handleRequest();
$this->view->form = $form;
$this->view->name = $authBackend;
$this->view->tabs->activate('authentication');
$this->render('authentication/remove');
}

View File

@ -5,19 +5,19 @@
namespace Icinga\Form\Config\Authentication;
use Zend_Validate_Callback;
use Icinga\Web\Form;
/**
* Form class for adding/modifying autologin authentication backends
*/
class AutologinBackendForm extends BaseBackendForm
class AutologinBackendForm extends Form
{
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_config_authentication_autologin');
$this->setSubmitLabel(t('Save Changes'));
$this->setName('form_config_authbackend_autologin');
}
/**
@ -31,7 +31,6 @@ class AutologinBackendForm extends BaseBackendForm
'name',
array(
'required' => true,
'allowEmpty' => false,
'label' => t('Backend Name'),
'helptext' => t('The name of this authentication backend'),
'validators' => array(
@ -53,7 +52,6 @@ class AutologinBackendForm extends BaseBackendForm
'strip_username_regexp',
array(
'required' => true,
'allowEmpty' => false,
'label' => t('Backend Domain Pattern'),
'helptext' => t('The domain pattern of this authentication backend'),
'value' => '/\@[^$]+$/',
@ -76,13 +74,15 @@ class AutologinBackendForm extends BaseBackendForm
}
/**
* Validate the configuration state of this backend
* Validate the configuration by creating a backend and requesting the user count
*
* Returns just true as autologins are being handled externally by the webserver.
* Returns always true as autologin backends are just "passive" backends. (The webserver authenticates users.)
*
* @return true
* @param Form $form The form to fetch the configuration values from
*
* @return bool Whether validation succeeded or not
*/
public function isValidAuthenticationBackend()
public function isValidAuthenticationBackend(Form $form)
{
return true;
}

View File

@ -1,94 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config\Authentication;
use Icinga\Web\Form;
/**
* Base form for authentication backend forms
*/
abstract class BaseBackendForm extends Form
{
/**
* Return whether the given values are complete/valid and check whether it is possible to connect to the backend
*
* If connection validation fails, a checkbox is prepended to the form to allow users to skip it.
*
* @param array $data The data to validate
*
* @return bool Whether the validation succeeded or not
*/
public function isValid($data)
{
if (false === parent::isValid($data)) {
return false;
}
if (
(false === isset($data['force_creation']) || false === $data['force_creation'])
&& false === $this->isValidAuthenticationBackend()
) {
$this->addForceCreationCheckbox();
return false;
}
return true;
}
/**
* Validate the configuration state of this backend with the concrete authentication backend.
*
* An implementation should not throw any exception, but use the add/setErrorMessages method
* of Zend_Form. If the 'force_creation' checkbox is set, this method won't be called.
*
* @return bool Whether validation succeeded or not
*/
abstract public function isValidAuthenticationBackend();
/**
* Return the backend's configuration values and its name
*
* The first value is the name and the second one the values as array.
*
* @return array
*/
public function getBackendConfig()
{
$values = $this->getValues();
$name = $values['name'];
unset($values['name']);
return array($name, $values);
}
/**
* Populate the form with the given configuration values
*
* @param string $name The name of the backend
* @param array $config The configuration values
*/
public function setBackendConfig($name, array $config)
{
$config['name'] = $name;
$this->populate($config);
}
/**
* Add a checkbox to be displayed at the beginning of the form
* which allows the user to skip the connection validation
*/
protected function addForceCreationCheckbox()
{
$this->addElement(
'checkbox',
'force_creation',
array(
'order' => 0,
'ignore' => true,
'label' => t('Force Changes'),
'helptext' => t('Check this box to enforce changes without connectivity validation')
)
);
}
}

View File

@ -5,17 +5,18 @@
namespace Icinga\Form\Config\Authentication;
use Exception;
use Icinga\Web\Form;
use Icinga\Web\Request;
use Icinga\Data\ResourceFactory;
use Icinga\Exception\ConfigurationError;
use Icinga\Authentication\Backend\DbUserBackend;
/**
* Form class for adding/modifying database authentication backends
*/
class DbBackendForm extends BaseBackendForm
class DbBackendForm extends Form
{
/**
* The available database resources prepared to be used as select input data
* The database resource names the user can choose from
*
* @var array
*/
@ -23,28 +24,23 @@ class DbBackendForm extends BaseBackendForm
/**
* Initialize this form
*
* Populates $this->resources.
*
* @throws ConfigurationError In case no database resources can be found
*/
public function init()
{
$this->setName('form_config_authentication_db');
$this->setSubmitLabel(t('Save Changes'));
$this->setName('form_config_authbackend_db');
}
$dbResources = array_keys(
ResourceFactory::getResourceConfigs('db')->toArray()
);
if (empty($dbResources)) {
throw new ConfigurationError(
t('There are no database resources')
);
}
// array_combine() is necessary in order to use the array as select input data
$this->resources = array_combine($dbResources, $dbResources);
/**
* Set the resource names the user can choose from
*
* @param array $resources The resources to choose from
*
* @return self
*/
public function setResources(array $resources)
{
$this->resources = $resources;
return $this;
}
/**
@ -69,7 +65,9 @@ class DbBackendForm extends BaseBackendForm
'required' => true,
'label' => t('Database Connection'),
'helptext' => t('The database connection to use for authenticating with this provider'),
'multiOptions' => $this->resources
'multiOptions' => false === empty($this->resources)
? array_combine($this->resources, $this->resources)
: array()
)
),
$this->createElement(
@ -84,25 +82,39 @@ class DbBackendForm extends BaseBackendForm
}
/**
* Validate the current configuration by creating a backend and requesting the user count
* Validate that the selected resource is a valid database authentication backend
*
* @return bool Whether validation succeeded or not
*
* @see BaseBackendForm::isValidAuthenticationBackend()
* @see Form::onSuccess()
*/
public function isValidAuthenticationBackend()
public function onSuccess(Request $request)
{
if (false === $this->isValidAuthenticationBackend($this)) {
return false;
}
}
/**
* Validate the configuration by creating a backend and requesting the user count
*
* @param Form $form The form to fetch the configuration values from
*
* @return bool Whether validation succeeded or not
*/
public function isValidAuthenticationBackend(Form $form)
{
$element = $form->getElement('resource');
try {
$testConnection = ResourceFactory::createResource(ResourceFactory::getResourceConfig(
$this->getValue('resource')
));
$testConnection = ResourceFactory::createResource(
ResourceFactory::getResourceConfig($element->getValue())
);
$dbUserBackend = new DbUserBackend($testConnection);
if ($dbUserBackend->count() < 1) {
$this->addErrorMessage(t('No users found under the specified database backend'));
$element->addError(t('No users found under the specified database backend'));
return false;
}
} catch (Exception $e) {
$this->addErrorMessage(sprintf(t('Using the specified backend failed: %s'), $e->getMessage()));
$element->addError(sprintf(t('Using the specified backend failed: %s'), $e->getMessage()));
return false;
}

View File

@ -5,17 +5,17 @@
namespace Icinga\Form\Config\Authentication;
use Exception;
use Icinga\Web\Form;
use Icinga\Data\ResourceFactory;
use Icinga\Exception\ConfigurationError;
use Icinga\Authentication\Backend\LdapUserBackend;
/**
* Form for adding or modifying LDAP authentication backends
* Form class for adding/modifying LDAP authentication backends
*/
class LdapBackendForm extends BaseBackendForm
class LdapBackendForm extends Form
{
/**
* The available ldap resources prepared to be used as select input data
* The ldap resource names the user can choose from
*
* @var array
*/
@ -23,28 +23,23 @@ class LdapBackendForm extends BaseBackendForm
/**
* Initialize this form
*
* Populates $this->resources.
*
* @throws ConfigurationError In case no database resources can be found
*/
public function init()
{
$this->setName('form_config_authentication_ldap');
$this->setSubmitLabel(t('Save Changes'));
$this->setName('form_config_authbackend_ldap');
}
$ldapResources = array_keys(
ResourceFactory::getResourceConfigs('ldap')->toArray()
);
if (empty($ldapResources)) {
throw new ConfigurationError(
t('There are no LDAP resources')
);
}
// array_combine() is necessary in order to use the array as select input data
$this->resources = array_combine($ldapResources, $ldapResources);
/**
* Set the resource names the user can choose from
*
* @param array $resources The resources to choose from
*
* @return self
*/
public function setResources(array $resources)
{
$this->resources = $resources;
return $this;
}
/**
@ -69,7 +64,9 @@ class LdapBackendForm extends BaseBackendForm
'required' => true,
'label' => t('LDAP Resource'),
'helptext' => t('The resource to use for authenticating with this provider'),
'multiOptions' => $this->resources
'multiOptions' => false === empty($this->resources)
? array_combine($this->resources, $this->resources)
: array()
)
),
$this->createElement(
@ -104,33 +101,39 @@ class LdapBackendForm extends BaseBackendForm
}
/**
* Validate the current configuration by connecting to a backend and requesting the user count
* Validate that the selected resource is a valid ldap authentication backend
*
* @return bool Whether validation succeeded or not
*
* @see BaseBackendForm::isValidAuthenticationBacken()
* @see Form::onSuccess()
*/
public function isValidAuthenticationBackend()
public function onSuccess(Request $request)
{
if (false === ResourceFactory::ldapAvailable()) {
// It should be possible to run icingaweb without the php ldap extension. When the user
// tries to create an ldap backend without ldap being installed we display an error.
$this->addErrorMessage(t('Using ldap is not possible, the php extension "ldap" is not installed.'));
if (false === $this->isValidAuthenticationBackend($this)) {
return false;
}
}
/**
* Validate the configuration by creating a backend and requesting the user count
*
* @param Form $form The form to fetch the configuration values from
*
* @return bool Whether validation succeeded or not
*/
public function isValidAuthenticationBackend(Form $form)
{
$element = $form->getElement('resource');
try {
$backend = ResourceFactory::createResource(
ResourceFactory::getResourceConfig($this->getValue('resource'))
$ldapUserBackend = new LdapUserBackend(
ResourceFactory::createResource(
ResourceFactory::getResourceConfig($element->getValue())
),
$form->getElement('user_class')->getValue(),
$form->getElement('user_name_attribute')->getValue()
);
$testConn = new LdapUserBackend(
$backend,
$this->getValue('user_class'),
$this->getValue('user_name_attribute')
);
$testConn->assertAuthenticationPossible();
} catch (Exception $exc) {
$this->addErrorMessage(sprintf(t('Connection validation failed: %s'), $exc->getMessage()));
$ldapUserBackend->assertAuthenticationPossible();
} catch (Exception $e) {
$element->addError(sprintf(t('Connection validation failed: %s'), $e->getMessage()));
return false;
}

View File

@ -0,0 +1,318 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config;
use InvalidArgumentException;
use Icinga\Web\Request;
use Icinga\Form\ConfigForm;
use Icinga\Web\Notification;
use Icinga\Application\Config;
use Icinga\Data\ResourceFactory;
use Icinga\Exception\ConfigurationError;
use Icinga\Form\Config\Authentication\DbBackendForm;
use Icinga\Form\Config\Authentication\LdapBackendForm;
use Icinga\Form\Config\Authentication\AutologinBackendForm;
class AuthenticationBackendConfigForm extends ConfigForm
{
/**
* The available resources split by type
*
* @var array
*/
protected $resources;
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_config_authbackend');
$this->setSubmitLabel(t('Save Changes'));
}
/**
* Set the resource configuration to use
*
* @param Config $resources The resource configuration
*
* @return self
*
* @throws ConfigurationError In case no resources are available for authentication
*/
public function setResourceConfig(Config $resourceConfig)
{
$resources = array();
foreach ($resourceConfig as $name => $resource) {
$resources[strtolower($resource->type)][] = $name;
}
if (empty($resources)) {
throw new ConfigurationError(t('Could not find any resources for authentication'));
}
$this->resources = $resources;
return $this;
}
/**
* Return a form object for the given backend type
*
* @param string $type The backend type for which to return a form
*
* @return Form
*/
public function getBackendForm($type)
{
if ($type === 'db') {
$form = new DbBackendForm();
$form->setResources(isset($this->resources['db']) ? $this->resources['db'] : array());
} elseif ($type === 'ldap') {
$form = new LdapBackendForm();
$form->setResources(isset($this->resources['ldap']) ? $this->resources['ldap'] : array());
} elseif ($type === 'autologin') {
$form = new AutologinBackendForm();
} else {
throw new InvalidArgumentException(sprintf(t('Invalid backend type "%s" provided'), $type));
}
return $form;
}
/**
* Add a particular authentication backend
*
* The backend to add is identified by the array-key `name'.
*
* @param array $values The values to extend the configuration with
*
* @return self
*
* @throws InvalidArgumentException In case the backend does already exist
*/
public function add(array $values)
{
$name = isset($values['name']) ? $values['name'] : '';
if (! $name) {
throw new InvalidArgumentException(t('Authentication backend name missing'));
} elseif ($this->config->get($name) !== null) {
throw new InvalidArgumentException(t('Authentication backend already exists'));
}
unset($values['name']);
$this->config->{$name} = $values;
return $this;
}
/**
* Edit a particular authentication backend
*
* @param string $name The name of the backend to edit
* @param array $values The values to edit the configuration with
*
* @return array The edited backend configuration
*
* @throws InvalidArgumentException In case the backend does not exist
*/
public function edit($name, array $values)
{
if (! $name) {
throw new InvalidArgumentException(t('Old authentication backend name missing'));
} elseif (! ($newName = isset($values['name']) ? $values['name'] : '')) {
throw new InvalidArgumentException(t('New authentication backend name missing'));
} elseif (($backendConfig = $this->config->get($name)) === null) {
throw new InvalidArgumentException(t('Unknown authentication backend provided'));
}
if ($newName !== $name) {
// Only remove the old entry if it has changed as the order gets screwed when editing backend names
unset($this->config->{$name});
}
unset($values['name']);
$this->config->{$newName} = array_merge($backendConfig->toArray(), $values);
return $this->config->{$newName};
}
/**
* Remove the given authentication backend
*
* @param string $name The name of the backend to remove
*
* @return array The removed backend configuration
*
* @throws InvalidArgumentException In case the backend does not exist
*/
public function remove($name)
{
if (! $name) {
throw new InvalidArgumentException(t('Authentication backend name missing'));
} elseif (($backendConfig = $this->config->get($name)) === null) {
throw new InvalidArgumentException(t('Unknown authentication backend provided'));
}
unset($this->config->{$name});
return $backendConfig;
}
/**
* Move the given authentication backend up or down in order
*
* @param string $name The name of the backend to be moved
* @param int $position The new (absolute) position of the backend
*
* @return self
*
* @throws InvalidArgumentException In case the backend does not exist
*/
public function move($name, $position)
{
if (! $name) {
throw new InvalidArgumentException(t('Authentication backend name missing'));
} elseif ($this->config->get($name) === null) {
throw new InvalidArgumentException(t('Unknown authentication backend provided'));
}
$backendOrder = $this->config->keys();
array_splice($backendOrder, array_search($name, $backendOrder), 1);
array_splice($backendOrder, $position, 0, $name);
$newConfig = array();
foreach ($backendOrder as $backendName) {
$newConfig[$backendName] = $this->config->get($backendName);
}
$config = new Config($newConfig);
$this->config = $config->setConfigFile($this->config->getConfigFile());
return $this;
}
/**
* Add or edit an authentication backend and save the configuration
*
* Performs a connectivity validation using the submitted values. A checkbox is
* added to the form to skip the check if it fails and redirection is aborted.
*
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
{
if (($el = $this->getElement('force_creation')) === null || false === $el->isChecked()) {
$backendForm = $this->getBackendForm($this->getElement('type')->getValue());
if (false === $backendForm->isValidAuthenticationBackend($this)) {
$this->addForceCreationCheckbox();
return false;
}
}
$authBackend = $request->getQuery('auth_backend');
try {
if ($authBackend === null) { // create new backend
$this->add($this->getValues());
$message = t('Authentication backend "%s" has been successfully created');
} else { // edit existing backend
$this->edit($authBackend, $this->getValues());
$message = t('Authentication backend "%s" has been successfully changed');
}
} catch (InvalidArgumentException $e) {
Notification::error($e->getMessage());
return;
}
if ($this->save()) {
Notification::success(sprintf($message, $this->getElement('name')->getValue()));
} else {
return false;
}
}
/**
* Populate the form in case an authentication backend is being edited
*
* @see Form::onShow()
*
* @throws ConfigurationError In case the backend name is missing in the request or is invalid
*/
public function onShow(Request $request)
{
$authBackend = $request->getQuery('auth_backend');
if ($authBackend !== null) {
if ($authBackend === '') {
throw new ConfigurationError(t('Authentication backend name missing'));
} elseif (false === isset($this->config->{$authBackend})) {
throw new ConfigurationError(t('Unknown authentication backend provided'));
} elseif (false === isset($this->config->{$authBackend}->backend)) {
throw new ConfigurationError(sprintf(t('Backend "%s" has no `backend\' setting'), $authBackend));
}
$configValues = $this->config->{$authBackend}->toArray();
$configValues['type'] = $configValues['backend'];
$configValues['name'] = $authBackend;
$this->populate($configValues);
}
}
/**
* Add a checkbox to be displayed at the beginning of the form
* which allows the user to skip the connection validation
*/
protected function addForceCreationCheckbox()
{
$this->addElement(
'checkbox',
'force_creation',
array(
'order' => 0,
'ignore' => true,
'label' => t('Force Changes'),
'helptext' => t('Check this box to enforce changes without connectivity validation')
)
);
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$backendTypes = array();
$backendType = isset($formData['type']) ? $formData['type'] : 'db';
if (isset($this->resources['db'])) {
$backendTypes['db'] = t('Database');
}
if (isset($this->resources['ldap']) && ($backendType === 'ldap' || ResourceFactory::ldapAvailable())) {
$backendTypes['ldap'] = 'LDAP';
}
$autologinBackends = array_filter(
$this->config->toArray(),
function ($authBackendCfg) {
return isset($authBackendCfg['backend']) && $authBackendCfg['backend'] === 'autologin';
}
);
if ($backendType === 'autologin' || empty($autologinBackends)) {
$backendTypes['autologin'] = t('Autologin');
}
$typeSelection = $this->createElement(
'select',
'type',
array(
'ignore' => true,
'required' => true,
'autosubmit' => true,
'label' => t('Backend Type'),
'helptext' => t('The type of the resource to use for this authenticaton backend'),
'multiOptions' => $backendTypes
)
);
return array_merge(
array($typeSelection),
$this->getBackendForm($backendType)->createElements($formData)
);
}
}

View File

@ -0,0 +1,68 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Config;
use InvalidArgumentException;
use Icinga\Web\Request;
use Icinga\Web\Notification;
use Icinga\Form\ConfigForm;
class AuthenticationBackendReorderForm extends ConfigForm
{
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_reorder_authbackend');
$this->setViewScript('form/reorder-authbackend.phtml');
}
/**
* Return the ordered backend names
*
* @return array
*/
public function getBackendOrder()
{
return $this->config->keys();
}
/**
* Update the authentication backend order and save the configuration
*
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
{
$formData = $this->getRequestData($request);
if (isset($formData['backend_newpos'])) {
$configForm = $this->getConfigForm();
list($backendName, $position) = explode('|', $formData['backend_newpos'], 2);
try {
if ($configForm->move($backendName, $position)->save()) {
Notification::success(t('Authentication order updated!'));
} else {
return false;
}
} catch (InvalidArgumentException $e) {
Notification::error($e->getMessage());
}
}
}
/**
* Return the config form for authentication backends
*
* @return ConfigForm
*/
protected function getConfigForm()
{
$form = new AuthenticationBackendConfigForm();
$form->setConfig($this->config);
return $form;
}
}

View File

@ -1,57 +0,0 @@
<div class="controls">
<?= $tabs; ?>
</div>
<div class="content" data-base-target="_next">
<?= $messageBox; ?>
<p>
<a href="<?= $this->href('/config/createAuthenticationBackend', array('type' => 'ldap')); ?>">
<?= $this->icon('create.png'); ?><?= $this->translate('Create A New LDAP Authentication Backend'); ?>
</a>
<br>
<a href="<?= $this->href('/config/createAuthenticationBackend', array('type' => 'db')); ?>">
<?= $this->icon('create.png'); ?><?= $this->translate('Create A New DB Authentication Backend'); ?>
</a>
<br>
<a href="<?= $this->href('/config/createAuthenticationBackend', array('type' => 'autologin')); ?>">
<?= $this->icon('create.png'); ?><?= $this->translate('Create A New Autologin Authentication Backend'); ?>
</a>
</p>
<form id="<?= $form->getName(); ?>" name="<?= $form->getName(); ?>" enctype="<?= $form->getEncType(); ?>" method="<?= $form->getMethod(); ?>">
<?= $form->getElement($form->getTokenElementName()); ?>
<table class="action">
<thead>
<th>Backend</th>
<th style="width: 5em"><?= $this->translate('Remove'); ?></th>
<th style="width: 5em"><?= $this->translate('Order'); ?></th>
</thead>
<tbody>
<?php for ($i = 0; $i < count($backendNames); $i++): ?>
<tr>
<td class="action">
<a href="<?= $this->href('config/editAuthenticationBackend', array('auth_backend' => $backendNames[$i])); ?>">
<?= $this->icon('edit.png'); ?> <?= $this->escape($backendNames[$i]); ?>
</a>
</td>
<td>
<a href="<?= $this->href('config/removeAuthenticationBackend', array('auth_backend' => $backendNames[$i])); ?>">
<?= $this->icon('remove.png', $this->translate('Remove')); ?>
</a>
</td>
<td>
<?php if ($i > 0): ?>
<button type="submit" name="<?= $backendNames[$i]; ?>" value="<?= $i - 1; ?>">
<?= $this->icon('up.png', $this->translate('Move up in authentication order')); ?>
</button>
<?php endif; ?>
<?php if ($i + 1 < count($backendNames)): ?>
<button type="submit" name="<?= $backendNames[$i]; ?>" value="<?= $i + 1; ?>">
<?= $this->icon('down.png', $this->translate('Move down in authentication order')); ?>
</button>
<?php endif; ?>
</td>
</tr>
<?php endfor; ?>
</tbody>
</table>
</form>
</div>

View File

@ -1,15 +1,7 @@
<h4>
<i class="icinga-icon-create"></i>
Create New Authentication Backend
</h4>
<?php if (isset($this->messageBox)): ?>
<?= $this->messageBox->render() ?>
<?php endif ?>
<h4><?= $this->translate('Create New Authentication Backend'); ?></h4>
<p>
Create a new backend for authenticating your users. This backend will be added at the end of your authentication order.
<?= $this->translate(
'Create a new backend for authenticating your users. This backend will be added at the end of your authentication order.'
); ?>
</p>
<?= $this->form ?>
<?= $form; ?>

View File

@ -1,8 +1,2 @@
<h4>
<?php printf(
$this->translate('Edit Backend "%s"'),
$this->escape($this->name)
); ?>
</h4>
<?= $messageBox; ?>
<?= $this->form; ?>
<h4><?= $this->translate('Edit Backend'); ?></h4>
<?= $form; ?>

View File

@ -1,8 +1,2 @@
<h4>
<?php printf(
$this->translate('Remove Backend "%s"'),
$this->escape($name)
); ?>
</h4>
<?= $messageBox ?>
<?= $form ?>
<h4><?= $this->translate('Remove Backend'); ?></h4>
<?= $form; ?>

View File

@ -0,0 +1,11 @@
<div class="controls">
<?= $tabs; ?>
</div>
<div class="content" data-base-target="_next">
<p>
<a href="<?= $this->href('/config/createAuthenticationBackend'); ?>">
<?= $this->icon('create.png'); ?><?= $this->translate('Create A New Authentication Backend'); ?>
</a>
</p>
<?= $form; ?>
</div>

View File

@ -0,0 +1,40 @@
<form id="<?= $form->getName(); ?>" name="<?= $form->getName(); ?>" enctype="<?= $form->getEncType(); ?>" method="<?= $form->getMethod(); ?>">
<table class="action">
<thead>
<th>Backend</th>
<th style="width: 5em"><?= $this->translate('Remove'); ?></th>
<th style="width: 5em"><?= $this->translate('Order'); ?></th>
</thead>
<tbody>
<?php $backendNames = $form->getBackendOrder(); ?>
<?php for ($i = 0; $i < count($backendNames); $i++): ?>
<tr>
<td class="action">
<a href="<?= $this->href('config/editAuthenticationBackend', array('auth_backend' => $backendNames[$i])); ?>">
<?= $this->icon('edit.png'); ?> <?= $this->escape($backendNames[$i]); ?>
</a>
</td>
<td>
<a href="<?= $this->href('config/removeAuthenticationBackend', array('auth_backend' => $backendNames[$i])); ?>">
<?= $this->icon('remove.png', $this->translate('Remove')); ?>
</a>
</td>
<td>
<?php if ($i > 0): ?>
<button type="submit" name="backend_newpos" value="<?= sprintf('%s|%s', $backendNames[$i], $i - 1); ?>">
<?= $this->icon('up.png', $this->translate('Move up in authentication order')); ?>
</button>
<?php endif; ?>
<?php if ($i + 1 < count($backendNames)): ?>
<button type="submit" name="backend_newpos" value="<?= sprintf('%s|%s', $backendNames[$i], $i + 1); ?>">
<?= $this->icon('down.png', $this->translate('Move down in authentication order')); ?>
</button>
<?php endif; ?>
</td>
</tr>
<?php endfor; ?>
</tbody>
</table>
<?= $form->getElement($form->getTokenElementName()); ?>
<?= $form->getElement($form->getUidElementName()); ?>
</form>