UserBackendConfigForm: Adjust how to process requests...
...and use sub-forms, finally. refs #9602
This commit is contained in:
parent
910dee199f
commit
4e3da3a6eb
|
@ -5,6 +5,8 @@ use Icinga\Application\Config;
|
|||
use Icinga\Application\Icinga;
|
||||
use Icinga\Application\Modules\Module;
|
||||
use Icinga\Data\ResourceFactory;
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
use Icinga\Exception\NotFoundError;
|
||||
use Icinga\Forms\Config\UserBackendConfigForm;
|
||||
use Icinga\Forms\Config\UserBackendReorderForm;
|
||||
use Icinga\Forms\Config\GeneralConfigForm;
|
||||
|
@ -193,80 +195,130 @@ class ConfigController extends Controller
|
|||
}
|
||||
|
||||
/**
|
||||
* Action for creating a new user backend
|
||||
* Create a new user backend
|
||||
*/
|
||||
public function createuserbackendAction()
|
||||
{
|
||||
$this->assertPermission('config/application/userbackend');
|
||||
$form = new UserBackendConfigForm();
|
||||
$form->setRedirectUrl('config/userbackend');
|
||||
$form->setTitle($this->translate('Create New User Backend'));
|
||||
$form->addDescription($this->translate(
|
||||
'Create a new backend for authenticating your users. This backend'
|
||||
. ' will be added at the end of your authentication order.'
|
||||
));
|
||||
$form->setIniConfig(Config::app('authentication'));
|
||||
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
|
||||
$form->setRedirectUrl('config/userbackend');
|
||||
|
||||
try {
|
||||
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
|
||||
} catch (ConfigurationError $e) {
|
||||
if ($this->hasPermission('config/application/resources')) {
|
||||
Notification::error($e->getMessage());
|
||||
$this->redirectNow('config/createresource');
|
||||
}
|
||||
|
||||
throw $e; // No permission for resource configuration, show the error
|
||||
}
|
||||
|
||||
$form->setOnSuccess(function (UserBackendConfigForm $form) {
|
||||
try {
|
||||
$form->add(array_filter($form->getValues()));
|
||||
} catch (Exception $e) {
|
||||
$form->error($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($form->save()) {
|
||||
Notification::success(t('User backend successfully created'));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
$form->handleRequest();
|
||||
|
||||
$this->view->form = $form;
|
||||
$this->render('userbackend/create');
|
||||
$this->render('form');
|
||||
}
|
||||
|
||||
/**
|
||||
* Action for editing user backends
|
||||
* Edit a user backend
|
||||
*/
|
||||
public function edituserbackendAction()
|
||||
{
|
||||
$this->assertPermission('config/application/userbackend');
|
||||
$backendName = $this->params->getRequired('backend');
|
||||
|
||||
$form = new UserBackendConfigForm();
|
||||
$form->setTitle($this->translate('Edit User Backend'));
|
||||
$form->setIniConfig(Config::app('authentication'));
|
||||
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
|
||||
$form->setRedirectUrl('config/userbackend');
|
||||
$form->setAction(Url::fromRequest());
|
||||
$form->handleRequest();
|
||||
$form->setRedirectUrl('config/userbackend');
|
||||
$form->setTitle(sprintf($this->translate('Edit User Backend %s'), $backendName));
|
||||
$form->setIniConfig(Config::app('authentication'));
|
||||
$form->setOnSuccess(function (UserBackendConfigForm $form) use ($backendName) {
|
||||
try {
|
||||
$form->edit($backendName, array_map(
|
||||
function ($v) {
|
||||
return $v !== '' ? $v : null;
|
||||
},
|
||||
$form->getValues()
|
||||
));
|
||||
} catch (Exception $e) {
|
||||
$form->error($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($form->save()) {
|
||||
Notification::success(sprintf(t('User backend "%s" successfully updated'), $backendName));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
try {
|
||||
$form->load($backendName);
|
||||
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
|
||||
$form->handleRequest();
|
||||
} catch (NotFoundError $_) {
|
||||
$this->httpNotFound(sprintf($this->translate('User backend "%s" not found'), $backendName));
|
||||
}
|
||||
|
||||
$this->view->form = $form;
|
||||
$this->render('userbackend/modify');
|
||||
$this->render('form');
|
||||
}
|
||||
|
||||
/**
|
||||
* Action for removing a user backend
|
||||
* Display a confirmation form to remove the backend identified by the 'backend' parameter
|
||||
*/
|
||||
public function removeuserbackendAction()
|
||||
{
|
||||
$this->assertPermission('config/application/userbackend');
|
||||
$form = new ConfirmRemovalForm(array(
|
||||
'onSuccess' => function ($form) {
|
||||
$configForm = new UserBackendConfigForm();
|
||||
$configForm->setIniConfig(Config::app('authentication'));
|
||||
$authBackend = $form->getRequest()->getQuery('backend');
|
||||
$backendName = $this->params->getRequired('backend');
|
||||
|
||||
try {
|
||||
$configForm->remove($authBackend);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
Notification::error($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($configForm->save()) {
|
||||
Notification::success(sprintf(
|
||||
t('User backend "%s" has been successfully removed'),
|
||||
$authBackend
|
||||
));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
));
|
||||
$form->setTitle($this->translate('Remove User Backend'));
|
||||
$backendForm = new UserBackendConfigForm();
|
||||
$backendForm->setIniConfig(Config::app('authentication'));
|
||||
$form = new ConfirmRemovalForm();
|
||||
$form->setRedirectUrl('config/userbackend');
|
||||
$form->setAction(Url::fromRequest());
|
||||
$form->setTitle(sprintf($this->translate('Remove User Backend %s'), $backendName));
|
||||
$form->setOnSuccess(function (ConfirmRemovalForm $form) use ($backendName, $backendForm) {
|
||||
try {
|
||||
$backendForm->delete($backendName);
|
||||
} catch (Exception $e) {
|
||||
$form->error($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($backendForm->save()) {
|
||||
Notification::success(sprintf(t('User backend "%s" successfully removed'), $backendName));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
$form->handleRequest();
|
||||
|
||||
$this->view->form = $form;
|
||||
$this->render('userbackend/remove');
|
||||
$this->render('form');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,11 +3,7 @@
|
|||
|
||||
namespace Icinga\Forms\Config\UserBackend;
|
||||
|
||||
use Exception;
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Data\ConfigObject;
|
||||
use Icinga\Data\ResourceFactory;
|
||||
use Icinga\Authentication\User\DbUserBackend;
|
||||
|
||||
/**
|
||||
* Form class for adding/modifying database user backends
|
||||
|
@ -43,7 +39,9 @@ class DbBackendForm extends Form
|
|||
}
|
||||
|
||||
/**
|
||||
* @see Form::createElements()
|
||||
* Create and add elements to this form
|
||||
*
|
||||
* @param array $formData
|
||||
*/
|
||||
public function createElements(array $formData)
|
||||
{
|
||||
|
@ -56,6 +54,20 @@ class DbBackendForm extends Form
|
|||
'description' => $this->translate(
|
||||
'The name of this authentication provider that is used to differentiate it from others'
|
||||
),
|
||||
'validators' => array(
|
||||
array(
|
||||
'Regex',
|
||||
false,
|
||||
array(
|
||||
'pattern' => '/^[^\\[\\]:]+$/',
|
||||
'messages' => array(
|
||||
'regexNotMatch' => $this->translate(
|
||||
'The name cannot contain \'[\', \']\' or \':\'.'
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
$this->addElement(
|
||||
|
@ -67,7 +79,7 @@ class DbBackendForm extends Form
|
|||
'description' => $this->translate(
|
||||
'The database connection to use for authenticating with this provider'
|
||||
),
|
||||
'multiOptions' => false === empty($this->resources)
|
||||
'multiOptions' => !empty($this->resources)
|
||||
? array_combine($this->resources, $this->resources)
|
||||
: array()
|
||||
)
|
||||
|
@ -80,49 +92,5 @@ class DbBackendForm extends Form
|
|||
'value' => 'db'
|
||||
)
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that the selected resource is a valid database user backend
|
||||
*
|
||||
* @see Form::onSuccess()
|
||||
*/
|
||||
public function onSuccess()
|
||||
{
|
||||
if (false === static::isValidUserBackend($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 static function isValidUserBackend(Form $form)
|
||||
{
|
||||
$backend = new DbUserBackend(ResourceFactory::createResource($form->getResourceConfig()));
|
||||
$result = $backend->inspect();
|
||||
if ($result->hasError()) {
|
||||
$form->addError(sprintf($form->translate('Using the specified backend failed: %s'), $result->getError()));
|
||||
}
|
||||
|
||||
// TODO: display diagnostics in $result->toArray() to the user
|
||||
|
||||
return ! $result->hasError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configuration for the chosen resource
|
||||
*
|
||||
* @return ConfigObject
|
||||
*/
|
||||
public function getResourceConfig()
|
||||
{
|
||||
return ResourceFactory::getResourceConfig($this->getValue('resource'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,14 +3,7 @@
|
|||
|
||||
namespace Icinga\Forms\Config\UserBackend;
|
||||
|
||||
use Exception;
|
||||
use Icinga\Authentication\User\LdapUserBackend;
|
||||
use Icinga\Data\Inspection;
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Data\ConfigObject;
|
||||
use Icinga\Data\ResourceFactory;
|
||||
use Icinga\Exception\AuthenticationException;
|
||||
use Icinga\Authentication\User\UserBackend;
|
||||
|
||||
/**
|
||||
* Form class for adding/modifying LDAP user backends
|
||||
|
@ -46,7 +39,9 @@ class LdapBackendForm extends Form
|
|||
}
|
||||
|
||||
/**
|
||||
* @see Form::createElements()
|
||||
* Create and add elements to this form
|
||||
*
|
||||
* @param array $formData
|
||||
*/
|
||||
public function createElements(array $formData)
|
||||
{
|
||||
|
@ -60,6 +55,20 @@ class LdapBackendForm extends Form
|
|||
'label' => $this->translate('Backend Name'),
|
||||
'description' => $this->translate(
|
||||
'The name of this authentication provider that is used to differentiate it from others.'
|
||||
),
|
||||
'validators' => array(
|
||||
array(
|
||||
'Regex',
|
||||
false,
|
||||
array(
|
||||
'pattern' => '/^[^\\[\\]:]+$/',
|
||||
'messages' => array(
|
||||
'regexNotMatch' => $this->translate(
|
||||
'The name cannot contain \'[\', \']\' or \':\'.'
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
@ -72,7 +81,7 @@ class LdapBackendForm extends Form
|
|||
'description' => $this->translate(
|
||||
'The LDAP connection to use for authenticating with this provider.'
|
||||
),
|
||||
'multiOptions' => false === empty($this->resources)
|
||||
'multiOptions' => !empty($this->resources)
|
||||
? array_combine($this->resources, $this->resources)
|
||||
: array()
|
||||
)
|
||||
|
@ -162,40 +171,5 @@ class LdapBackendForm extends Form
|
|||
)
|
||||
)
|
||||
);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that the selected resource is a valid ldap user backend
|
||||
*
|
||||
* @see Form::onSuccess()
|
||||
*/
|
||||
public function onSuccess()
|
||||
{
|
||||
if (false === static::isValidUserBackend($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 static function isValidUserBackend(Form $form)
|
||||
{
|
||||
/**
|
||||
* @var $result Inspection
|
||||
*/
|
||||
$result = UserBackend::create(null, new ConfigObject($form->getValues()))->inspect();
|
||||
if ($result->hasError()) {
|
||||
$form->addError($result->getError());
|
||||
}
|
||||
|
||||
// TODO: display diagnostics in $result->toArray() to the user
|
||||
|
||||
return ! $result->hasError();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,26 +4,38 @@
|
|||
namespace Icinga\Forms\Config;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Icinga\Forms\ConfigForm;
|
||||
use Icinga\Web\Notification;
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Application\Platform;
|
||||
use Icinga\Data\ConfigObject;
|
||||
use Icinga\Data\ResourceFactory;
|
||||
use Icinga\Authentication\User\UserBackend;
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
use Icinga\Exception\IcingaException;
|
||||
use Icinga\Exception\NotFoundError;
|
||||
use Icinga\Data\ConfigObject;
|
||||
use Icinga\Data\Inspectable;
|
||||
use Icinga\Forms\ConfigForm;
|
||||
use Icinga\Forms\Config\UserBackend\ExternalBackendForm;
|
||||
use Icinga\Forms\Config\UserBackend\DbBackendForm;
|
||||
use Icinga\Forms\Config\UserBackend\LdapBackendForm;
|
||||
use Icinga\Forms\Config\UserBackend\ExternalBackendForm;
|
||||
use Icinga\Web\Form;
|
||||
|
||||
/**
|
||||
* Form for managing user backends
|
||||
*/
|
||||
class UserBackendConfigForm extends ConfigForm
|
||||
{
|
||||
/**
|
||||
* The available resources split by type
|
||||
* The available user backend resources split by type
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $resources;
|
||||
|
||||
/**
|
||||
* The backend to load when displaying the form for the first time
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $backendToLoad;
|
||||
|
||||
/**
|
||||
* Initialize this form
|
||||
*/
|
||||
|
@ -36,15 +48,39 @@ class UserBackendConfigForm extends ConfigForm
|
|||
/**
|
||||
* Set the resource configuration to use
|
||||
*
|
||||
* @param Config $resources The resource configuration
|
||||
* @param Config $resourceConfig The resource configuration
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws ConfigurationError In case there are no valid resources for authentication available
|
||||
*/
|
||||
public function setResourceConfig(Config $resourceConfig)
|
||||
{
|
||||
$resources = array();
|
||||
foreach ($resourceConfig as $name => $resource) {
|
||||
$resources[strtolower($resource->type)][] = $name;
|
||||
if (in_array($resource->type, array('db', 'ldap'))) {
|
||||
$resources[$resource->type][] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($resources)) {
|
||||
$externalBackends = $this->config->toArray();
|
||||
array_walk(
|
||||
$externalBackends,
|
||||
function (& $authBackendCfg) {
|
||||
if (! isset($authBackendCfg['backend']) || $authBackendCfg['backend'] !== 'external') {
|
||||
$authBackendCfg = null;
|
||||
}
|
||||
}
|
||||
);
|
||||
if (count(array_filter($externalBackends)) > 0 && (
|
||||
$this->backendToLoad === null || !isset($externalBackends[$this->backendToLoad])
|
||||
)) {
|
||||
throw new ConfigurationError($this->translate(
|
||||
'Could not find any valid user backend resources.'
|
||||
. ' Please configure a resource for authentication first.'
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
$this->resources = $resources;
|
||||
|
@ -54,9 +90,11 @@ class UserBackendConfigForm extends ConfigForm
|
|||
/**
|
||||
* Return a form object for the given backend type
|
||||
*
|
||||
* @param string $type The backend type for which to return a form
|
||||
* @param string $type The backend type for which to return a form
|
||||
*
|
||||
* @return Form
|
||||
*
|
||||
* @throws InvalidArgumentException In case the given backend type is invalid
|
||||
*/
|
||||
public function getBackendForm($type)
|
||||
{
|
||||
|
@ -84,81 +122,103 @@ class UserBackendConfigForm extends ConfigForm
|
|||
}
|
||||
|
||||
/**
|
||||
* Add a particular user backend
|
||||
* Populate the form with the given backend's config
|
||||
*
|
||||
* The backend to add is identified by the array-key `name'.
|
||||
*
|
||||
* @param array $values The values to extend the configuration with
|
||||
* @param string $name
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgumentException In case the backend does already exist
|
||||
* @throws NotFoundError In case no backend with the given name is found
|
||||
*/
|
||||
public function add(array $values)
|
||||
public function load($name)
|
||||
{
|
||||
$name = isset($values['name']) ? $values['name'] : '';
|
||||
if (! $name) {
|
||||
throw new InvalidArgumentException($this->translate('User backend name missing'));
|
||||
} elseif ($this->config->hasSection($name)) {
|
||||
throw new InvalidArgumentException($this->translate('User backend already exists'));
|
||||
if (! $this->config->hasSection($name)) {
|
||||
throw new NotFoundError('No user backend called "%s" found', $name);
|
||||
}
|
||||
|
||||
unset($values['name']);
|
||||
$this->config->setSection($name, $values);
|
||||
$this->backendToLoad = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a particular user backend
|
||||
* Add a new user backend
|
||||
*
|
||||
* @param string $name The name of the backend to edit
|
||||
* @param array $values The values to edit the configuration with
|
||||
* The backend to add is identified by the array-key `name'.
|
||||
*
|
||||
* @return array The edited backend configuration
|
||||
* @param array $data
|
||||
*
|
||||
* @throws InvalidArgumentException In case the backend does not exist
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgumentException In case $data does not contain a backend name
|
||||
* @throws IcingaException In case a backend with the same name already exists
|
||||
*/
|
||||
public function edit($name, array $values)
|
||||
public function add(array $data)
|
||||
{
|
||||
if (! $name) {
|
||||
throw new InvalidArgumentException($this->translate('Old user backend name missing'));
|
||||
} elseif (! ($newName = isset($values['name']) ? $values['name'] : '')) {
|
||||
throw new InvalidArgumentException($this->translate('New user backend name missing'));
|
||||
} elseif (! $this->config->hasSection($name)) {
|
||||
throw new InvalidArgumentException($this->translate('Unknown user backend provided'));
|
||||
if (! isset($data['name'])) {
|
||||
throw new InvalidArgumentException('Key \'name\' missing');
|
||||
}
|
||||
|
||||
$backendConfig = $this->config->getSection($name);
|
||||
if ($newName !== $name) {
|
||||
// Only remove the old entry if it has changed as the order gets screwed when editing backend names
|
||||
$this->config->removeSection($name);
|
||||
$backendName = $data['name'];
|
||||
if ($this->config->hasSection($backendName)) {
|
||||
throw new IcingaException(
|
||||
$this->translate('A user backend with the name "%s" does already exist'),
|
||||
$backendName
|
||||
);
|
||||
}
|
||||
|
||||
unset($values['name']);
|
||||
$this->config->setSection($newName, $backendConfig->merge($values));
|
||||
return $backendConfig;
|
||||
unset($data['name']);
|
||||
$this->config->setSection($backendName, $data);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the given user backend
|
||||
* Edit a user backend
|
||||
*
|
||||
* @param string $name The name of the backend to remove
|
||||
* @param string $name
|
||||
* @param array $data
|
||||
*
|
||||
* @return array The removed backend configuration
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgumentException In case the backend does not exist
|
||||
* @throws NotFoundError In case no backend with the given name is found
|
||||
*/
|
||||
public function remove($name)
|
||||
public function edit($name, array $data)
|
||||
{
|
||||
if (! $name) {
|
||||
throw new InvalidArgumentException($this->translate('user backend name missing'));
|
||||
} elseif (! $this->config->hasSection($name)) {
|
||||
throw new InvalidArgumentException($this->translate('Unknown user backend provided'));
|
||||
if (! $this->config->hasSection($name)) {
|
||||
throw new NotFoundError('No user backend called "%s" found', $name);
|
||||
}
|
||||
|
||||
$backendConfig = $this->config->getSection($name);
|
||||
if (isset($data['name'])) {
|
||||
if ($data['name'] !== $name) {
|
||||
$this->config->removeSection($name);
|
||||
$name = $data['name'];
|
||||
}
|
||||
|
||||
unset($data['name']);
|
||||
}
|
||||
|
||||
$backendConfig->merge($data);
|
||||
foreach ($backendConfig->toArray() as $k => $v) {
|
||||
if ($v === null) {
|
||||
unset($backendConfig->$k);
|
||||
}
|
||||
}
|
||||
|
||||
$this->config->setSection($name, $backendConfig);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a user backend
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function delete($name)
|
||||
{
|
||||
$this->config->removeSection($name);
|
||||
return $backendConfig;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -169,14 +229,12 @@ class UserBackendConfigForm extends ConfigForm
|
|||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgumentException In case the backend does not exist
|
||||
* @throws NotFoundError In case no backend with the given name is found
|
||||
*/
|
||||
public function move($name, $position)
|
||||
{
|
||||
if (! $name) {
|
||||
throw new InvalidArgumentException($this->translate('User backend name missing'));
|
||||
} elseif (! $this->config->hasSection($name)) {
|
||||
throw new InvalidArgumentException($this->translate('Unknown user backend provided'));
|
||||
if (! $this->config->hasSection($name)) {
|
||||
throw new NotFoundError('No user backend called "%s" found', $name);
|
||||
}
|
||||
|
||||
$backendOrder = $this->config->keys();
|
||||
|
@ -194,105 +252,9 @@ class UserBackendConfigForm extends ConfigForm
|
|||
}
|
||||
|
||||
/**
|
||||
* Add or edit an user backend and save the configuration
|
||||
* Create and add elements to this form
|
||||
*
|
||||
* 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()
|
||||
{
|
||||
if (($el = $this->getElement('force_creation')) === null || false === $el->isChecked()) {
|
||||
$backendForm = $this->getBackendForm($this->getElement('type')->getValue());
|
||||
if (false === $backendForm::isValidUserBackend($this)) {
|
||||
$this->addElement($this->getForceCreationCheckbox());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$authBackend = $this->request->getQuery('backend');
|
||||
try {
|
||||
if ($authBackend === null) { // create new backend
|
||||
$this->add($this->getValues());
|
||||
$message = $this->translate('User backend "%s" has been successfully created');
|
||||
} else { // edit existing backend
|
||||
$this->edit($authBackend, $this->getValues());
|
||||
$message = $this->translate('User 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 user backend is being edited
|
||||
*
|
||||
* @see Form::onRequest()
|
||||
*
|
||||
* @throws ConfigurationError In case the backend name is missing in the request or is invalid
|
||||
*/
|
||||
public function onRequest()
|
||||
{
|
||||
$authBackend = $this->request->getQuery('backend');
|
||||
if ($authBackend !== null) {
|
||||
if ($authBackend === '') {
|
||||
throw new ConfigurationError($this->translate('User backend name missing'));
|
||||
} elseif (! $this->config->hasSection($authBackend)) {
|
||||
throw new ConfigurationError($this->translate('Unknown user backend provided'));
|
||||
} elseif ($this->config->getSection($authBackend)->backend === null) {
|
||||
throw new ConfigurationError(
|
||||
sprintf($this->translate('Backend "%s" has no `backend\' setting'), $authBackend)
|
||||
);
|
||||
}
|
||||
|
||||
$configValues = $this->config->getSection($authBackend)->toArray();
|
||||
$configValues['type'] = $configValues['backend'];
|
||||
$configValues['name'] = $authBackend;
|
||||
$this->populate($configValues);
|
||||
} elseif (empty($this->resources)) {
|
||||
$externalBackends = array_filter(
|
||||
$this->config->toArray(),
|
||||
function ($authBackendCfg) {
|
||||
return isset($authBackendCfg['backend']) && $authBackendCfg['backend'] === 'external';
|
||||
}
|
||||
);
|
||||
|
||||
if (false === empty($externalBackends)) {
|
||||
throw new ConfigurationError($this->translate('Could not find any resources for authentication'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a checkbox to be displayed at the beginning of the form
|
||||
* which allows the user to skip the connection validation
|
||||
*
|
||||
* @return Zend_Form_Element
|
||||
*/
|
||||
protected function getForceCreationCheckbox()
|
||||
{
|
||||
return $this->createElement(
|
||||
'checkbox',
|
||||
'force_creation',
|
||||
array(
|
||||
'order' => 0,
|
||||
'ignore' => true,
|
||||
'label' => $this->translate('Force Changes'),
|
||||
'description' => $this->translate('Check this box to enforce changes without connectivity validation')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Form::createElements()
|
||||
* @param array $formData
|
||||
*/
|
||||
public function createElements(array $formData)
|
||||
{
|
||||
|
@ -302,7 +264,7 @@ class UserBackendConfigForm extends ConfigForm
|
|||
if (isset($this->resources['db'])) {
|
||||
$backendTypes['db'] = $this->translate('Database');
|
||||
}
|
||||
if (isset($this->resources['ldap']) && ($backendType === 'ldap' || Platform::extensionLoaded('ldap'))) {
|
||||
if (isset($this->resources['ldap'])) {
|
||||
$backendTypes['ldap'] = 'LDAP';
|
||||
$backendTypes['msldap'] = 'ActiveDirectory';
|
||||
}
|
||||
|
@ -336,21 +298,107 @@ class UserBackendConfigForm extends ConfigForm
|
|||
)
|
||||
);
|
||||
|
||||
if (isset($formData['force_creation']) && $formData['force_creation']) {
|
||||
if (isset($formData['skip_validation']) && $formData['skip_validation']) {
|
||||
// In case another error occured and the checkbox was displayed before
|
||||
$this->addElement($this->getForceCreationCheckbox());
|
||||
$this->addSkipValidationCheckbox();
|
||||
}
|
||||
|
||||
$this->addElements($this->getBackendForm($backendType)->createElements($formData)->getElements());
|
||||
$this->addSubForm($this->getBackendForm($backendType)->create($formData), 'backend_form');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configuration for the chosen resource
|
||||
*
|
||||
* @return ConfigObject
|
||||
* Populate the configuration of the backend to load
|
||||
*/
|
||||
public function getResourceConfig()
|
||||
public function onRequest()
|
||||
{
|
||||
return ResourceFactory::getResourceConfig($this->getValue('resource'));
|
||||
if ($this->backendToLoad) {
|
||||
$data = $this->config->getSection($this->backendToLoad)->toArray();
|
||||
$data['name'] = $this->backendToLoad;
|
||||
$data['type'] = $data['backend'];
|
||||
$this->populate($data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all form element values
|
||||
*
|
||||
* @param bool $suppressArrayNotation Ignored
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getValues($suppressArrayNotation = false)
|
||||
{
|
||||
$values = parent::getValues();
|
||||
$values = array_merge($values, $values['backend_form']);
|
||||
unset($values['backend_form']);
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the given values are valid
|
||||
*
|
||||
* @param array $formData The data to validate
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid($formData)
|
||||
{
|
||||
if (! parent::isValid($formData)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (($el = $this->getElement('skip_validation')) === null || false === $el->isChecked()) {
|
||||
$backendForm = $this->getBackendForm($this->getValue('type'));
|
||||
if (! static::isValidUserBackend($this)) {
|
||||
if ($el === null) {
|
||||
$this->addSkipValidationCheckbox();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the configuration by creating a backend and running its inspection checks
|
||||
*
|
||||
* @param Form $form The form to fetch the configuration values from
|
||||
*
|
||||
* @return bool Whether inspection succeeded or not
|
||||
*/
|
||||
public static function isValidUserBackend(Form $form)
|
||||
{
|
||||
$backend = UserBackend::create(null, new ConfigObject($form->getValues()));
|
||||
if ($backend instanceof Inspectable) {
|
||||
$inspection = $backend->inspect();
|
||||
if ($inspection->hasError()) {
|
||||
$form->error($inspection->getError());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a checkbox to the form by which the user can skip the connection validation
|
||||
*/
|
||||
protected function addSkipValidationCheckbox()
|
||||
{
|
||||
$this->addElement(
|
||||
'checkbox',
|
||||
'skip_validation',
|
||||
array(
|
||||
'order' => 0,
|
||||
'ignore' => true,
|
||||
'required' => true,
|
||||
'label' => $this->translate('Skip Validation'),
|
||||
'description' => $this->translate(
|
||||
'Check this box to enforce changes without validating that authentication is possible.'
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
|
||||
namespace Icinga\Forms\Config;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use Icinga\Web\Notification;
|
||||
use Icinga\Forms\ConfigForm;
|
||||
use Icinga\Exception\NotFoundError;
|
||||
use Icinga\Web\Notification;
|
||||
|
||||
class UserBackendReorderForm extends ConfigForm
|
||||
{
|
||||
|
@ -29,7 +29,9 @@ class UserBackendReorderForm extends ConfigForm
|
|||
}
|
||||
|
||||
/**
|
||||
* @see Form::createElements()
|
||||
* Create and add elements to this form
|
||||
*
|
||||
* @param array $formData
|
||||
*/
|
||||
public function createElements(array $formData)
|
||||
{
|
||||
|
@ -39,8 +41,6 @@ class UserBackendReorderForm extends ConfigForm
|
|||
|
||||
/**
|
||||
* Update the user backend order and save the configuration
|
||||
*
|
||||
* @see Form::onSuccess()
|
||||
*/
|
||||
public function onSuccess()
|
||||
{
|
||||
|
@ -55,8 +55,8 @@ class UserBackendReorderForm extends ConfigForm
|
|||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (InvalidArgumentException $e) {
|
||||
Notification::error($e->getMessage());
|
||||
} catch (NotFoundError $_) {
|
||||
Notification::error(sprintf($this->translate('User backend "%s" not found'), $backendName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
<div class="controls">
|
||||
<?= $this->tabs->showOnlyCloseButton() ?>
|
||||
</div>
|
||||
<div class="content">
|
||||
<?= $form; ?>
|
||||
</div>
|
|
@ -1,6 +0,0 @@
|
|||
<div class="controls">
|
||||
<?= $this->tabs->showOnlyCloseButton() ?>
|
||||
</div>
|
||||
<div class="content">
|
||||
<?= $form; ?>
|
||||
</div>
|
|
@ -3,11 +3,12 @@
|
|||
|
||||
namespace Icinga\Module\Setup\Forms;
|
||||
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Data\ConfigObject;
|
||||
use Icinga\Forms\Config\UserBackendConfigForm;
|
||||
use Icinga\Forms\Config\UserBackend\DbBackendForm;
|
||||
use Icinga\Forms\Config\UserBackend\LdapBackendForm;
|
||||
use Icinga\Forms\Config\UserBackend\ExternalBackendForm;
|
||||
use Icinga\Data\ConfigObject;
|
||||
use Icinga\Web\Form;
|
||||
|
||||
/**
|
||||
* Wizard page to define authentication backend specific details
|
||||
|
@ -66,14 +67,14 @@ class AuthBackendPage extends Form
|
|||
$this->setRequiredCue(null);
|
||||
$backendForm = new DbBackendForm();
|
||||
$backendForm->setRequiredCue(null);
|
||||
$backendForm->createElements($formData)->removeElement('resource');
|
||||
$backendForm->create($formData)->removeElement('resource');
|
||||
$this->addDescription($this->translate(
|
||||
'As you\'ve chosen to use a database for authentication all you need '
|
||||
. 'to do now is defining a name for your first authentication backend.'
|
||||
));
|
||||
} elseif ($this->config['type'] === 'ldap') {
|
||||
$backendForm = new LdapBackendForm();
|
||||
$backendForm->createElements($formData)->removeElement('resource');
|
||||
$backendForm->create($formData)->removeElement('resource');
|
||||
$this->addDescription($this->translate(
|
||||
'Before you are able to authenticate using the LDAP connection defined earlier you need to'
|
||||
. ' provide some more information so that Icinga Web 2 is able to locate account details.'
|
||||
|
@ -97,15 +98,30 @@ class AuthBackendPage extends Form
|
|||
);
|
||||
} else { // $this->config['type'] === 'external'
|
||||
$backendForm = new ExternalBackendForm();
|
||||
$backendForm->createElements($formData);
|
||||
$backendForm->create($formData);
|
||||
$this->addDescription($this->translate(
|
||||
'You\'ve chosen to authenticate using a web server\'s mechanism so it may be necessary'
|
||||
. ' to adjust usernames before any permissions, restrictions, etc. are being applied.'
|
||||
));
|
||||
}
|
||||
|
||||
$this->addElements($backendForm->getElements());
|
||||
$this->getElement('name')->setValue('icingaweb2');
|
||||
$backendForm->getElement('name')->setValue('icingaweb2');
|
||||
$this->addSubForm($backendForm, 'backend_form');
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all form element values
|
||||
*
|
||||
* @param bool $suppressArrayNotation Ignored
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getValues($suppressArrayNotation = false)
|
||||
{
|
||||
$values = parent::getValues();
|
||||
$values = array_merge($values, $values['backend_form']);
|
||||
unset($values['backend_form']);
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -117,11 +133,11 @@ class AuthBackendPage extends Form
|
|||
*/
|
||||
public function isValid($data)
|
||||
{
|
||||
if (false === parent::isValid($data)) {
|
||||
if (! parent::isValid($data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->config['type'] === 'ldap' && ( !isset($data['skip_validation']) || $data['skip_validation'] == 0)) {
|
||||
if ($this->config['type'] === 'ldap' && (! isset($data['skip_validation']) || $data['skip_validation'] == 0)) {
|
||||
$self = clone $this;
|
||||
$self->addElement(
|
||||
'text',
|
||||
|
@ -130,7 +146,7 @@ class AuthBackendPage extends Form
|
|||
'value' => $this->getResourceConfig()
|
||||
)
|
||||
);
|
||||
if (! LdapBackendForm::isValidUserBackend($self)) {
|
||||
if (! UserBackendConfigForm::isValidUserBackend($self)) {
|
||||
$this->addSkipValidationCheckbox();
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue