Skip to content

Commit 29e6715

Browse files
WIP : Introduce search field to add member to the user group
1 parent 0a41c52 commit 29e6715

File tree

3 files changed

+181
-124
lines changed

3 files changed

+181
-124
lines changed

application/controllers/GroupController.php

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
namespace Icinga\Controllers;
55

66
use Exception;
7+
use GuzzleHttp\Psr7\ServerRequest;
78
use Icinga\Application\Logger;
89
use Icinga\Authentication\User\DomainAwareInterface;
910
use Icinga\Data\DataArray\ArrayDatasource;
1011
use Icinga\Data\Filter\Filter;
1112
use Icinga\Data\Reducible;
13+
use Icinga\Data\UserSuggestions;
1214
use Icinga\Exception\NotFoundError;
1315
use Icinga\Forms\Config\UserGroup\AddMemberForm;
1416
use Icinga\Forms\Config\UserGroup\UserGroupForm;
@@ -17,10 +19,11 @@
1719
use Icinga\Web\Form;
1820
use Icinga\Web\Notification;
1921
use Icinga\Web\Url;
20-
use Icinga\Web\Widget;
22+
use ipl\Web\Url as IplUrl;
2123

2224
class GroupController extends AuthBackendController
2325
{
26+
protected $urlParams;
2427
public function init()
2528
{
2629
$this->view->title = $this->translate('User Groups');
@@ -225,23 +228,42 @@ public function addmemberAction()
225228
$this->assertPermission('config/access-control/groups');
226229
$groupName = $this->params->getRequired('group');
227230
$backend = $this->getUserGroupBackend($this->params->getRequired('backend'), 'Icinga\Data\Extensible');
228-
229-
$form = new AddMemberForm();
230-
$form->setDataSource($this->fetchUsers())
231+
$form = (new AddMemberForm())
231232
->setBackend($backend)
232233
->setGroupName($groupName)
233234
->setRedirectUrl(
234235
Url::fromPath('group/show', array('backend' => $backend->getName(), 'group' => $groupName))
235236
)
236-
->setUidDisabled();
237+
->setSuggestionUrl(IplUrl::fromPath(
238+
'group/complete',
239+
[
240+
'_disableLayout' => true,
241+
'showCompact' => true,
242+
'backend' => $this->params->getRequired('backend'),
243+
'group' => $groupName
244+
]
245+
));
237246

238-
try {
239-
$form->handleRequest();
240-
} catch (NotFoundError $_) {
241-
$this->httpNotFound(sprintf($this->translate('Group "%s" not found'), $groupName));
242-
}
247+
$form->on(AddMemberForm::ON_SUCCESS, function ($form) {
248+
$this->getResponse()->redirectAndExit($form->getRedirectUrl());
249+
});
250+
$form->handleRequest(ServerRequest::fromGlobals());
251+
252+
$this->addTitleTab($this->translate('New User Group Member'));
253+
$this->addContent($form);
254+
}
255+
256+
public function completeAction()
257+
{
258+
$backend = $this->getUserGroupBackend($this->params->getRequired('backend'), 'Icinga\Data\Extensible');
259+
$groupName = $this->params->getRequired('group');
243260

244-
$this->renderForm($form, $this->translate('New User Group Member'));
261+
$suggestions = new UserSuggestions();
262+
$suggestions->setUserGroupName($groupName);
263+
$suggestions->setUserGroupBackend($backend);
264+
$suggestions->setBackends($this->loadUserBackends('Icinga\Data\Selectable'));
265+
$suggestions->forRequest(ServerRequest::fromGlobals());
266+
$this->getDocument()->add($suggestions);
245267
}
246268

247269
/**

application/forms/Config/UserGroup/AddMemberForm.php

Lines changed: 20 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -1,129 +1,40 @@
11
<?php
2-
/* Icinga Web 2 | (c) 2015 Icinga Development Team | GPLv2+ */
2+
/* Icinga Web 2 | (c) 2022 Icinga Development Team | GPLv2+ */
33

44
namespace Icinga\Forms\Config\UserGroup;
55

66
use Exception;
7-
use Icinga\Data\Extensible;
8-
use Icinga\Data\Filter\Filter;
9-
use Icinga\Data\Selectable;
107
use Icinga\Exception\NotFoundError;
11-
use Icinga\Web\Form;
128
use Icinga\Web\Notification;
9+
use ipl\Web\Control\SimpleSearchField;
1310

1411
/**
1512
* Form for adding one or more group members
1613
*/
17-
class AddMemberForm extends Form
14+
class AddMemberForm extends SimpleSearchField
1815
{
19-
/**
20-
* The data source to fetch users from
21-
*
22-
* @var Selectable
23-
*/
24-
protected $ds;
25-
26-
/**
27-
* The user group backend to use
28-
*
29-
* @var Extensible
30-
*/
3116
protected $backend;
3217

33-
/**
34-
* The group to add members for
35-
*
36-
* @var string
37-
*/
3818
protected $groupName;
3919

4020
/**
41-
* Set the data source to fetch users from
42-
*
43-
* @param Selectable $ds
44-
*
45-
* @return $this
46-
*/
47-
public function setDataSource(Selectable $ds)
48-
{
49-
$this->ds = $ds;
50-
return $this;
51-
}
52-
53-
/**
54-
* Set the user group backend to use
55-
*
56-
* @param Extensible $backend
57-
*
58-
* @return $this
21+
* @param mixed $backend
5922
*/
60-
public function setBackend(Extensible $backend)
23+
public function setBackend($backend)
6124
{
6225
$this->backend = $backend;
26+
6327
return $this;
6428
}
6529

6630
/**
67-
* Set the group to add members for
68-
*
69-
* @param string $groupName
70-
*
71-
* @return $this
31+
* @param mixed $groupName
7232
*/
7333
public function setGroupName($groupName)
7434
{
7535
$this->groupName = $groupName;
76-
return $this;
77-
}
7836

79-
/**
80-
* Create and add elements to this form
81-
*
82-
* @param array $formData The data sent by the user
83-
*/
84-
public function createElements(array $formData)
85-
{
86-
// TODO(jom): Fetching already existing members to prevent the user from mistakenly creating duplicate
87-
// memberships (no matter whether the data source permits it or not, a member does never need to be
88-
// added more than once) should be kept at backend level (GroupController::fetchUsers) but this does
89-
// not work currently as our ldap protocol stuff is unable to handle our filter implementation..
90-
$members = $this->backend
91-
->select()
92-
->from('group_membership', array('user_name'))
93-
->where('group_name', $this->groupName)
94-
->fetchColumn();
95-
$filter = empty($members) ? Filter::matchAll() : Filter::not(Filter::where('user_name', $members));
96-
97-
$users = $this->ds->select()->from('user', array('user_name'))->applyFilter($filter)->fetchColumn();
98-
if (! empty($users)) {
99-
$this->addElement(
100-
'multiselect',
101-
'user_name',
102-
array(
103-
'multiOptions' => array_combine($users, $users),
104-
'label' => $this->translate('Backend Users'),
105-
'description' => $this->translate(
106-
'Select one or more users (fetched from your user backends) to add as group member'
107-
),
108-
'class' => 'grant-permissions'
109-
)
110-
);
111-
}
112-
113-
$this->addElement(
114-
'textarea',
115-
'users',
116-
array(
117-
'required' => empty($users),
118-
'label' => $this->translate('Users'),
119-
'description' => $this->translate(
120-
'Provide one or more usernames separated by comma to add as group member'
121-
)
122-
)
123-
);
124-
125-
$this->setTitle(sprintf($this->translate('Add members for group %s'), $this->groupName));
126-
$this->setSubmitLabel($this->translate('Add'));
37+
return $this;
12738
}
12839

12940
/**
@@ -133,48 +44,44 @@ public function createElements(array $formData)
13344
*/
13445
public function onSuccess()
13546
{
136-
$userNames = $this->getValue('user_name') ?: array();
137-
if (($users = $this->getValue('users'))) {
138-
$userNames = array_merge($userNames, array_map('trim', explode(',', $users)));
139-
}
140-
141-
if (empty($userNames)) {
142-
$this->info($this->translate(
143-
'Please provide at least one username, either by choosing one '
144-
. 'in the list or by manually typing one in the text box below'
145-
));
47+
$q = $this->getValue($this->getSearchParameter());
48+
if (empty($q)) {
49+
Notification::error(t('Please provide at least one username'));
14650
return false;
14751
}
14852

53+
$userNames = array_unique(explode(self::TERM_SEPARATOR, urldecode($q)));
54+
$userNames = array_map('trim', $userNames);
55+
14956
$single = null;
15057
foreach ($userNames as $userName) {
15158
try {
15259
$this->backend->insert(
15360
'group_membership',
154-
array(
61+
[
15562
'group_name' => $this->groupName,
15663
'user_name' => $userName
157-
)
64+
]
15865
);
15966
} catch (NotFoundError $e) {
16067
throw $e; // Trigger 404, the group name is initially accessed as GET parameter
16168
} catch (Exception $e) {
16269
Notification::error(sprintf(
163-
$this->translate('Failed to add "%s" as group member for "%s"'),
70+
t('Failed to add "%s" as group member for "%s"'),
16471
$userName,
16572
$this->groupName
16673
));
167-
$this->error($e->getMessage());
74+
16875
return false;
16976
}
17077

17178
$single = $single === null;
17279
}
17380

17481
if ($single) {
175-
Notification::success(sprintf($this->translate('Group member "%s" added successfully'), $userName));
82+
Notification::success(sprintf(t('Group member "%s" added successfully'), $userName));
17683
} else {
177-
Notification::success($this->translate('Group members added successfully'));
84+
Notification::success(t('Group members added successfully'));
17885
}
17986

18087
return true;

0 commit comments

Comments
 (0)