Rename users and usergroups to contacts and contactgroups (#1156)

This ensures that the UI will stop using the term *user* in favor of
*contact* and the term *usergroup* in favor of *contactgroup*.
Routes and denylists will also change accordingly.

What does not change, are database table names. While it would be
certainly possible, changing relation names is a breaking change I'd
like to avoid. It would break any restriction on `<type>.user.name` and
`<type>.usergroup.name`.

closes #944
This commit is contained in:
Johannes Meyer 2025-04-11 08:58:10 +02:00 committed by GitHub
commit 18332c564a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 419 additions and 288 deletions

View file

@ -357,7 +357,7 @@ class MigrateCommand extends Command
} elseif ($permission === 'no-monitoring/contacts') {
$changed = true;
$updatedPermissions[] = $permission;
$role['icingadb/denylist/routes'] = 'users,usergroups';
$role['icingadb/denylist/routes'] = 'contacts,contactgroups';
} else {
$updatedPermissions[] = $permission;
}

View file

@ -0,0 +1,48 @@
<?php
/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */
namespace Icinga\Module\Icingadb\Controllers;
use Icinga\Exception\NotFoundError;
use Icinga\Module\Icingadb\Model\User;
use Icinga\Module\Icingadb\Web\Controller;
use Icinga\Module\Icingadb\Widget\Detail\ObjectHeader;
use Icinga\Module\Icingadb\Widget\Detail\UserDetail;
use ipl\Stdlib\Filter;
class ContactController extends Controller
{
/** @var User The user object */
protected $user;
public function init()
{
$this->assertRouteAccess('contacts');
$this->addTitleTab(t('Contact'));
$name = $this->params->getRequired('name');
$query = User::on($this->getDb())->with('timeperiod');
$query->filter(Filter::equal('user.name', $name));
$this->applyRestrictions($query);
$user = $query->first();
if ($user === null) {
throw new NotFoundError(t('Contact not found'));
}
$this->user = $user;
$this->setTitle($user->display_name);
}
public function indexAction()
{
$this->addControl(new ObjectHeader($this->user));
$this->addContent(new UserDetail($this->user));
$this->setAutorefreshInterval(10);
}
}

View file

@ -0,0 +1,48 @@
<?php
/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */
namespace Icinga\Module\Icingadb\Controllers;
use Icinga\Exception\NotFoundError;
use Icinga\Module\Icingadb\Model\Usergroup;
use Icinga\Module\Icingadb\Web\Controller;
use Icinga\Module\Icingadb\Widget\Detail\ObjectHeader;
use Icinga\Module\Icingadb\Widget\Detail\UsergroupDetail;
use ipl\Stdlib\Filter;
class ContactgroupController extends Controller
{
/** @var Usergroup The usergroup object */
protected $usergroup;
public function init()
{
$this->assertRouteAccess('contactgroups');
$this->addTitleTab(t('Contact Group'));
$name = $this->params->getRequired('name');
$query = Usergroup::on($this->getDb());
$query->filter(Filter::equal('usergroup.name', $name));
$this->applyRestrictions($query);
$usergroup = $query->first();
if ($usergroup === null) {
throw new NotFoundError(t('Contact group not found'));
}
$this->usergroup = $usergroup;
$this->setTitle($usergroup->display_name);
}
public function indexAction()
{
$this->addControl(new ObjectHeader($this->usergroup));
$this->addContent(new UsergroupDetail($this->usergroup));
$this->setAutorefreshInterval(10);
}
}

View file

