From 705bb665a520ea7b161b7c51b69c97221bb27cce Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Fri, 22 May 2015 15:53:47 +0200 Subject: [PATCH] UserController: List memberships when showing a user refs #8826 --- application/controllers/UserController.php | 71 ++++++++++++++++++++++ application/views/scripts/user/show.phtml | 60 ++++++++++++++++-- public/css/icinga/main-content.less | 28 +++++++++ 3 files changed, 154 insertions(+), 5 deletions(-) diff --git a/application/controllers/UserController.php b/application/controllers/UserController.php index 217859574..3fe3dd604 100644 --- a/application/controllers/UserController.php +++ b/application/controllers/UserController.php @@ -7,7 +7,10 @@ use Icinga\Application\Config; use Icinga\Application\Logger; use Icinga\Authentication\User\UserBackend; use Icinga\Authentication\User\UserBackendInterface; +use Icinga\Authentication\UserGroup\UserGroupBackend; use Icinga\Forms\Config\UserForm; +use Icinga\Data\DataArray\ArrayDatasource; +use Icinga\User; use Icinga\Web\Controller; use Icinga\Web\Form; use Icinga\Web\Notification; @@ -114,8 +117,53 @@ class UserController extends Controller $this->httpNotFound(sprintf($this->translate('User "%s" not found'), $userName)); } + $memberships = $this->loadMemberships(new User($userName))->select(); + + $filterEditor = Widget::create('filterEditor') + ->setQuery($memberships) + ->preserveParams('limit', 'sort', 'dir', 'view', 'backend', 'user') + ->ignoreParams('page') + ->handleRequest($this->getRequest()); + $memberships->applyFilter($filterEditor->getFilter()); + + $this->setupFilterControl($filterEditor); + $this->setupPaginationControl($memberships); + $this->setupLimitControl(); + $this->setupSortControl( + array( + 'group_name' => $this->translate('Group') + ), + $memberships + ); + $this->view->user = $user; $this->view->backend = $backend; + $this->view->memberships = $memberships; + + $removeForm = new Form(); + $removeForm->setUidDisabled(); + $removeForm->addElement('hidden', 'user_name', array( + 'isArray' => true, + 'value' => $userName, + 'decorators' => array('ViewHelper') + )); + $removeForm->addElement('hidden', 'redirect', array( + 'value' => Url::fromPath('user/show', array( + 'backend' => $backend->getName(), + 'user' => $userName + )), + 'decorators' => array('ViewHelper') + )); + $removeForm->addElement('button', 'btn_submit', array( + 'escape' => false, + 'type' => 'submit', + 'class' => 'link-like', + 'value' => 'btn_submit', + 'decorators' => array('ViewHelper'), + 'label' => $this->view->icon('trash'), + 'title' => $this->translate('Cancel this membership') + )); + $this->view->removeForm = $removeForm; } /** @@ -176,6 +224,29 @@ class UserController extends Controller $this->render('form'); } + /** + * Fetch and return the given user's groups from all user group backends + * + * @param User $user + * + * @return ArrayDatasource + */ + protected function loadMemberships(User $user) + { + $groups = array(); + foreach (Config::app('groups') as $backendName => $backendConfig) { + $backend = UserGroupBackend::create($backendName, $backendConfig); + foreach ($backend->getMemberships($user) as $groupName) { + $groups[] = (object) array( + 'group_name' => $groupName, + 'backend' => $backend + ); + } + } + + return new ArrayDatasource($groups); + } + /** * Return all user backends implementing the given interface * diff --git a/application/views/scripts/user/show.phtml b/application/views/scripts/user/show.phtml index 00b242512..cd8801b1a 100644 --- a/application/views/scripts/user/show.phtml +++ b/application/views/scripts/user/show.phtml @@ -1,6 +1,7 @@ -
- compact): ?> - showOnlyCloseButton(); ?> - + compact): ?> + showOnlyCloseButton(); ?> +

escape($user->user_name); ?>

translate('State'); ?>: is_active ? $this->translate('Active') : $this->translate('Inactive'); ?>

translate('Created at'); ?>: created_at === null ? '-' : $this->formatDateTime($user->created_at); ?>

translate('Last modified'); ?>: last_modified === null ? '-' : $this->formatDateTime($user->last_modified); ?>

+ compact): ?> + sortBox; ?> + + limiter; ?> + paginator; ?> + compact): ?> + filterEditor; ?> +
-
+
+ 0): ?> + + + + + + + + + + + + + + + +
translate('Group'); ?>translate('Cancel', 'group.membership'); ?>
qlink($membership->group_name, 'group/show', array( + 'backend' => $membership->backend->getName(), + 'group' => $membership->group_name + ), array( + 'title' => sprintf($this->translate('Show detailed information for group %s'), $membership->group_name) + )); ?> + backend instanceof Reducible): ?> + setAction($this->url('group/removemember', array( + 'backend' => $membership->backend->getName(), + 'group' => $membership->group_name + ))); ?> + + - + +
+ +

translate('No memberships found matching the filter'); ?>

+ +qlink($this->translate('Create new membership'), 'user/createmembership', array( + 'user' => $user->user_name +), array( + 'icon' => 'plus', + 'data-base-target' => '_next', + 'class' => 'membership-create' +)); ?>
\ No newline at end of file diff --git a/public/css/icinga/main-content.less b/public/css/icinga/main-content.less index 603466f67..4d5c4c896 100644 --- a/public/css/icinga/main-content.less +++ b/public/css/icinga/main-content.less @@ -228,6 +228,7 @@ div.content.users { div.controls div.user-header { border-bottom: 2px solid @colorPetrol; + margin-bottom: 1em; .user-name { display: inline-block; @@ -241,6 +242,33 @@ div.controls div.user-header { } } +div.content.memberships { + table.membership-list { + th.membership-cancel { + width: 8em; + padding-right: 0.5em; + text-align: right; + } + + td.membership-cancel { + text-align: right; + + form button.link-like { + color: inherit; + } + } + } + + p { + margin-top: 0; + } + + a.membership-create { + display: block; + margin-top: 1em; + } +} + div.content.groups { table.group-list { th.group-remove {