'super_role', 'type' => 3, 'rules' => [ 'services.write.mode' => 1 ] ] ]); $this->assertArrayHasKey('roleids', $role); self::$super_roleid = $role['roleids'][0]; $user = CDataHelper::call('user.create', [ [ 'username' => 'user_for_role', 'passwd' => 'zabbixzabbix', 'roleid' => self::$super_roleid, 'usrgrps' => [ [ 'usrgrpid' => '7' ] ] ] ]); $this->assertArrayHasKey('userids', $user); self::$super_user = $user['userids'][0]; } /** * Scheduled report. */ public function prepareReportData() { $response = CDataHelper::call('report.create', [ [ 'userid' => self::$super_user, 'name' => 'test_report_for_role', 'dashboardid' => '1', 'users' => [ [ 'userid' => self::$super_user, 'exclude' => '0' ] ] ] ]); $this->assertArrayHasKey('reportids', $response); self::$reportid = $response['reportids'][0]; } public function prepareServiceData() { // Remove all unnecessary services before proceeding with execution. DBExecute('DELETE FROM services'); // Create services for Service permission checks. CDataHelper::call('service.create', [ [ 'name' => 'Parent 1', 'algorithm' => 1, 'sortorder' => 1 ], [ 'name' => 'Parent 2', 'algorithm' => 2, 'sortorder' => 2 ], [ 'name' => 'Child of parent 1', 'algorithm' => 2, 'sortorder' => 1, 'tags' => [ [ 'tag' => 'test', 'value' => 'test123' ] ] ], [ 'name' => 'Child of child 1', 'algorithm' => 2, 'sortorder' => 1 ], [ 'name' => 'Child of parent 2', 'algorithm' => 2, 'sortorder' => 1 ] ]); $services = CDataHelper::getIds('name'); CDataHelper::call('service.update', [ [ 'serviceid' => $services['Child of parent 1'], 'parents' => [ [ 'serviceid' => $services['Parent 1'] ] ], 'children' => [ [ 'serviceid' => $services['Child of child 1'] ] ] ], [ 'serviceid' => $services['Child of parent 2'], 'parents' => [ [ 'serviceid' => $services['Parent 2'] ] ] ] ]); } public static function getPageActionsData() { return [ // Map creation/edit. [ [ 'page_buttons' => [ 'Create map', 'Import', 'Delete' ], 'form_button' => [ 'Edit map' ], 'list_link' => 'sysmaps.php', 'action_link' => 'zabbix.php?action=map.view&sysmapid=1', 'action' => 'Create and edit maps', 'check_links' => ['sysmap.php?sysmapid=1', 'sysmaps.php?form=Create+map'] ] ], // Dashboard creation/edit. [ [ 'page_buttons' => [ 'Create dashboard', 'Delete' ], 'form_button' => [ 'Edit dashboard' ], 'list_link' => 'zabbix.php?action=dashboard.list', 'action_link' => 'zabbix.php?action=dashboard.view&dashboardid=1220', 'action' => 'Create and edit dashboards', 'check_links' => ['zabbix.php?action=dashboard.view&new=1'] ] ], // Manage scheduled reports. [ [ 'report' => true, 'page_buttons' => [ 'Create report', 'Enable', 'Disable', 'Delete' ], 'form_button' => [ 'Update', 'Clone', 'Test', 'Delete', 'Cancel' ], 'list_link' => 'zabbix.php?action=scheduledreport.list', 'action' => 'Manage scheduled reports', 'check_links' => ['zabbix.php?action=scheduledreport.edit'] ] ] ]; } /** * Check creation/edit for dashboard, map, reports. * * @dataProvider getPageActionsData */ public function testUserRolesPermissions_PageActions($data) { $this->page->userLogin('user_for_role', 'zabbixzabbix'); foreach ([true, false] as $action_status) { $this->page->open($data['list_link'])->waitUntilReady(); $this->query('class:list-table')->asTable()->waitUntilVisible()->one()->getRow(0)->select(); foreach ($data['page_buttons'] as $button) { $this->assertTrue($this->query('button', $button)->one()->isEnabled($action_status)); } $this->page->open(array_key_exists('report', $data) ? 'zabbix.php?action=scheduledreport.edit&reportid='. self::$reportid : $data['action_link'])->waitUntilReady(); foreach ($data['form_button'] as $text) { $this->assertTrue($this->query('button', $text)->one()->isEnabled(($text === 'Cancel') ? true : $action_status)); } if ($action_status) { $this->changeRoleRule([$data['action'] => false]); } } $this->checkLinks($data['check_links']); } /** * Check creation/edit for maintenance. */ public function testUserRolesPermissions_MaintenanceActions() { $form_button = [ 'Update', 'Clone', 'Delete', 'Cancel']; $headers = ['', 'Name', 'Type', 'Active since', 'Active till', 'State', 'Description']; $this->page->userLogin('user_for_role', 'zabbixzabbix'); foreach ([true, false] as $action_status) { $this->page->open('zabbix.php?action=maintenance.list')->waitUntilReady(); $this->assertTrue($this->query('button', 'Create maintenance period')->one()->isEnabled($action_status)); $table = $this->query('class:list-table')->asTable()->waitUntilVisible()->one(); if ($action_status) { $table->getRow(0)->select(); $this->assertTrue($this->query('button', 'Delete')->one()->isEnabled()); } else { // Checkboxes and the Delete button are not visible. $this->assertFalse($this->query('button', 'Delete')->one(false)->isValid()); $this->assertFalse($this->query('id:maintenanceids_1')->one(false)->isValid()); array_shift($headers); } $this->assertEquals($headers, $table->getHeadersText()); $table->getRow(0)->getColumn('Name')->query('tag:a')->one()->click(); $dialog = COverlayDialogElement::find()->waitUntilReady()->one(); foreach ($form_button as $text) { $this->assertTrue($dialog->getFooter()->query('button', $text)->one()->isEnabled(($text === 'Cancel') ? true : $action_status)); } $dialog->close(); if ($action_status) { $this->changeRoleRule(['Create and edit maintenance' => false]); } } } public static function getProblemActionsData() { return [ // Message. [ [ 'activityid' => 'message', 'action' => 'Add problem comments', 'column' => 'Message', 'value' => 'test_text' ] ], // Severity. [ [ 'activityid' => 'change_severity', 'action' => 'Change severity', 'column' => 'Severity', 'value' => 'Average' ] ], // Close problem. [ [ 'activityid' => 'close_problem', 'action' => 'Close problems', 'column' => 'Status', 'value' => 'CLOSING' ] ], // Acknowledge problem. [ [ 'activityid' => 'acknowledge_problem', 'action' => 'Acknowledge problems', 'column' => 'Update', 'value' => 'Update' ] ] ]; } /** * Check problem actions. * * @backupOnce events * * @dataProvider getProblemActionsData */ public function testUserRolesPermissions_ProblemAction($data) { $this->page->userLogin('user_for_role', 'zabbixzabbix'); foreach ([true, false] as $action_status) { $this->page->open('zabbix.php?action=problem.view')->waitUntilReady(); $row = $this->query('class:list-table')->asTable()->one()->findRow('Problem', 'Test trigger with tag'); $row->getColumn('Update')->query('link:Update')->waitUntilClickable()->one()->click(); $dialog = COverlayDialogElement::find()->waitUntilReady()->one(); $this->assertTrue($dialog->query('id', $data['activityid'])->one()->isEnabled($action_status)); $this->changeRoleRule([$data['action'] => !$action_status]); // Check that problem actions works after they were turned on. if ($action_status === false) { $this->page->open('zabbix.php?action=problem.view')->waitUntilReady(); $row->getColumn('Update')->query('link:Update')->waitUntilCLickable()->one()->click(); COverlayDialogElement::find()->waitUntilReady()->one(); if ($data['activityid'] === 'message') { $dialog->query('id:message')->one()->fill('test_text'); $dialog->query('button:Update')->one()->click(); $dialog->ensureNotPresent(); $this->page->waitUntilReady(); $row->getColumn('Actions')->query("xpath:.//button[". CXPathHelper::fromClass('zi-alert-with-content')."]")->one()->click(); $message_hint = $this->query('xpath://div[@data-hintboxid]')->asOverlayDialog()->waitUntilPresent()->all()->last(); $value = $message_hint->query('class:list-table')->asTable()->one()->getRow(0)->getColumn($data['column'])->getText(); $this->assertEquals($data['value'], $value); } else { $dialog->query('id', $data['activityid'])->asCheckbox()->one()->check(); if ($data['activityid'] === 'change_severity') { $dialog->query('id:severity')->asSegmentedRadio()->one()->fill('Average'); } $dialog->query('button:Update')->one()->click(); $this->page->waitUntilReady(); $status = $row->getColumn($data['column'])->getText(); $this->assertEquals($data['value'], $status); } } } } /** * Check that Acknowledge link is disabled after all problem actions is disabled. */ public function testUserRolesPermissions_ProblemsActionsAll() { $problem = 'Test trigger with tag'; $actions = [ 'Add problem comments' => false, 'Change severity' => false, 'Acknowledge problems' => false, 'Suppress problems' => false, 'Close problems' => false, 'Change problem ranking' => false ]; $this->page->userLogin('user_for_role', 'zabbixzabbix'); foreach ([true, false] as $action_status) { // Problem page. $this->page->open('zabbix.php?action=problem.view')->waitUntilReady(); $problem_row = $this->query('class:list-table')->asTable()->one()->findRow('Problem', $problem); $this->assertEquals($action_status, $problem_row->getColumn('Update')->query('xpath:.//*[text()="Update"]') ->one()->isAttributePresent('onclick')); // Problem widget in dashboard. $this->page->open('zabbix.php?action=dashboard.view&dashboardid=1')->waitUntilReady(); $table = CDashboardElement::find()->one()->getWidget('Current problems')->query('class:list-table')->asTable()->one(); $this->assertEquals($action_status, $table->findRow('Problem • Severity', $problem)->getColumn('Update') ->query('xpath:.//*[text()="Update"]')->one()->isAttributePresent('onclick')); // Event details page. $this->page->open('tr_events.php?triggerid=99251&eventid=93')->waitUntilReady(); $table = $this->query('xpath://h4[text()='.CXPathHelper::escapeQuotes('Event list [previous 20]'). ']/../..//table')->asTable()->one(); $this->assertEquals($action_status, $table->query('xpath:(.//*[text()="Update"])[2]') ->one()->isAttributePresent('onclick')); if ($action_status) { $this->changeRoleRule($actions); } } } public static function getScriptActionData() { return [ // Monitoring problems page. [ [ 'link' => 'zabbix.php?action=problem.view', 'selector' => 'xpath:(//a[@class="link-action wordbreak" and text()="ЗАББИКС Сервер"])[1]' ] ], // Dashboard problem widget. [ [ 'link' => 'zabbix.php?action=dashboard.view&dashboardid=1', 'selector' => 'link:ЗАББИКС Сервер' ] ], // Monitoring hosts page. [ [ 'link' => 'zabbix.php?action=host.view', 'selector' => 'link:3_Host_to_check_Monitoring_Overview' ] ], // Event detail page. [ [ 'link' => 'tr_events.php?triggerid=99251&eventid=93', 'selector' => 'xpath:(//*[@class="list-table"])[1]//*[text()="ЗАББИКС Сервер"]' ] ], // Monitoring maps page. [ [ 'link' => 'zabbix.php?action=map.view&sysmapid=1', 'selector' => 'xpath://*[name()="g"][@class="map-elements"]/*[name()="image"]' ] ] ]; } /** * Check script actions. * * @dataProvider getScriptActionData */ public function testUserRolesPermissions_ScriptAction($data) { $context_before = [ 'Dashboards', 'Problems', 'Latest data', 'Graphs', 'Web', 'Inventory', 'Host', 'Items', 'Triggers', 'Discovery', 'Web', 'Detect operating system', 'Ping', 'Traceroute' ]; $context_after = [ 'Dashboards', 'Problems', 'Latest data', 'Graphs', 'Web', 'Inventory', 'Host', 'Items', 'Triggers', 'Discovery', 'Web' ]; $this->page->userLogin('user_for_role', 'zabbixzabbix'); foreach ([true, false] as $action_status) { $this->page->open($data['link'])->waitUntilReady(); $this->query($data['selector'])->waitUntilPresent()->one()->click(); $popup = CPopupMenuElement::find()->waitUntilVisible()->one(); if ($action_status) { $this->assertTrue($popup->hasItems($context_before)); $this->assertEquals(['VIEW', 'CONFIGURATION', 'SCRIPTS'], $popup->getTitles()->asText()); $this->changeRoleRule(['Execute scripts' => false]); } else { $this->assertTrue($popup->hasItems($context_after)); $this->assertEquals(['VIEW', 'CONFIGURATION'], $popup->getTitles()->asText()); $this->changeRoleRule(['Execute scripts' => true]); } } } /** * Module enable/disable. */ public function testUserRolesPermissions_Module() { $pages_before = [ 'Dashboards', 'Monitoring', 'Services', 'Inventory', 'Reports', 'Data collection', 'Alerts', 'Users', 'Administration', 'Module 5 menu' ]; $this->page->userLogin('user_for_role', 'zabbixzabbix'); $this->page->open('zabbix.php?action=module.list')->waitUntilReady(); $this->query('button:Scan directory')->one()->click(); $this->query('class:list-table')->asTable()->one()->findRows('Name', '5th Module')->select(); $this->query('button:Enable')->one()->click(); $this->page->acceptAlert(); $this->page->waitUntilReady(); $this->assertMessage(TEST_GOOD, 'Module enabled'); foreach ([true, false] as $action_status) { $page_number = $this->query('xpath://ul[@class="menu-main"]/li/a')->count(); $all_pages = []; for ($i = 1; $i <= $page_number; ++$i) { $all_pages[] = $this->query('xpath:(//ul[@class="menu-main"]/li/a)['.$i.']')->one()->getText(); } if ($action_status) { $this->assertEquals($pages_before, $all_pages); $this->changeRoleRule(['5th Module' => false]); } else { $pages_after = array_values(array_diff($pages_before, ['Module 5 menu'])); $this->assertEquals($pages_after, $all_pages); } } } public static function getUIData() { return [ [ [ 'section' => 'Inventory', 'page' => 'Overview', 'displayed_ui' => [ 'Hosts' ], 'link' => ['hostinventoriesoverview.php'] ] ], [ [ 'section' => 'Inventory', 'page' => 'Hosts', 'displayed_ui' => [ 'Overview' ], 'link' => ['hostinventories.php'] ] ], [ [ 'section' => 'Reports', 'page' => 'Availability report', 'displayed_ui' => [ 'Scheduled reports', 'System information', 'Top 100 triggers', 'Audit log', 'Action log', 'Notifications' ], 'link' => ['report2.php'] ] ], [ [ 'section' => 'Reports', 'page' => 'System information', 'displayed_ui' => [ 'Scheduled reports', 'Availability report', 'Top 100 triggers', 'Audit log', 'Action log', 'Notifications' ], 'link' => ['zabbix.php?action=report.status'] ] ], [ [ 'section' => 'Reports', 'page' => 'Availability report', 'displayed_ui' => [ 'System information', 'Scheduled reports', 'Top 100 triggers', 'Audit log', 'Action log', 'Notifications' ], 'link' => ['report2.php'] ] ], [ [ 'section' => 'Reports', 'page' => 'Top 100 triggers', 'displayed_ui' => [ 'Availability report', 'System information', 'Scheduled reports', 'Audit log', 'Action log', 'Notifications' ], 'link' => ['zabbix.php?action=toptriggers.list'] ] ], [ [ 'section' => 'Reports', 'page' => 'Audit log', 'displayed_ui' => [ 'Availability report', 'System information', 'Scheduled reports', 'Top 100 triggers', 'Action log', 'Notifications' ], 'link' => ['zabbix.php?action=auditlog.list'] ] ], [ [ 'section' => 'Reports', 'page' => 'Action log', 'displayed_ui' => [ 'Availability report', 'System information', 'Scheduled reports', 'Top 100 triggers', 'Audit log', 'Notifications' ], 'link' => ['zabbix.php?action=actionlog.list'] ] ], [ [ 'section' => 'Reports', 'page' => 'Notifications', 'displayed_ui' => [ 'Availability report', 'System information', 'Scheduled reports', 'Top 100 triggers', 'Audit log', 'Action log' ], 'link' => ['report4.php'] ] ], [ [ 'section' => 'Data collection', 'page' => 'Template groups', 'displayed_ui' => [ 'Host groups', 'Templates', 'Hosts', 'Maintenance', 'Event correlation', 'Discovery' ], 'link' => ['zabbix.php?action=templategroup.list'] ] ], [ [ 'section' => 'Data collection', 'page' => 'Host groups', 'displayed_ui' => [ 'Template groups', 'Templates', 'Hosts', 'Maintenance', 'Event correlation', 'Discovery' ], 'link' => ['zabbix.php?action=hostgroup.list'] ] ], [ [ 'section' => 'Data collection', 'page' => 'Templates', 'displayed_ui' => [ 'Template groups', 'Host groups', 'Hosts', 'Maintenance', 'Event correlation', 'Discovery' ], 'link' => ['zabbix.php?action=template.list'] ] ], [ [ 'section' => 'Data collection', 'page' => 'Hosts', 'displayed_ui' => [ 'Template groups', 'Host groups', 'Templates', 'Maintenance', 'Event correlation', 'Discovery' ], 'link' => ['zabbix.php?action=host.list'] ] ], [ [ 'section' => 'Data collection', 'page' => 'Maintenance', 'displayed_ui' => [ 'Template groups', 'Host groups', 'Templates', 'Hosts', 'Event correlation', 'Discovery' ], 'link' => ['zabbix.php?action=maintenance.list'] ] ], [ [ 'section' => 'Data collection', 'page' => 'Event correlation', 'displayed_ui' => [ 'Template groups', 'Host groups', 'Templates', 'Hosts', 'Maintenance', 'Discovery' ], 'link' => ['zabbix.php?action=correlation.list'] ] ], [ [ 'section' => 'Data collection', 'page' => 'Discovery', 'displayed_ui' => [ 'Template groups', 'Host groups', 'Templates', 'Hosts', 'Maintenance', 'Event correlation' ], 'link' => ['zabbix.php?action=discovery.list'] ] ], [ [ 'section' => 'Alerts', 'page' => 'Trigger actions', 'actions' => true, 'displayed_ui' => [ 'Service actions', 'Discovery actions', 'Autoregistration actions', 'Internal actions', 'Media types', 'Scripts' ], 'link' => ['zabbix.php?action=action.list&eventsource=0'] ] ], [ [ 'section' => 'Alerts', 'page' => 'Service actions', 'actions' => true, 'displayed_ui' => [ 'Trigger actions', 'Discovery actions', 'Autoregistration actions', 'Internal actions', 'Media types', 'Scripts' ], 'link' => ['zabbix.php?action=action.list&eventsource=4'] ] ], [ [ 'section' => 'Alerts', 'page' => 'Discovery actions', 'actions' => true, 'displayed_ui' => [ 'Trigger actions', 'Service actions', 'Autoregistration actions', 'Internal actions', 'Media types', 'Scripts' ], 'link' => ['zabbix.php?action=action.list&eventsource=1'] ] ], [ [ 'section' => 'Alerts', 'page' => 'Autoregistration actions', 'actions' => true, 'displayed_ui' => [ 'Trigger actions', 'Service actions', 'Discovery actions', 'Internal actions', 'Media types', 'Scripts' ], 'link' => ['zabbix.php?action=action.list&eventsource=2'] ] ], [ [ 'section' => 'Alerts', 'page' => 'Internal actions', 'actions' => true, 'displayed_ui' => [ 'Trigger actions', 'Service actions', 'Discovery actions', 'Autoregistration actions', 'Media types', 'Scripts' ], 'link' => ['zabbix.php?action=action.list&eventsource=3'] ] ], [ [ 'section' => 'Alerts', 'page' => 'Actions', 'displayed_ui' => [ 'Media types', 'Scripts' ], 'link' => [ 'zabbix.php?action=action.list&eventsource=0', 'zabbix.php?action=action.list&eventsource=1', 'zabbix.php?action=action.list&eventsource=2', 'zabbix.php?action=action.list&eventsource=3', 'zabbix.php?action=action.list&eventsource=4' ] ] ], [ [ 'section' => 'Alerts', 'page' => 'Media types', 'displayed_ui' => [ 'Trigger actions', 'Service actions', 'Discovery actions', 'Autoregistration actions', 'Internal actions', 'Scripts' ], 'link' => ['zabbix.php?action=mediatype.list'] ] ], [ [ 'section' => 'Alerts', 'page' => 'Scripts', 'displayed_ui' => [ 'Trigger actions', 'Service actions', 'Discovery actions', 'Autoregistration actions', 'Internal actions', 'Media types' ], 'link' => ['zabbix.php?action=script.list'] ] ], [ [ 'section' => 'Users', 'page' => 'User groups', 'displayed_ui' => [ 'User roles', 'Users', 'API tokens', 'Authentication' ], 'link' => ['zabbix.php?action=usergroup.list'] ] ], [ [ 'section' => 'Users', 'user_roles' => true, 'page' => 'User roles', 'displayed_ui' => [ 'User groups', 'Users', 'API tokens', 'Authentication' ], 'link' => ['zabbix.php?action=userrole.list'] ] ], [ [ 'section' => 'Users', 'page' => 'Users', 'displayed_ui' => [ 'User groups', 'User roles', 'API tokens', 'Authentication' ], 'link' => ['zabbix.php?action=user.list'] ] ], [ [ 'section' => 'Users', 'page' => 'API tokens', 'displayed_ui' => [ 'User groups', 'User roles', 'Users', 'Authentication' ], 'link' => ['zabbix.php?action=token.list'] ] ], [ [ 'section' => 'Users', 'page' => 'Authentication', 'displayed_ui' => [ 'User groups', 'User roles', 'Users', 'API tokens' ], 'link' => ['zabbix.php?action=authentication.edit'] ] ], [ [ 'section' => 'Administration', 'page' => 'General', 'displayed_ui' => [ 'Audit log', 'Housekeeping', 'Proxies', 'Macros', 'Queue' ], 'link' => [ 'zabbix.php?action=gui.edit', 'zabbix.php?action=autoreg.edit', 'zabbix.php?action=image.list', 'zabbix.php?action=iconmap.list', 'zabbix.php?action=regex.list', 'zabbix.php?action=trigdisplay.edit', 'zabbix.php?action=geomaps.edit', 'zabbix.php?action=module.list', 'zabbix.php?action=miscconfig.edit' ] ] ], [ [ 'section' => 'Administration', 'page' => 'Audit log', 'displayed_ui' => [ 'General', 'Proxies', 'Housekeeping', 'Macros', 'Queue' ], 'link' => ['zabbix.php?action=audit.settings.edit'] ] ], [ [ 'section' => 'Administration', 'page' => 'Housekeeping', 'displayed_ui' => [ 'General', 'Audit log', 'Proxies', 'Macros', 'Queue' ], 'link' => ['zabbix.php?action=housekeeping.edit'] ] ], [ [ 'section' => 'Administration', 'page' => 'Proxies', 'displayed_ui' => [ 'General', 'Audit log', 'Housekeeping', 'Macros', 'Queue' ], 'link' => ['zabbix.php?action=proxy.list'] ] ], [ [ 'section' => 'Administration', 'page' => 'Macros', 'displayed_ui' => [ 'General', 'Audit log', 'Housekeeping', 'Proxies', 'Queue' ], 'link' => ['zabbix.php?action=macros.edit'] ] ], [ [ 'section' => 'Administration', 'page' => 'Queue', 'displayed_ui' => [ 'General', 'Audit log', 'Housekeeping', 'Proxies', 'Macros' ], 'link' => [ 'zabbix.php?action=queue.overview', 'zabbix.php?action=queue.overview.proxy', 'zabbix.php?action=queue.details' ] ] ], [ [ 'section' => 'Monitoring', 'page' => 'Problems', 'displayed_ui' => [ 'Hosts', 'Latest data', 'Maps', 'Discovery' ], 'link' => ['zabbix.php?action=problem.view'] ] ], [ [ 'section' => 'Monitoring', 'page' => 'Hosts', 'displayed_ui' => [ 'Problems', 'Latest data', 'Maps', 'Discovery' ], 'link' => ['zabbix.php?action=host.view'] ] ], [ [ 'section' => 'Monitoring', 'page' => 'Latest data', 'displayed_ui' => [ 'Problems', 'Hosts', 'Maps', 'Discovery' ], 'link' => ['zabbix.php?action=latest.view'] ] ], [ [ 'section' => 'Monitoring', 'page' => 'Maps', 'displayed_ui' => [ 'Problems', 'Hosts', 'Latest data', 'Discovery' ], 'link' => ['sysmaps.php'] ] ], [ [ 'section' => 'Monitoring', 'page' => 'Discovery', 'displayed_ui' => [ 'Problems', 'Hosts', 'Latest data', 'Maps' ], 'link' => ['zabbix.php?action=discovery.view'] ] ], [ [ 'section' => 'Services', 'page' => 'Services', 'displayed_ui' => [ 'SLA', 'SLA report' ], 'link' => ['zabbix.php?action=service.list'] ] ], [ [ 'section' => 'Services', 'page' => 'SLA', 'displayed_ui' => [ 'Services', 'SLA report' ], 'link' => ['zabbix.php?action=sla.list'] ] ], [ [ 'section' => 'Services', 'page' => 'SLA report', 'displayed_ui' => [ 'Services', 'SLA' ], 'link' => ['zabbix.php?action=slareport.list'] ] ] ]; } /** * UI permission * * @dataProvider getUIData */ public function testUserRolesPermissions_UI($data) { $user_roles = [ 'Users' => [ 'User groups', 'User roles', 'Users', 'API tokens', 'Authentication' ] ]; $this->page->userLogin('user_for_role', 'zabbixzabbix'); foreach ([true, false] as $action_status) { $menu = CMainMenuElement::find()->one(); if ($data['section'] !== 'Dashboards') { $menu->select($data['section']); } if ($data['page'] === $data['section']) { $submenu = $menu->query("xpath:.//a[text()=".CXPathHelper::escapeQuotes($data['section']). "]/../ul[@class='submenu']")->one(); $this->assertEquals($action_status, $submenu->query('link', $data['page'])->one(false)->isValid()); } else { if (array_key_exists('actions', $data)) { $menu->query('xpath:.//ul/li/a[text()="Actions"]')->waitUntilClickable()->one()->click(); } $this->assertEquals($action_status, $menu->exists($data['page'])); } if ($action_status) { if (array_key_exists('user_roles', $data)) { $this->signOut(); $this->page->userLogin('Admin', 'zabbix'); $this->changeRoleRule([$data['section'] => $data['displayed_ui']]); $this->signOut(); $this->page->userLogin('user_for_role', 'zabbixzabbix'); } else { $this->changeRoleRule([$data['section'] => $data['displayed_ui']]); $this->page->open('zabbix.php?action=dashboard.view')->waitUntilReady(); } if (array_key_exists('actions', $data)) { $this->changeRoleRule([$data['section'] => $data['displayed_ui']]); $this->page->open('zabbix.php?action=action.list'.(($data['page'] === 'Trigger actions') ? '&eventsource=1' : '&eventsource=0'))->waitUntilReady(); $popup_menu = $this->query('id:page-title-general')->asPopupButton()->one()->getMenu(); $this->assertNotContains($data['page'], $popup_menu->getItems()->asText()); $this->page->open('zabbix.php?action=dashboard.view')->waitUntilReady(); } } else { if (array_key_exists('user_roles', $data)) { $this->checkLinks($data['link']); $this->signOut(); $this->page->userLogin('Admin', 'zabbix'); $this->changeRoleRule($user_roles); $this->signOut(); } else { $this->checkLinks($data['link']); $this->signOut(); } } } } /** * Manage API token action check. */ public function testUserRolesPermissions_ManageApiToken() { $this->page->userLogin('user_for_role', 'zabbixzabbix'); $this->page->open('zabbix.php?action=user.token.list')->waitUntilReady(); $this->assertEquals('TEST_SERVER_NAME: API tokens', $this->page->getTitle()); $this->changeRoleRule(['Manage API tokens' => false]); $this->checkLinks(['zabbix.php?action=user.token.list']); } /** * Disabling access to Dashboard. Check warning message text and button. */ public function testUserRolesPermissions_Dashboard() { $this->page->userLogin('user_for_role', 'zabbixzabbix'); $this->page->open('zabbix.php?action=dashboard.view')->waitUntilReady(); $this->changeRoleRule(['Dashboards' => false]); $this->checkLinks(['zabbix.php?action=dashboard.view'], 'Problems'); } public static function getRoleServiceData() { return [ [ [ 'role_config' => [ 'Read-write access to services' => 'None', 'Read-only access to services' => 'None' ], 'services' => null ] ], [ [ 'role_config' => [ 'Read-write access to services' => 'All', 'Read-only access to services' => 'None' ], 'services' => [ 'Child of child 1' => 'write', 'Child of parent 1' => 'write', 'Child of parent 2' => 'write', 'Parent 1' => 'write', 'Parent 2' => 'write' ] ] ], [ [ 'role_config' => [ 'Read-write access to services' => 'None', 'Read-only access to services' => 'All' ], 'services' => [ 'Child of child 1' => 'read', 'Child of parent 1' => 'read', 'Child of parent 2' => 'read', 'Parent 1' => 'read', 'Parent 2' => 'read' ] ] ], [ [ 'role_config' => [ 'Read-write access to services' => 'All', 'Read-only access to services' => 'All' ], 'services' => [ 'Child of child 1' => 'write', 'Child of parent 1' => 'write', 'Child of parent 2' => 'write', 'Parent 1' => 'write', 'Parent 2' => 'write' ] ] ], [ [ 'role_config' => [ 'Read-write access to services' => 'Service list', 'Read-only access to services' => 'None' ], 'service_list' => [ 'Read-write access to services with tag' => [ 'service-write-tag-tag' => 'test', 'service_write_tag_value' => 'test123' ] ], 'services' => [ 'Child of child 1' => 'write', 'Child of parent 1' => 'write' ] ] ], [ [ 'role_config' => [ 'Read-write access to services' => 'None', 'Read-only access to services' => 'Service list' ], 'service_list' => [ 'Read-only access to services with tag' => [ 'service-read-tag-tag' => 'test', 'service_read_tag_value' => 'test123' ] ], 'services' => [ 'Child of child 1' => 'read', 'Child of parent 1' => 'read' ] ] ], [ [ 'role_config' => [ 'Read-write access to services' => 'Service list', 'Read-only access to services' => 'None' ], 'service_list' => [ 'xpath:(//div[@class="multiselect-control"])[1]' => 'Child of parent 1' ], 'services' => [ 'Child of child 1' => 'write', 'Child of parent 1' => 'write' ] ] ], [ [ 'role_config' => [ 'Read-write access to services' => 'None', 'Read-only access to services' => 'Service list', // added element 'API methods' with default value for page scroll 'API methods' => 'Deny list' ], 'service_list' => [ 'xpath:(//div[@class="multiselect-control"])[2]' => 'Child of parent 1' ], 'services' => [ 'Child of child 1' => 'read', 'Child of parent 1' => 'read' ] ] ], [ [ 'role_config' => [ 'Read-write access to services' => 'Service list', 'Read-only access to services' => 'All' ], 'service_list' => [ 'xpath:(//div[@class="multiselect-control"])[1]' => 'Child of parent 1' ], 'services' => [ 'Child of child 1' => 'write', 'Child of parent 1' => 'write', 'Child of parent 2' => 'read', 'Parent 1' => 'read', 'Parent 2' => 'read' ] ] ] ]; } /** * Check permissions to services based on user role configuration. * * @dataProvider getRoleServiceData */ public function testUserRolesPermissions_ServicePermissions($data) { // Prepare a combination of service name and the number of child services for service for further comparison. if ($data['services'] !== null) { $child_services = [ 'Child of parent 1' => 1, 'Parent 1' => 1, 'Parent 2' => 1 ]; $column_content = []; foreach (array_keys($data['services']) as $service) { $column_content[] = array_key_exists($service, $child_services) ? $service.' '.$child_services[$service] : $service; } } // Configure the role according to the data provider. $this->page->login()->open('zabbix.php?action=userrole.edit&roleid='.self::$super_roleid)->waitUntilReady(); $form = $this->query('id:userrole-form')->waitUntilPresent()->asForm()->one(); $form->fill($data['role_config']); if (array_key_exists('service_list', $data)) { $form->fill($data['service_list']); } $form->submit(); $this->assertMessage(TEST_GOOD, 'User role updated'); $this->page->logout(); // Login as user that belongs to the updated row and check access to services based on applied configuration. $this->page->userLogin('user_for_role', 'zabbixzabbix'); $this->page->open('zabbix.php?action=service.list')->waitUntilReady(); $this->assertEquals('user_for_role', $this->query('xpath://a[text()="User settings"]')->one()->getAttribute('title')); $services_mode = $this->query('id:list_mode')->asSegmentedRadio()->one(false); // Check that table service list content and edit mode in not available if the user doest have permissions. if ($data['services'] === null) { $this->assertTableData(); $this->assertFalse($services_mode->isValid()); return; } elseif ($data['role_config']['Read-write access to services'] !== 'None') { // Open edit mode if user has write permissions to at least one service. $services_mode->select('Edit'); $this->page->waituntilReady(); } // Filter out unnecessary services. $this->query('id:filter_tags_0_tag')->waitUntilVisible()->one()->fill('action'); $this->query('id:filter_tags_0_operator')->asDropdown()->waitUntilVisible()->one()->fill('Does not exist'); // Apply filter in order to see the list of available services. $this->query('name:filter_set')->waitUntilClickable()->one()->click(); $this->page->waituntilReady(); $this->assertTableDataColumn($column_content, 'Name'); $table = $this->query('class:list-table')->asTable()->one(); // Check buttons are not visible for user with no permissions, otherwise, check edit permissions per service. if ($data['role_config']['Read-write access to services'] === 'None') { foreach ($table->getRows() as $row) { $this->assertEquals(0, $row->query('xpath:.//button')->all(false)->count()); } } else { foreach ($data['services'] as $service => $permissions) { $property = ($permissions === 'write') ? CElementFilter::CLICKABLE : CElementFilter::NOT_CLICKABLE; $row = $table->findRow('Name', $service, true); // Check that all three action buttons in the row are clickable. $this->assertEquals(3, $row->query("xpath:.//button")->all() ->filter(new CElementFilter($property))->count() ); } } } public static function getExecuteNowButtonData() { return [ [ [ 'user' => 'U1-r-on', 'test_cases' => [ // Simple items. [ 'items' => ['I4-trap-log'] ], [ 'expected' => TEST_GOOD, 'items' => ['I5-agent-txt', 'I4-trap-log'], 'message' => 'Request sent successfully. Some items are filtered due to access permissions or type.' ], // Dependent items. [ 'expected' => TEST_GOOD, 'items' => ['I1-lvl2-dep-log'], 'message' => 'Request sent successfully' ], [ 'expected' => TEST_BAD, 'items' => ['I2-lvl2-dep-log'], 'message' => 'Cannot send request: wrong master item type.' ] ] ] ], [ [ 'user' => 'U2-r-off', 'test_cases' => [ // Simple items. [ 'items' => ['I4-trap-log'] ], [ 'items' => ['I5-agent-txt', 'I4-trap-log'] ], // Dependent items. [ 'items' => ['I1-lvl2-dep-log'] ], [ 'items' => ['I2-lvl2-dep-log'] ] ] ] ], [ [ 'user' => 'U3-rw-off', 'test_cases' => [ // Simple items. [ 'items' => ['I4-trap-log'] ], // Dependent items. [ 'expected' => TEST_GOOD, 'items' => ['I1-lvl2-dep-log', 'I4-trap-log'], 'message' => 'Request sent successfully. Some items are filtered due to access permissions or type.' ], [ 'expected' => TEST_BAD, 'items' => ['I2-lvl2-dep-log'], 'message' => 'Cannot send request: wrong master item type.' ] ] ] ] ]; } /** * Check permissions to "Execute now" button on Latest data page based on user role. * * @dataProvider getExecuteNowButtonData */ public function testUserRolesPermissions_ExecuteNowButton($data) { // Login and select host group for testing. $this->page->userLogin($data['user'], 'zabbixzabbix'); $this->page->open('zabbix.php?action=latest.view')->waitUntilReady(); $table = $this->query('xpath://table['.CXPathHelper::fromClass('overflow-ellipsis').']')->asTable()->one(); $filter_form = $this->query('name:zbx_filter')->asForm()->one(); $filter_form->fill(['Host groups' => 'HG-for-executenow']); $filter_form->submit(); $table->waitUntilReloaded(); $selected_count = $this->query('id:selected_count')->one(); $select_all = $this->query('id:all_items')->asCheckbox()->one(); foreach ($data['test_cases'] as $test_case) { $table->findRows('Name', $test_case['items'])->select(); $this->assertEquals(count($test_case['items']).' selected', $selected_count->getText()); // Disabled "Execute now" button. if (!array_key_exists('expected', $test_case)) { $this->assertTrue($this->query('button:Execute now')->one()->isEnabled(false)); // Reset selected items. $select_all->check(); $select_all->uncheck(); $this->assertEquals('0 selected', $selected_count->getText()); continue; } $this->query('button:Execute now')->one()->click(); switch (CTestArrayHelper::get($test_case, 'expected')) { case TEST_GOOD: $this->assertMessage(TEST_GOOD, $test_case['message']); // After a successful "Execute now" action, the item selection is reset. $this->assertEquals('0 selected', $selected_count->getText()); break; case TEST_BAD: $this->assertMessage(TEST_BAD, 'Cannot execute operation', $test_case['message']); // Reset selected items after a failed "Execute now" action. $this->assertEquals(count($test_case['items']).' selected', $selected_count->getText()); $select_all->check(); $select_all->uncheck(); $this->assertEquals('0 selected', $selected_count->getText()); break; } CMessageElement::find()->waitUntilVisible()->one()->close(); } } public static function getExecuteNowContextMenuData() { return [ [ [ 'user' => 'U1-r-on', 'test_cases' => [ [ 'items' => ['I4-trap-log', 'I2-lvl1-trap-num'] ], [ 'expected' => TEST_GOOD, 'items' => 'I1-lvl2-dep-log' ], [ 'expected' => TEST_BAD, 'items' => 'I2-lvl2-dep-log', 'message' => 'Cannot send request: wrong master item type.' ] ] ] ], [ [ 'user' => 'U2-r-off', 'test_cases' => [ [ 'items' => ['I4-trap-log', 'I5-agent-txt', 'I1-lvl2-dep-log', 'I2-lvl2-dep-log'] ] ] ] ], [ [ 'user' => 'U3-rw-off', 'test_cases' => [ [ 'items' => ['I4-trap-log', 'I2-lvl1-trap-num'] ], [ 'expected' => TEST_GOOD, 'items' => 'I1-lvl2-dep-log' ], [ 'expected' => TEST_BAD, 'items' => 'I2-lvl2-dep-log', 'message' => 'Cannot send request: wrong master item type.' ] ] ] ] ]; } /** * Check permissions to "Execute now" link in context menu on Latest data page based on user role. * * @dataProvider getExecuteNowContextMenuData */ public function testUserRolesPermissions_ExecuteNowContextMenu($data) { // Login and select host group for testing. $this->page->userLogin($data['user'], 'zabbixzabbix'); $this->page->open('zabbix.php?action=latest.view')->waitUntilReady(); $filter_form = $this->query('name:zbx_filter')->asForm()->one(); $filter_form->fill(['Host groups' => 'HG-for-executenow']); $filter_form->submit(); $this->page->waitUntilReady(); foreach ($data['test_cases'] as $test_case) { // Disabled "Execute now" option in context menu. if (!array_key_exists('expected', $test_case)) { foreach ($test_case['items'] as $item) { $this->query('link', $item)->one()->click(); $popup = CPopupMenuElement::find()->waitUntilVisible()->one(); $this->assertFalse($popup->getItem('Execute now')->isEnabled()); $this->page->pressKey(WebDriverKeys::ESCAPE); } continue; } $this->query('link', $test_case['items'])->one()->click(); $popup = CPopupMenuElement::find()->waitUntilVisible()->one(); $popup->fill('Execute now'); if ($test_case['expected'] === TEST_GOOD) { $this->assertMessage(TEST_GOOD, 'Request sent successfully'); } else { $this->assertMessage(TEST_BAD, 'Cannot execute operation', $test_case['message']); } CMessageElement::find()->waitUntilVisible()->one()->close(); } } /** * Check disabled actions with links. * * @param array $links checked links after disabling action * @param string $page page name displayed on error message button */ private function checkLinks($links, $page = 'Dashboards') { foreach ($links as $link) { $this->page->open($link)->waitUntilReady(); $this->assertMessage(TEST_BAD, 'Access denied', 'You are logged in as "user_for_role". '. 'You have no permissions to access this page.'); $this->query('button:Go to "'.$page.'"')->one()->waitUntilClickable()->click(); if ($page === 'Dashboards') { $this->assertStringContainsString('zabbix.php?action=dashboard', $this->page->getCurrentUrl()); } } } /** * Enable/disable actions and UI. * * @param array $action action with true/false status or UI section with page */ private function changeRoleRule($action) { $this->page->open('zabbix.php?action=userrole.edit&roleid='.self::$super_roleid)->waitUntilReady(); $this->query('id:userrole-form')->waitUntilPresent()->asForm()->one()->fill($action)->submit(); $this->page->waitUntilReady(); $this->assertMessage(TEST_GOOD, 'User role updated'); } /** * Click Sign out button. */ private function signOut() { $this->query('xpath://a[@class="zi-signout"]')->waitUntilPresent()->one()->click(); $this->page->waitUntilReady(); $this->query('button:Sign in')->waitUntilVisible(); } }