@ -0,0 +1,96 @@
<?php
/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */
namespace Icinga\Module\Icingadb\Controllers;
use GuzzleHttp\Psr7\ServerRequest;
use Icinga\Module\Icingadb\Model\Usergroup;
use Icinga\Module\Icingadb\Web\Control\SearchBar\ObjectSuggestions;
use Icinga\Module\Icingadb\Web\Controller;
use Icinga\Module\Icingadb\Widget\ItemList\ObjectList;
use Icinga\Module\Icingadb\Web\Control\ViewModeSwitcher;
use ipl\Web\Control\LimitControl;
use ipl\Web\Control\SortControl;
use ipl\Web\Url;
class ContactgroupsController extends Controller
{
public function init()
{
parent::init();
$this->assertRouteAccess();
}
public function indexAction()
{
$this->addTitleTab(t('Contact Groups'));
$db = $this->getDb();
$usergroups = Usergroup::on($db);
$limitControl = $this->createLimitControl();
$paginationControl = $this->createPaginationControl($usergroups);
$sortControl = $this->createSortControl(
$usergroups,
[
'usergroup.display_name' => t('Name')
]
);
$searchBar = $this->createSearchBar($usergroups, [
$limitControl->getLimitParam(),
$sortControl->getSortParam()
]);
if ($searchBar->hasBeenSent() && ! $searchBar->isValid()) {
if ($searchBar->hasBeenSubmitted()) {
$filter = $this->getFilter();
} else {
$this->addControl($searchBar);
$this->sendMultipartUpdate();
return;
}
} else {
$filter = $searchBar->getFilter();
}
$this->filter($usergroups, $filter);
yield $this->export($usergroups);
$this->addControl($paginationControl);
$this->addControl($sortControl);
$this->addControl($limitControl);
$this->addControl($searchBar);
$this->addContent(new ObjectList($usergroups));
if (! $searchBar->hasBeenSubmitted() && $searchBar->hasBeenSent()) {
$this->sendMultipartUpdate();
}
$this->setAutorefreshInterval(10);
}
public function completeAction()
{
$suggestions = new ObjectSuggestions();
$suggestions->setModel(Usergroup::class);
$suggestions->forRequest(ServerRequest::fromGlobals());
$this->getDocument()->add($suggestions);
}
public function searchEditorAction()
{
$editor = $this->createSearchEditor(Usergroup::on($this->getDb()), [
LimitControl::DEFAULT_LIMIT_PARAM,
SortControl::DEFAULT_SORT_PARAM,
ViewModeSwitcher::DEFAULT_VIEW_MODE_PARAM
]);
$this->getDocument()->add($editor);
$this->setTitle(t('Adjust Filter'));
}
}

View file

@ -0,0 +1,97 @@
<?php
/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */
namespace Icinga\Module\Icingadb\Controllers;
use GuzzleHttp\Psr7\ServerRequest;
use Icinga\Module\Icingadb\Model\User;
use Icinga\Module\Icingadb\Web\Control\SearchBar\ObjectSuggestions;
use Icinga\Module\Icingadb\Web\Controller;
use Icinga\Module\Icingadb\Widget\ItemList\ObjectList;
use Icinga\Module\Icingadb\Web\Control\ViewModeSwitcher;
use ipl\Web\Control\LimitControl;
use ipl\Web\Control\SortControl;
class ContactsController extends Controller
{
public function init()
{
parent::init();
$this->assertRouteAccess();
}
public function indexAction()
{
$this->addTitleTab(t('Contacts'));
$db = $this->getDb();
$users = User::on($db);
$limitControl = $this->createLimitControl();
$paginationControl = $this->createPaginationControl($users);
$sortControl = $this->createSortControl(
$users,
[
'user.display_name' => t('Name'),
'user.email' => t('Email'),
'user.pager' => t('Pager Address / Number')
]
);
$searchBar = $this->createSearchBar($users, [
$limitControl->getLimitParam(),
$sortControl->getSortParam()
]);
if ($searchBar->hasBeenSent() && ! $searchBar->isValid()) {
if ($searchBar->hasBeenSubmitted()) {
$filter = $this->getFilter();
} else {
$this->addControl($searchBar);
$this->sendMultipartUpdate();
return;
}
} else {
$filter = $searchBar->getFilter();
}
$this->filter($users, $filter);
yield $this->export($users);
$this->addControl($paginationControl);
$this->addControl($sortControl);
$this->addControl($limitControl);
$this->addControl($searchBar);
$this->addContent(new ObjectList($users));
if (! $searchBar->hasBeenSubmitted() && $searchBar->hasBeenSent()) {
$this->sendMultipartUpdate();
}
$this->setAutorefreshInterval(10);
}
public function completeAction()
{
$suggestions = new ObjectSuggestions();
$suggestions->setModel(User::class);
$suggestions->forRequest(ServerRequest::fromGlobals());
$this->getDocument()->add($suggestions);
}
public function searchEditorAction()
{
$editor = $this->createSearchEditor(User::on($this->getDb()), [
LimitControl::DEFAULT_LIMIT_PARAM,
SortControl::DEFAULT_SORT_PARAM,
ViewModeSwitcher::DEFAULT_VIEW_MODE_PARAM
]);
$this->getDocument()->add($editor);
$this->setTitle(t('Adjust Filter'));
}
}

