diff --git a/application/controllers/GroupController.php b/application/controllers/GroupController.php index d18397cf49..e07b2c181d 100644 --- a/application/controllers/GroupController.php +++ b/application/controllers/GroupController.php @@ -9,6 +9,7 @@ use Icinga\Data\DataArray\ArrayDatasource; use Icinga\Data\Filter\Filter; use Icinga\Data\Reducible; +use Icinga\Data\UserSuggestions; use Icinga\Exception\NotFoundError; use Icinga\Forms\Config\UserGroup\AddMemberForm; use Icinga\Forms\Config\UserGroup\UserGroupForm; @@ -17,7 +18,7 @@ use Icinga\Web\Form; use Icinga\Web\Notification; use Icinga\Web\Url; -use Icinga\Web\Widget; +use ipl\Web\Url as IplUrl; class GroupController extends AuthBackendController { @@ -224,24 +225,50 @@ public function addmemberAction() { $this->assertPermission('config/access-control/groups'); $groupName = $this->params->getRequired('group'); - $backend = $this->getUserGroupBackend($this->params->getRequired('backend'), 'Icinga\Data\Extensible'); + $backend = $this->getUserGroupBackend( + $this->params->getRequired('backend'), + 'Icinga\Data\Extensible' + ); - $form = new AddMemberForm(); - $form->setDataSource($this->fetchUsers()) + $form = (new AddMemberForm()) ->setBackend($backend) ->setGroupName($groupName) ->setRedirectUrl( - Url::fromPath('group/show', array('backend' => $backend->getName(), 'group' => $groupName)) + IplUrl::fromPath('group/show', ['backend' => $backend->getName(), 'group' => $groupName]) ) - ->setUidDisabled(); + ->setSuggestionUrl(IplUrl::fromPath( + 'group/complete', + [ + '_disableLayout' => true, + 'showCompact' => true, + 'backend' => $this->params->getRequired('backend'), + 'group' => $groupName + ] + )); - try { - $form->handleRequest(); - } catch (NotFoundError $_) { - $this->httpNotFound(sprintf($this->translate('Group "%s" not found'), $groupName)); - } + $form->on(AddMemberForm::ON_SUCCESS, function ($form) { + $this->getResponse()->redirectAndExit($form->getRedirectUrl()); + })->handleRequest($this->getServerRequest()); + + $this->addTitleTab($this->translate('New User Group Member')); + $this->addContent($form); + } + + public function completeAction() + { + $backend = $this->getUserGroupBackend( + $this->params->getRequired('backend'), + 'Icinga\Data\Extensible' + ); + + $groupName = $this->params->getRequired('group'); - $this->renderForm($form, $this->translate('New User Group Member')); + $suggestions = (new UserSuggestions()) + ->setUserGroupName($groupName) + ->setUserGroupBackend($backend) + ->setUserBackends($this->loadUserBackends('Icinga\Data\Selectable')) + ->forRequest($this->getServerRequest()); + $this->getDocument()->addHtml($suggestions); } /** diff --git a/application/forms/Config/UserGroup/AddMemberForm.php b/application/forms/Config/UserGroup/AddMemberForm.php index debb9b7af0..c981f12771 100644 --- a/application/forms/Config/UserGroup/AddMemberForm.php +++ b/application/forms/Config/UserGroup/AddMemberForm.php @@ -1,28 +1,18 @@ ds = $ds; - return $this; - } - /** * Set the user group backend to use * @@ -76,74 +53,18 @@ public function setGroupName($groupName) return $this; } - /** - * Create and add elements to this form - * - * @param array $formData The data sent by the user - */ - public function createElements(array $formData) - { - // TODO(jom): Fetching already existing members to prevent the user from mistakenly creating duplicate - // memberships (no matter whether the data source permits it or not, a member does never need to be - // added more than once) should be kept at backend level (GroupController::fetchUsers) but this does - // not work currently as our ldap protocol stuff is unable to handle our filter implementation.. - $members = $this->backend - ->select() - ->from('group_membership', array('user_name')) - ->where('group_name', $this->groupName) - ->fetchColumn(); - $filter = empty($members) ? Filter::matchAll() : Filter::not(Filter::where('user_name', $members)); - - $users = $this->ds->select()->from('user', array('user_name'))->applyFilter($filter)->fetchColumn(); - if (! empty($users)) { - $this->addElement( - 'multiselect', - 'user_name', - array( - 'multiOptions' => array_combine($users, $users), - 'label' => $this->translate('Backend Users'), - 'description' => $this->translate( - 'Select one or more users (fetched from your user backends) to add as group member' - ), - 'class' => 'grant-permissions' - ) - ); - } - - $this->addElement( - 'textarea', - 'users', - array( - 'required' => empty($users), - 'label' => $this->translate('Users'), - 'description' => $this->translate( - 'Provide one or more usernames separated by comma to add as group member' - ) - ) - ); - - $this->setTitle(sprintf($this->translate('Add members for group %s'), $this->groupName)); - $this->setSubmitLabel($this->translate('Add')); - } - - /** - * Insert the members for the group - * - * @return bool - */ public function onSuccess() { - $userNames = $this->getValue('user_name') ?: array(); - if (($users = $this->getValue('users'))) { - $userNames = array_merge($userNames, array_map('trim', explode(',', $users))); - } + $q = $this->getValue($this->getSearchParameter(), ''); + + $userNames = array_unique(array_filter( + array_map('trim', explode(self::TERM_SEPARATOR, rawurldecode($q))) + )); if (empty($userNames)) { - $this->info($this->translate( - 'Please provide at least one username, either by choosing one ' - . 'in the list or by manually typing one in the text box below' - )); - return false; + Notification::info(t('Please provide at least one username')); + + return; } $single = null; @@ -151,32 +72,28 @@ public function onSuccess() try { $this->backend->insert( 'group_membership', - array( + [ 'group_name' => $this->groupName, 'user_name' => $userName - ) + ] ); - } catch (NotFoundError $e) { - throw $e; // Trigger 404, the group name is initially accessed as GET parameter } catch (Exception $e) { Notification::error(sprintf( - $this->translate('Failed to add "%s" as group member for "%s"'), + t('Failed to add "%s" as group member for "%s"'), $userName, $this->groupName )); - $this->error($e->getMessage()); - return false; + + return; } $single = $single === null; } if ($single) { - Notification::success(sprintf($this->translate('Group member "%s" added successfully'), $userName)); + Notification::success(sprintf(t('Group member "%s" added successfully'), $userName)); } else { - Notification::success($this->translate('Group members added successfully')); + Notification::success(t('Group members added successfully')); } - - return true; } }