View file

@ -1,48 +1,28 @@
<?php
/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */
/* Icinga DB Web | (c) 2025 Icinga GmbH | GPLv2 */
namespace Icinga\Module\Icingadb\Controllers;
use Icinga\Exception\NotFoundError;
use Icinga\Module\Icingadb\Model\User;
use Icinga\Module\Icingadb\Web\Controller;
use Icinga\Module\Icingadb\Widget\Detail\ObjectHeader;
use Icinga\Module\Icingadb\Widget\Detail\UserDetail;
use ipl\Stdlib\Filter;
/**
* @deprecated Will be removed with 1.3, use ContactController instead
*/
class UserController extends Controller
{
/** @var User The user object */
protected $user;
public function init()
public function preDispatch()
{
$this->assertRouteAccess('users');
$url = $this->getRequest()->getUrl();
$url->setPath(preg_replace(
'~^icingadb/user(?=/|$)~',
'icingadb/contact',
$url->getPath()
));
$this->addTitleTab(t('User'));
$name = $this->params->getRequired('name');
$query = User::on($this->getDb())->with('timeperiod');
$query->filter(Filter::equal('user.name', $name));
$this->applyRestrictions($query);
$user = $query->first();
if ($user === null) {
throw new NotFoundError(t('User not found'));
}
$this->user = $user;
$this->setTitle($user->display_name);
}
public function indexAction()
{
$this->addControl(new ObjectHeader($this->user));
$this->addContent(new UserDetail($this->user));
$this->setAutorefreshInterval(10);
$this->getResponse()
->setHttpResponseCode(301)
->setHeader('Location', $url->getAbsoluteUrl())
->sendResponse();
}
}

View file

@ -1,48 +1,28 @@
<?php
/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */
/* Icinga DB Web | (c) 2025 Icinga GmbH | GPLv2 */
namespace Icinga\Module\Icingadb\Controllers;
use Icinga\Exception\NotFoundError;
use Icinga\Module\Icingadb\Model\Usergroup;
use Icinga\Module\Icingadb\Web\Controller;
use Icinga\Module\Icingadb\Widget\Detail\ObjectHeader;
use Icinga\Module\Icingadb\Widget\Detail\UsergroupDetail;
use ipl\Stdlib\Filter;
/**
* @deprecated Will be removed with 1.3, use ContactgroupController instead
*/
class UsergroupController extends Controller
{
/** @var Usergroup The usergroup object */
protected $usergroup;
public function init()
public function preDispatch()
{
$this->assertRouteAccess('usergroups');
$url = $this->getRequest()->getUrl();
$url->setPath(preg_replace(
'~^icingadb/usergroup(?=/|$)~',
'icingadb/contactgroup',
$url->getPath()
));
$this->addTitleTab(t('User Group'));
$name = $this->params->getRequired('name');
$query = Usergroup::on($this->getDb());
$query->filter(Filter::equal('usergroup.name', $name));
$this->applyRestrictions($query);
$usergroup = $query->first();
if ($usergroup === null) {
throw new NotFoundError(t('User group not found'));
}
$this->usergroup = $usergroup;
$this->setTitle($usergroup->display_name);
}
public function indexAction()
{
$this->addControl(new ObjectHeader($this->usergroup));
$this->addContent(new UsergroupDetail($this->usergroup));
$this->setAutorefreshInterval(10);
$this->getResponse()
->setHttpResponseCode(301)
->setHeader('Location', $url->getAbsoluteUrl())
->sendResponse();
}
}

View file

@ -1,96 +1,28 @@
<?php
/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */
/* Icinga DB Web | (c) 2025 Icinga GmbH | GPLv2 */
namespace Icinga\Module\Icingadb\Controllers;
use GuzzleHttp\Psr7\ServerRequest;
use Icinga\Module\Icingadb\Model\Usergroup;
use Icinga\Module\Icingadb\Web\Control\SearchBar\ObjectSuggestions;
use Icinga\Module\Icingadb\Web\Controller;
use Icinga\Module\Icingadb\Widget\ItemList\ObjectList;
use Icinga\Module\Icingadb\Web\Control\ViewModeSwitcher;
use ipl\Web\Control\LimitControl;
use ipl\Web\Control\SortControl;
use ipl\Web\Url;
/**
* @deprecated Will be removed with 1.3, use ContactgroupsController instead
*/
class UsergroupsController extends Controller
{
public function init()
public function preDispatch()
{
parent::init();
$url = $this->getRequest()->getUrl();
$url->setPath(preg_replace(
'~^icingadb/usergroups(?=/|$)~',
'icingadb/contactgroups',
$url->getPath()
));
$this->assertRouteAccess();
}
public function indexAction()
{
$this->addTitleTab(t('User Groups'));
$db = $this->getDb();
$usergroups = Usergroup::on($db);
$limitControl = $this->createLimitControl();
$paginationControl = $this->createPaginationControl($usergroups);
$sortControl = $this->createSortControl(
$usergroups,
[
'usergroup.display_name' => t('Name')
]
);
$searchBar = $this->createSearchBar($usergroups, [
$limitControl->getLimitParam(),
$sortControl->getSortParam()
]);
if ($searchBar->hasBeenSent() && ! $searchBar->isValid()) {
if ($searchBar->hasBeenSubmitted()) {
$filter = $this->getFilter();
} else {
$this->addControl($searchBar);
$this->sendMultipartUpdate();
return;
}
} else {
$filter = $searchBar->getFilter();
}
$this->filter($usergroups, $filter);
yield $this->export($usergroups);
$this->addControl($paginationControl);
$this->addControl($sortControl);
$this->addControl($limitControl);
$this->addControl($searchBar);
$this->addContent(new ObjectList($usergroups));
if (! $searchBar->hasBeenSubmitted() && $searchBar->hasBeenSent()) {
$this->sendMultipartUpdate();
}
$this->setAutorefreshInterval(10);
}
public function completeAction()
{
$suggestions = new ObjectSuggestions();
$suggestions->setModel(Usergroup::class);
$suggestions->forRequest(ServerRequest::fromGlobals());
$this->getDocument()->add($suggestions);
}
public function searchEditorAction()
{
$editor = $this->createSearchEditor(Usergroup::on($this->getDb()), [
LimitControl::DEFAULT_LIMIT_PARAM,
SortControl::DEFAULT_SORT_PARAM,
ViewModeSwitcher::DEFAULT_VIEW_MODE_PARAM
]);
$this->getDocument()->add($editor);
$this->setTitle(t('Adjust Filter'));
$this->getResponse()
->setHttpResponseCode(301)
->setHeader('Location', $url->getAbsoluteUrl())
->sendResponse();
}
}

View file

@ -1,98 +1,28 @@
<?php
/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */
/* Icinga DB Web | (c) 2025 Icinga GmbH | GPLv2 */
namespace Icinga\Module\Icingadb\Controllers;
use GuzzleHttp\Psr7\ServerRequest;
use Icinga\Module\Icingadb\Model\User;
use Icinga\Module\Icingadb\Web\Control\SearchBar\ObjectSuggestions;
use Icinga\Module\Icingadb\Web\Controller;
use Icinga\Module\Icingadb\Widget\ItemList\ObjectList;
use Icinga\Module\Icingadb\Web\Control\ViewModeSwitcher;
use ipl\Web\Control\LimitControl;
use ipl\Web\Control\SortControl;
use ipl\Web\Url;
/**
* @deprecated Will be removed with 1.3, use ContactsController instead
*/
class UsersController extends Controller
{
public function init()
public function preDispatch()
{
parent::init();
$url = $this->getRequest()->getUrl();
$url->setPath(preg_replace(
'~^icingadb/users(?=/|$)~',
'icingadb/contacts',
$url->getPath()
));
$this->assertRouteAccess();
}
public function indexAction()
{
$this->addTitleTab(t('Users'));
$db = $this->getDb();
$users = User::on($db);
$limitControl = $this->createLimitControl();
$paginationControl = $this->createPaginationControl($users);
$sortControl = $this->createSortControl(
$users,
[
'user.display_name' => t('Name'),
'user.email' => t('Email'),
'user.pager' => t('Pager Address / Number')
]
);
$searchBar = $this->createSearchBar($users, [
$limitControl->getLimitParam(),
$sortControl->getSortParam()
]);
if ($searchBar->hasBeenSent() && ! $searchBar->isValid()) {
if ($searchBar->hasBeenSubmitted()) {
$filter = $this->getFilter();
} else {
$this->addControl($searchBar);
$this->sendMultipartUpdate();
return;
}
} else {
$filter = $searchBar->getFilter();
}
$this->filter($users, $filter);
yield $this->export($users);
$this->addControl($paginationControl);
$this->addControl($sortControl);
$this->addControl($limitControl);
$this->addControl($searchBar);
$this->addContent(new ObjectList($users));
if (! $searchBar->hasBeenSubmitted() && $searchBar->hasBeenSent()) {
$this->sendMultipartUpdate();
}
$this->setAutorefreshInterval(10);
}
public function completeAction()
{
$suggestions = new ObjectSuggestions();
$suggestions->setModel(User::class);
$suggestions->forRequest(ServerRequest::fromGlobals());
$this->getDocument()->add($suggestions);
}
public function searchEditorAction()
{
$editor = $this->createSearchEditor(User::on($this->getDb()), [
LimitControl::DEFAULT_LIMIT_PARAM,
SortControl::DEFAULT_SORT_PARAM,
ViewModeSwitcher::DEFAULT_VIEW_MODE_PARAM
]);
$this->getDocument()->add($editor);
$this->setTitle(t('Adjust Filter'));
$this->getResponse()
->setHttpResponseCode(301)
->setHeader('Location', $url->getAbsoluteUrl())
->sendResponse();
}
}

View file

@ -373,26 +373,30 @@ namespace Icinga\Module\Icingadb {
]);
}
if (! array_key_exists('usergroups', $routeDenylist)) {
$overviewSection->add(N_('User Groups'), [
'description' => $this->translate('List user groups'),
'url' => 'icingadb/usergroups',
if (
! array_key_exists('usergroups', $routeDenylist) // TODO: Remove with 1.3, compat only
&& ! array_key_exists('contactgroups', $routeDenylist)
) {
$overviewSection->add(N_('Contact Groups'), [
'description' => $this->translate('List contact groups'),
'url' => 'icingadb/contactgroups',
'priority' => 90,
'icon' => 'users'
]);
}
if (! array_key_exists('users', $routeDenylist)) {
$overviewSection->add(N_('Users'), [
'description' => $this->translate('List users'),
'url' => 'icingadb/users',
if (
! array_key_exists('users', $routeDenylist) // TODO: Remove with 1.3, compat only
&& ! array_key_exists('contacts', $routeDenylist)
) {
$overviewSection->add(N_('Contacts'), [
'description' => $this->translate('List contacts'),
'url' => 'icingadb/contacts',
'priority' => 100,
'icon' => 'user-friends'
]);
}
$overviewSection->add(N_('Comments'), [
'url' => 'icingadb/comments',
'description' => $this->translate('List comments'),
@ -501,20 +505,26 @@ namespace Icinga\Module\Icingadb {
]);
}
if (! array_key_exists('usergroups', $routeDenylist)) {
$section->add(N_('User Groups'), [
'url' => 'icingadb/usergroups',
if (
! array_key_exists('usergroups', $routeDenylist) // TODO: Remove with 1.3, compat only
&& ! array_key_exists('contactgroups', $routeDenylist)
) {
$section->add(N_('Contact Groups'), [
'url' => 'icingadb/contactgroups',
'priority' => 70,
'description' => $this->translate('List user groups'),
'description' => $this->translate('List contact groups'),
'icon' => 'users'
]);
}
if (! array_key_exists('users', $routeDenylist)) {
$section->add(N_('Users'), [
'url' => 'icingadb/users',
if (
! array_key_exists('users', $routeDenylist) // TODO: Remove with 1.3, compat only
&& ! array_key_exists('contacts', $routeDenylist)
) {
$section->add(N_('Contacts'), [
'url' => 'icingadb/contacts',
'priority' => 80,
'description' => $this->translate('List users'),
'description' => $this->translate('List contacts'),
'icon' => 'user-friends'
]);
}

View file

@ -77,7 +77,7 @@ icingadb/denylist/variables | Hide custom variables of Icinga objects that are p
`icingadb/denylist/routes` will block users from accessing defined routes and from related information elsewhere.
For example, if `hostgroups` are part of the list a user won't have access to the hostgroup overview nor to a host's
groups shown in its detail area. This should be a comma separated list. Possible values are: hostgroups, servicegroups,
users, usergroups
contacts, contactgroups
`icingadb/denylist/variables` will block users from accessing certain custom variables. A user affected by this won't
see that those variables even exist. This should be a comma separated list of [variable paths](#variable-paths). It is

View file

@ -150,7 +150,7 @@ The command permissions have not changed. It is only the module identifier that
`monitoring/command/*` is now `icingadb/command/*`
The `no-monitoring/contacts` permission (or *fake refusal*) is now a restriction: `icingadb/denylist/routes`.
Add `users,usergroups` to it to achieve the same effect.
Add `contacts,contactgroups` to it to achieve the same effect.
### Perform The Migration

View file

@ -41,7 +41,17 @@ trait Auth
return StringHelper::trimSplit($restriction);
}, $this->getAuth()->getRestrictions('icingadb/denylist/routes'))));
return ! array_key_exists($name, $routeDenylist);
if (! array_key_exists($name, $routeDenylist)) {
if ($name === 'contacts' && array_key_exists('users', $routeDenylist)) {
return false; // TODO: Remove with 1.3, compat only
} elseif ($name === 'contactgroups' && array_key_exists('usergroups', $routeDenylist)) {
return false; // TODO: Remove with 1.3, compat only
}
return true;
}
return false;
}
/**

View file

@ -118,22 +118,22 @@ abstract class Links
public static function user(User $user): Url
{
return Url::fromPath('icingadb/user', ['name' => $user->name]);
return Url::fromPath('icingadb/contact', ['name' => $user->name]);
}
public static function usergroup(Usergroup $usergroup): Url
{
return Url::fromPath('icingadb/usergroup', ['name' => $usergroup->name]);
return Url::fromPath('icingadb/contactgroup', ['name' => $usergroup->name]);
}
public static function users(): Url
{
return Url::fromPath('icingadb/users');
return Url::fromPath('icingadb/contacts');
}
public static function usergroups(): Url
{
return Url::fromPath('icingadb/usergroups');
return Url::fromPath('icingadb/contactgroups');
}
public static function event(History $event): Url

View file

@ -31,8 +31,8 @@ class UrlMigrator
'monitoring/service/history' => ['service', 'icingadb/service/history'],
'monitoring/list/hostgroups' => ['hostgroups', 'icingadb/hostgroups'],
'monitoring/list/servicegroups' => ['servicegroups', 'icingadb/servicegroups'],
'monitoring/list/contactgroups' => ['contactgroups', 'icingadb/usergroups'],
'monitoring/list/contacts' => ['contacts', 'icingadb/users'],
'monitoring/list/contactgroups' => ['contactgroups', 'icingadb/contactgroups'],
'monitoring/list/contacts' => ['contacts', 'icingadb/contacts'],
'monitoring/list/comments' => ['comments', 'icingadb/comments'],
'monitoring/list/downtimes' => ['downtimes', 'icingadb/downtimes'],
'monitoring/list/eventhistory' => ['history', 'icingadb/history'],

View file

@ -80,7 +80,7 @@ class NotificationHistory extends Model
'previous_hard_state' => t('Previous Hard State'),
'author' => t('Notification Author'),
'text' => t('Notification Text'),
'users_notified' => t('Users Notified')
'users_notified' => t('Contacts Notified')
];
}

View file

@ -49,11 +49,11 @@ class Usergroup extends Model
{
return [
'environment_id' => t('Environment Id'),
'name_checksum' => t('Usergroup Name Checksum'),
'properties_checksum' => t('Usergroup Properties Checksum'),
'name' => t('Usergroup Name'),
'name_ci' => t('Usergroup Name (CI)'),
'display_name' => t('Usergroup Display Name'),
'name_checksum' => t('Contactgroup Name Checksum'),
'properties_checksum' => t('Contactgroup Properties Checksum'),
'name' => t('Contactgroup Name'),
'name_ci' => t('Contactgroup Name (CI)'),
'display_name' => t('Contactgroup Display Name'),
'zone_id' => t('Zone Id')
];
}

View file

@ -55,8 +55,8 @@ class ObjectSuggestions extends Suggestions
'service' => t('Service %s', '..<customvar-name>'),
'servicegroup' => t('Servicegroup %s', '..<customvar-name>'),
'timeperiod' => t('Timeperiod %s', '..<customvar-name>'),
'user' => t('User %s', '..<customvar-name>'),
'usergroup' => t('Usergroup %s', '..<customvar-name>')
'user' => t('Contact %s', '..<customvar-name>'),
'usergroup' => t('Contactgroup %s', '..<customvar-name>')
];
}

View file

@ -152,14 +152,14 @@ class EventDetail extends BaseHtmlElement
$eventInfo[] = new HorizontalKeyValue($objectKey, $objectInfo);
$notifiedUsers = [new HtmlElement('h2', null, Text::create(t('Notified Users')))];
$notifiedUsers = [new HtmlElement('h2', null, Text::create(t('Notified Contacts')))];
if ($notification->users_notified === 0) {
$notifiedUsers[] = new EmptyState(t('None', 'notified users: none'));
} elseif (! $this->isPermittedRoute('users')) {
} elseif (! $this->isPermittedRoute('contacts')) {
$notifiedUsers[] = Text::create(sprintf(tp(
'This notification was sent to a single user',
'This notification was sent to %d users',
'This notification was sent to a single contact',
'This notification was sent to %d contacts',
$notification->users_notified
), $notification->users_notified));
} elseif ($notification->users_notified > 0) {

View file

@ -402,14 +402,14 @@ class ObjectDetail extends BaseHtmlElement
return [
Html::tag('h2', t('Notifications')),
new HorizontalKeyValue(
t('Users'),
$userList->hasContent() ? $userList : new EmptyState(t('No users configured.'))
t('Contacts'),
$userList->hasContent() ? $userList : new EmptyState(t('No contacts configured.'))
),
new HorizontalKeyValue(
t('User Groups'),
t('Contact Groups'),
$usergroupList->hasContent()
? $usergroupList
: new EmptyState(t('No user groups configured.'))
: new EmptyState(t('No contact groups configured.'))
)
];
}
@ -574,7 +574,7 @@ class ObjectDetail extends BaseHtmlElement
}
$userQuery = null;
if ($this->isPermittedRoute('users')) {
if ($this->isPermittedRoute('contacts')) {
$userQuery = User::on($this->getDb());
$userQuery->filter($objectFilter);
$this->applyRestrictions($userQuery);
@ -587,7 +587,7 @@ class ObjectDetail extends BaseHtmlElement
}
}
if ($this->isPermittedRoute('usergroups')) {
if ($this->isPermittedRoute('contactgroups')) {
$usergroupQuery = Usergroup::on($this->getDb());
$usergroupQuery->filter($objectFilter);
$this->applyRestrictions($usergroupQuery);

View file

@ -74,7 +74,7 @@ class UsergroupDetail extends BaseHtmlElement
))->setBaseTarget('_next');
return [
new HtmlElement('h2', null, Text::create(t('Users'))),
new HtmlElement('h2', null, Text::create(t('Contacts'))),
new ObjectList($users),
$showMoreLink
];

View file

@ -209,13 +209,13 @@ class ObjectList extends ItemList
case $data instanceof User:
$this
->setDetailUrl(Url::fromPath('icingadb/user'))
->setDetailUrl(Url::fromPath('icingadb/contact'))
->addDetailFilterAttribute($item, Filter::equal('name', $object->name));
break;
case $object instanceof Usergroup:
$this
->setDetailUrl(Url::fromPath('icingadb/usergroup'))
->setDetailUrl(Url::fromPath('icingadb/contactgroup'))
->addDetailFilterAttribute($item, Filter::equal('name', $object->name));
break;

View file

@ -499,7 +499,7 @@ class MigrateCommandTest extends TestCase
],
'no-monitoring-contacts' => [
'permissions' => 'module/monitoring,no-monitoring/contacts',
'icingadb/denylist/routes' => 'users,usergroups'
'icingadb/denylist/routes' => 'contacts,contactgroups'
],
'reporting-only' => [
'permissions' => 'module/reporting'