Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/zabbix/zabbix.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtjoms Rimdjonoks <artjoms.rimdjonoks@zabbix.com>2021-02-08 21:52:36 +0300
committerArtjoms Rimdjonoks <artjoms.rimdjonoks@zabbix.com>2021-02-08 21:52:36 +0300
commit60c77a15aeef3fc9e32aa9f18f96b5563b38e438 (patch)
tree3fceed36fd25e19115937a5b01be8387eff3a777 /ui/app/controllers
parent897094a0045e4aff12e383f92b9a30b8a11cce2c (diff)
parent041720766868904c0bdace33ca4d77e536a6cb21 (diff)
.......... [ZBXNEXT-6309] updated to the latest master branch (simple conflicts solved)
Diffstat (limited to 'ui/app/controllers')
-rw-r--r--ui/app/controllers/CControllerAuditLogList.php3
-rw-r--r--ui/app/controllers/CControllerAuthenticationUpdate.php2
-rw-r--r--ui/app/controllers/CControllerCorrelationList.php2
-rw-r--r--ui/app/controllers/CControllerHost.php9
-rw-r--r--ui/app/controllers/CControllerMenuPopup.php27
-rw-r--r--ui/app/controllers/CControllerPopupGeneric.php5
-rw-r--r--ui/app/controllers/CControllerPopupItemTest.php97
-rw-r--r--ui/app/controllers/CControllerPopupItemTestEdit.php12
-rw-r--r--ui/app/controllers/CControllerPopupMassupdateItem.php2
-rw-r--r--ui/app/controllers/CControllerPopupMassupdateItemPrototype.php4
-rw-r--r--ui/app/controllers/CControllerPopupScriptExec.php73
-rw-r--r--ui/app/controllers/CControllerProfileUpdate.php2
-rw-r--r--ui/app/controllers/CControllerScriptCreate.php45
-rw-r--r--ui/app/controllers/CControllerScriptEdit.php86
-rw-r--r--ui/app/controllers/CControllerScriptList.php4
-rw-r--r--ui/app/controllers/CControllerScriptUpdate.php54
-rw-r--r--ui/app/controllers/CControllerTokenCreate.php110
-rw-r--r--ui/app/controllers/CControllerTokenDelete.php69
-rw-r--r--ui/app/controllers/CControllerTokenDisable.php71
-rw-r--r--ui/app/controllers/CControllerTokenEdit.php110
-rw-r--r--ui/app/controllers/CControllerTokenEnable.php71
-rw-r--r--ui/app/controllers/CControllerTokenList.php196
-rw-r--r--ui/app/controllers/CControllerTokenUpdate.php127
-rw-r--r--ui/app/controllers/CControllerTokenView.php59
-rw-r--r--ui/app/controllers/CControllerUserTokenEdit.php94
-rw-r--r--ui/app/controllers/CControllerUserTokenList.php140
-rw-r--r--ui/app/controllers/CControllerUserTokenView.php56
-rw-r--r--ui/app/controllers/CControllerUserroleCreate.php1
-rw-r--r--ui/app/controllers/CControllerUserroleEdit.php1
-rw-r--r--ui/app/controllers/CControllerUserroleUpdate.php1
-rw-r--r--ui/app/controllers/CControllerWidgetHostAvailView.php35
31 files changed, 1406 insertions, 162 deletions
diff --git a/ui/app/controllers/CControllerAuditLogList.php b/ui/app/controllers/CControllerAuditLogList.php
index 2f76a71c088..9b896b26314 100644
--- a/ui/app/controllers/CControllerAuditLogList.php
+++ b/ui/app/controllers/CControllerAuditLogList.php
@@ -219,7 +219,8 @@ class CControllerAuditLogList extends CController {
AUDIT_RESOURCE_SETTINGS => _('Settings'),
AUDIT_RESOURCE_HOUSEKEEPING => _('Housekeeping'),
AUDIT_RESOURCE_AUTHENTICATION => _('Authentication'),
- AUDIT_RESOURCE_TEMPLATE_DASHBOARD => _('Template dashboard')
+ AUDIT_RESOURCE_TEMPLATE_DASHBOARD => _('Template dashboard'),
+ AUDIT_RESOURCE_AUTH_TOKEN => _('API token')
];
}
diff --git a/ui/app/controllers/CControllerAuthenticationUpdate.php b/ui/app/controllers/CControllerAuthenticationUpdate.php
index c84f5b2ac62..5bd561b6923 100644
--- a/ui/app/controllers/CControllerAuthenticationUpdate.php
+++ b/ui/app/controllers/CControllerAuthenticationUpdate.php
@@ -31,8 +31,6 @@ class CControllerAuthenticationUpdate extends CController {
->setArgument('action', 'authentication.edit')
->getUrl()
);
-
- $this->disableSIDValidation();
}
protected function checkInput() {
diff --git a/ui/app/controllers/CControllerCorrelationList.php b/ui/app/controllers/CControllerCorrelationList.php
index 145e3403a53..41f531113ba 100644
--- a/ui/app/controllers/CControllerCorrelationList.php
+++ b/ui/app/controllers/CControllerCorrelationList.php
@@ -88,7 +88,7 @@ class CControllerCorrelationList extends CController {
'selectFilter' => ['formula', 'conditions', 'evaltype', 'eval_formula'],
'selectOperations' => ['type'],
'search' => [
- 'name' => ($filter['name'] === '') ? null : $filter['name'],
+ 'name' => ($filter['name'] === '') ? null : $filter['name']
],
'filter' => [
'status' => ($filter['status'] == -1) ? null : $filter['status']
diff --git a/ui/app/controllers/CControllerHost.php b/ui/app/controllers/CControllerHost.php
index c19a2c12946..cd25d7a5f71 100644
--- a/ui/app/controllers/CControllerHost.php
+++ b/ui/app/controllers/CControllerHost.php
@@ -154,11 +154,8 @@ abstract class CControllerHost extends CController {
// Get additional data to limited host amount.
$hosts = API::Host()->get([
- 'output' => ['hostid', 'name', 'status', 'maintenance_status', 'maintenanceid', 'maintenance_type',
- 'available', 'snmp_available', 'jmx_available', 'ipmi_available', 'error', 'ipmi_error', 'snmp_error',
- 'jmx_error'
- ],
- 'selectInterfaces' => ['ip', 'dns', 'port', 'main', 'type', 'useip'],
+ 'output' => ['hostid', 'name', 'status', 'maintenance_status', 'maintenanceid', 'maintenance_type'],
+ 'selectInterfaces' => ['ip', 'dns', 'port', 'main', 'type', 'useip', 'available', 'error', 'details'],
'selectGraphs' => API_OUTPUT_COUNT,
'selectHttpTests' => API_OUTPUT_COUNT,
'selectTags' => ['tag', 'value'],
@@ -280,7 +277,7 @@ abstract class CControllerHost extends CController {
$data = [];
if ($filter['groupids']) {
- $groups= API::HostGroup()->get([
+ $groups = API::HostGroup()->get([
'output' => ['groupid', 'name'],
'groupids' => $filter['groupids']
]);
diff --git a/ui/app/controllers/CControllerMenuPopup.php b/ui/app/controllers/CControllerMenuPopup.php
index c73ad01a224..2dd1620b7ec 100644
--- a/ui/app/controllers/CControllerMenuPopup.php
+++ b/ui/app/controllers/CControllerMenuPopup.php
@@ -565,6 +565,7 @@ class CControllerMenuPopup extends CController {
$can_be_closed = ($db_trigger['manual_close'] == ZBX_TRIGGER_MANUAL_CLOSE_ALLOWED
&& CWebUser::checkAccess(CRoleHelper::ACTIONS_CLOSE_PROBLEMS)
);
+ $event = [];
if (array_key_exists('eventid', $data)) {
$menu_data['eventid'] = $data['eventid'];
@@ -622,6 +623,32 @@ class CControllerMenuPopup extends CController {
);
}
+ $scripts_by_hosts = CWebUser::checkAccess(CRoleHelper::ACTIONS_EXECUTE_SCRIPTS)
+ ? $event ? API::Script()->getScriptsByHosts(array_keys($hosts)) : []
+ : [];
+
+ $scripts = [];
+ foreach ($scripts_by_hosts as &$host_scripts) {
+ foreach ($host_scripts as &$host_script) {
+ if (!array_key_exists($host_script['scriptid'], $scripts)) {
+ $host_script['name'] = trimPath($host_script['name']);
+ $scripts[$host_script['scriptid']] = $host_script;
+ }
+ }
+ unset($host_script);
+ }
+ unset($host_scripts);
+
+ CArrayHelper::sort($scripts, ['name']);
+
+ foreach (array_values($scripts) as $script) {
+ $menu_data['scripts'][] = [
+ 'name' => $script['name'],
+ 'scriptid' => $script['scriptid'],
+ 'confirmation' => $script['confirmation']
+ ];
+ }
+
return $menu_data;
}
diff --git a/ui/app/controllers/CControllerPopupGeneric.php b/ui/app/controllers/CControllerPopupGeneric.php
index 04c405d1b7c..aad1e3c880e 100644
--- a/ui/app/controllers/CControllerPopupGeneric.php
+++ b/ui/app/controllers/CControllerPopupGeneric.php
@@ -377,8 +377,7 @@ class CControllerPopupGeneric extends CController {
],
'table_columns' => [
_('Name'),
- _('Execute on'),
- _('Commands')
+ _('Execute on')
]
],
'roles' => [
@@ -1298,7 +1297,7 @@ class CControllerPopupGeneric extends CController {
case 'scripts':
$options += [
- 'output' => ['scriptid', 'name', 'type', 'execute_on', 'command'],
+ 'output' => ['scriptid', 'name', 'type', 'execute_on'],
'groupids' => (!$this->hostids && $this->groupids) ? $this->groupids : null
];
diff --git a/ui/app/controllers/CControllerPopupItemTest.php b/ui/app/controllers/CControllerPopupItemTest.php
index a209937f9c6..29b59609690 100644
--- a/ui/app/controllers/CControllerPopupItemTest.php
+++ b/ui/app/controllers/CControllerPopupItemTest.php
@@ -137,55 +137,56 @@ abstract class CControllerPopupItemTest extends CController {
'url' => [
'host' => ['{HOSTNAME}', '{HOST.HOST}', '{HOST.NAME}'],
'interface' => ['{HOST.IP}', '{IPADDRESS}', '{HOST.DNS}', '{HOST.CONN}', '{HOST.PORT}'],
- 'item' => ['{ITEM.ID}', '{ITEM.KEY}'],
+ 'item' => ['{ITEM.ID}', '{ITEM.KEY.ORIG}', '{ITEM.KEY}'],
'support_user_macros' => true,
'support_lld_macros' => true
],
'posts' => [
'host' => ['{HOSTNAME}', '{HOST.HOST}', '{HOST.NAME}'],
'interface' => ['{HOST.IP}', '{IPADDRESS}', '{HOST.DNS}', '{HOST.CONN}', '{HOST.PORT}'],
- 'item' => ['{ITEM.ID}', '{ITEM.KEY}'],
+ 'item' => ['{ITEM.ID}', '{ITEM.KEY.ORIG}', '{ITEM.KEY}'],
'support_user_macros' => true,
'support_lld_macros' => true
],
'http_proxy' => [
'host' => ['{HOSTNAME}', '{HOST.HOST}', '{HOST.NAME}'],
'interface' => ['{HOST.IP}', '{IPADDRESS}', '{HOST.DNS}', '{HOST.CONN}', '{HOST.PORT}'],
- 'item' => ['{ITEM.ID}', '{ITEM.KEY}'],
+ 'item' => ['{ITEM.ID}', '{ITEM.KEY.ORIG}', '{ITEM.KEY}'],
'support_user_macros' => true,
'support_lld_macros' => true
],
'ssl_cert_file' => [
'host' => ['{HOSTNAME}', '{HOST.HOST}', '{HOST.NAME}'],
'interface' => ['{HOST.IP}', '{IPADDRESS}', '{HOST.DNS}', '{HOST.CONN}', '{HOST.PORT}'],
- 'item' => ['{ITEM.ID}', '{ITEM.KEY}'],
+ 'item' => ['{ITEM.ID}', '{ITEM.KEY.ORIG}', '{ITEM.KEY}'],
'support_user_macros' => true,
'support_lld_macros' => true
],
'ssl_key_file' => [
'host' => ['{HOSTNAME}', '{HOST.HOST}', '{HOST.NAME}'],
'interface' => ['{HOST.IP}', '{IPADDRESS}', '{HOST.DNS}', '{HOST.CONN}', '{HOST.PORT}'],
- 'item' => ['{ITEM.ID}', '{ITEM.KEY}'],
+ 'item' => ['{ITEM.ID}', '{ITEM.KEY.ORIG}', '{ITEM.KEY}'],
'support_user_macros' => true,
'support_lld_macros' => true
],
'query_fields' => [
'host' => ['{HOSTNAME}', '{HOST.HOST}', '{HOST.NAME}'],
'interface' => ['{HOST.IP}', '{IPADDRESS}', '{HOST.DNS}', '{HOST.CONN}', '{HOST.PORT}'],
- 'item' => ['{ITEM.ID}', '{ITEM.KEY}'],
+ 'item' => ['{ITEM.ID}', '{ITEM.KEY.ORIG}', '{ITEM.KEY}'],
'support_user_macros' => true,
'support_lld_macros' => true
],
'headers' => [
'host' => ['{HOSTNAME}', '{HOST.HOST}', '{HOST.NAME}'],
'interface' => ['{HOST.IP}', '{IPADDRESS}', '{HOST.DNS}', '{HOST.CONN}', '{HOST.PORT}'],
- 'item' => ['{ITEM.ID}', '{ITEM.KEY}'],
+ 'item' => ['{ITEM.ID}', '{ITEM.KEY.ORIG}', '{ITEM.KEY}'],
'support_user_macros' => true,
'support_lld_macros' => true
],
'parameters' => [
'host' => ['{HOSTNAME}', '{HOST.HOST}', '{HOST.NAME}'],
'interface' => ['{HOST.IP}', '{IPADDRESS}', '{HOST.DNS}', '{HOST.CONN}'],
+ 'item' => ['{ITEM.ID}', '{ITEM.KEY.ORIG}', '{ITEM.KEY}'],
'support_user_macros' => true,
'support_lld_macros' => true
],
@@ -304,9 +305,8 @@ abstract class CControllerPopupItemTest extends CController {
if ($ret && $hostid != 0) {
$hosts = API::Host()->get([
- 'output' => ['hostid', 'host', 'name', 'status', 'available', 'proxy_hostid', 'tls_subject',
- 'ipmi_available', 'jmx_available', 'snmp_available', 'maintenance_status', 'maintenance_type',
- 'ipmi_authtype', 'ipmi_privilege', 'ipmi_username', 'ipmi_password',
+ 'output' => ['hostid', 'host', 'name', 'status', 'proxy_hostid', 'tls_subject', 'maintenance_status',
+ 'maintenance_type', 'ipmi_authtype', 'ipmi_privilege', 'ipmi_username', 'ipmi_password',
'tls_issuer', 'tls_connect'
],
'hostids' => [$hostid],
@@ -315,7 +315,7 @@ abstract class CControllerPopupItemTest extends CController {
if (!$hosts) {
$hosts = API::Template()->get([
- 'output' => ['templateid', 'host', 'name', 'status', 'available', 'jmx_available'],
+ 'output' => ['templateid', 'host', 'name', 'status'],
'templateids' => [$hostid],
'editable' => true
]);
@@ -427,7 +427,8 @@ abstract class CControllerPopupItemTest extends CController {
$interface_input['address'] = $input['address'];
}
- if (array_key_exists('data', $input) && array_key_exists('interface_details', $input['data'])) {
+ if (array_key_exists('data', $input) && array_key_exists('interface_details', $input['data'])
+ && is_array($input['data']['interface_details'])) {
$interface_input['details'] = $input['data']['interface_details'];
}
elseif (array_key_exists('interface', $input) && array_key_exists('details', $input['interface'])) {
@@ -530,17 +531,13 @@ abstract class CControllerPopupItemTest extends CController {
$data += [
'key' => $input['key'],
'host' => [
- 'hostid' => $this->host['hostid'],
- 'available' => $this->host['available'],
- 'jmx_available' => $this->host['jmx_available']
+ 'hostid' => $this->host['hostid']
]
];
if ($this->host['status'] != HOST_STATUS_TEMPLATE) {
$data['host'] += [
'maintenance_status' => $this->host['maintenance_status'],
- 'ipmi_available' => $this->host['ipmi_available'],
- 'snmp_available' => $this->host['snmp_available'],
'maintenance_type' => $this->host['maintenance_type']
];
}
@@ -739,12 +736,39 @@ abstract class CControllerPopupItemTest extends CController {
// Get values from database; resolve macros.
if (($this->host['status'] == HOST_STATUS_MONITORED || $this->host['status'] == HOST_STATUS_NOT_MONITORED)
&& array_key_exists('interfaceid', $inputs)) {
- $output_details = ($this->item_type == ITEM_TYPE_SNMP) ? ['details'] : [];
- $interfaces = API::HostInterface()->get([
- 'output' => array_merge(['hostid', 'type', 'dns', 'ip', 'port', 'main', 'useip'], $output_details),
- 'interfaceids' => $inputs['interfaceid'],
- 'hostids' => $this->host['hostid']
- ]);
+ $output = ['hostid', 'type', 'dns', 'ip', 'port', 'main', 'useip'];
+ $interfaces = [];
+
+ if ($this->item_type == ITEM_TYPE_SNMP) {
+ $output[] = 'details';
+ }
+
+ if (itemTypeInterface($this->item_type) === false) {
+ $host_interfaces = API::HostInterface()->get([
+ 'output' => $output,
+ 'hostids' => $this->host['hostid'],
+ 'filter' => ['main' => INTERFACE_PRIMARY]
+ ]);
+ $host_interfaces = zbx_toHash($host_interfaces, 'type');
+
+ $ordered_interface_types = [INTERFACE_TYPE_AGENT, INTERFACE_TYPE_SNMP, INTERFACE_TYPE_JMX,
+ INTERFACE_TYPE_IPMI
+ ];
+
+ foreach ($ordered_interface_types as $interface_type) {
+ if (array_key_exists($interface_type, $host_interfaces)) {
+ $interfaces[] = $host_interfaces[$interface_type];
+ break;
+ }
+ }
+ }
+ else {
+ $interfaces = API::HostInterface()->get([
+ 'output' => $output,
+ 'interfaceids' => $inputs['interfaceid'],
+ 'hostids' => $this->host['hostid']
+ ]);
+ }
if (count($interfaces) != 0) {
$interfaces = CMacrosResolverHelper::resolveHostInterfaces($interfaces);
@@ -766,6 +790,10 @@ abstract class CControllerPopupItemTest extends CController {
}
}
+ if ($this->item_type == ITEM_TYPE_SCRIPT) {
+ return $interface_data;
+ }
+
// Apply client side cache.
foreach ($inputs as $key => $value) {
if (is_array($value)) {
@@ -893,10 +921,31 @@ abstract class CControllerPopupItemTest extends CController {
'{ITEM.ID}' => (array_key_exists('itemid', $inputs) && $inputs['itemid'])
? $inputs['itemid']
: UNRESOLVED_MACRO_STRING,
- '{ITEM.KEY}' => array_key_exists('key', $inputs) ? $inputs['key'] : UNRESOLVED_MACRO_STRING
+ '{ITEM.KEY}' => array_key_exists('key', $inputs) ? $inputs['key'] : UNRESOLVED_MACRO_STRING,
+ '{ITEM.KEY.ORIG}' => array_key_exists('key', $inputs) ? $inputs['key'] : UNRESOLVED_MACRO_STRING
]
];
+ if (array_key_exists('key', $inputs) && strstr($inputs['key'], '{') !== false) {
+ $usermacros = CMacrosResolverHelper::extractItemTestMacros([
+ 'steps' => [],
+ 'delay' => '',
+ 'supported_macros' => array_diff_key($this->macros_by_item_props['key'],
+ ['support_user_macros' => true, 'support_lld_macros' => true]
+ ),
+ 'support_lldmacros' => ($this->preproc_item instanceof CItemPrototype),
+ 'texts_support_macros' => [$inputs['key']],
+ 'texts_support_lld_macros' => [$inputs['key']],
+ 'texts_support_user_macros' => [$inputs['key']],
+ 'hostid' => $this->host ? $this->host['hostid'] : 0,
+ 'macros_values' => array_intersect_key($macros, $this->macros_by_item_props['key'])
+ ]);
+
+ foreach ($usermacros['macros'] as $macro => $value) {
+ $macros['item']['{ITEM.KEY}'] = str_replace($macro, $value, $macros['item']['{ITEM.KEY}']);
+ }
+ }
+
return $macros;
}
diff --git a/ui/app/controllers/CControllerPopupItemTestEdit.php b/ui/app/controllers/CControllerPopupItemTestEdit.php
index 808c77fe8fb..abddd97d4ac 100644
--- a/ui/app/controllers/CControllerPopupItemTestEdit.php
+++ b/ui/app/controllers/CControllerPopupItemTestEdit.php
@@ -149,9 +149,9 @@ class CControllerPopupItemTestEdit extends CControllerPopupItemTest {
$inputs = $this->getItemTestProperties($this->getInputAll());
// Work with preprocessing steps.
- $preprocessing_steps_inpupt = $this->getInput('steps', []);
+ $preprocessing_steps_input = $this->getInput('steps', []);
$preprocessing_steps = [];
- foreach ($preprocessing_steps_inpupt as $preproc) {
+ foreach ($preprocessing_steps_input as $preproc) {
if ($preproc['type'] == ZBX_PREPROC_VALIDATE_NOT_SUPPORTED) {
array_unshift($preprocessing_steps, $preproc);
}
@@ -248,13 +248,13 @@ class CControllerPopupItemTestEdit extends CControllerPopupItemTest {
// Extract macros and apply effective values for each of them.
$usermacros = CMacrosResolverHelper::extractItemTestMacros([
'steps' => $preprocessing_steps,
- 'hostid' => $this->host ? $this->host['hostid'] : 0,
'delay' => $show_prev ? $this->getInput('delay', ZBX_ITEM_DELAY_DEFAULT) : '',
- 'texts_support_macros' => $texts_support_macros,
- 'texts_support_lld_macros' => $texts_support_lld_macros,
- 'texts_support_user_macros' => $texts_support_user_macros,
'supported_macros' => $supported_macros,
'support_lldmacros' => $support_lldmacros,
+ 'texts_support_macros' => $texts_support_macros,
+ 'texts_support_user_macros' => $texts_support_user_macros,
+ 'texts_support_lld_macros' => $texts_support_lld_macros,
+ 'hostid' => $this->host ? $this->host['hostid'] : 0,
'macros_values' => $this->getSupportedMacros($inputs + ['interfaceid' => $this->getInput('interfaceid', 0)])
]);
diff --git a/ui/app/controllers/CControllerPopupMassupdateItem.php b/ui/app/controllers/CControllerPopupMassupdateItem.php
index 67ff9890ec0..0701aedcb9c 100644
--- a/ui/app/controllers/CControllerPopupMassupdateItem.php
+++ b/ui/app/controllers/CControllerPopupMassupdateItem.php
@@ -450,7 +450,7 @@ class CControllerPopupMassupdateItem extends CController {
'multiple_interface_types' => false,
'initial_item_type' => null,
'preprocessing_test_type' => CControllerPopupItemTestEdit::ZBX_TEST_TYPE_ITEM,
- 'preprocessing_types' => CItem::$supported_preprocessing_types,
+ 'preprocessing_types' => CItem::SUPPORTED_PREPROCESSING_TYPES,
'displayApplications' => true,
'display_interfaces' => true,
'displayMasteritems' => true,
diff --git a/ui/app/controllers/CControllerPopupMassupdateItemPrototype.php b/ui/app/controllers/CControllerPopupMassupdateItemPrototype.php
index a31f9c20b85..8936497b41a 100644
--- a/ui/app/controllers/CControllerPopupMassupdateItemPrototype.php
+++ b/ui/app/controllers/CControllerPopupMassupdateItemPrototype.php
@@ -216,7 +216,7 @@ class CControllerPopupMassupdateItemPrototype extends CController {
if (is_array($application_prototype)
&& array_key_exists('new', $application_prototype)) {
$new_application_prototypes[] = [
- 'name' => $application_prototype['new'],
+ 'name' => $application_prototype['new']
];
}
else {
@@ -580,7 +580,7 @@ class CControllerPopupMassupdateItemPrototype extends CController {
'multiple_interface_types' => false,
'initial_item_type' => null,
'preprocessing_test_type' => CControllerPopupItemTestEdit::ZBX_TEST_TYPE_ITEM_PROTOTYPE,
- 'preprocessing_types' => CItemPrototype::$supported_preprocessing_types,
+ 'preprocessing_types' => CItemPrototype::SUPPORTED_PREPROCESSING_TYPES,
'displayApplications' => true,
'display_interfaces' => true,
'displayMasteritems' => true,
diff --git a/ui/app/controllers/CControllerPopupScriptExec.php b/ui/app/controllers/CControllerPopupScriptExec.php
index 1abf588619a..9d7ab9742b1 100644
--- a/ui/app/controllers/CControllerPopupScriptExec.php
+++ b/ui/app/controllers/CControllerPopupScriptExec.php
@@ -23,8 +23,9 @@ class CControllerPopupScriptExec extends CController {
protected function checkInput() {
$fields = [
+ 'scriptid' => 'db scripts.scriptid',
'hostid' => 'db hosts.hostid',
- 'scriptid' => 'db scripts.scriptid'
+ 'eventid' => 'db events.eventid'
];
$ret = $this->validateInput($fields);
@@ -48,62 +49,78 @@ class CControllerPopupScriptExec extends CController {
return false;
}
- return (bool) API::Host()->get([
- 'output' => [],
- 'hostids' => $this->getInput('hostid')
- ]);
+ if ($this->hasInput('hostid')) {
+ return (bool) API::Host()->get([
+ 'output' => [],
+ 'hostids' => $this->getInput('hostid')
+ ]);
+ }
+
+ if ($this->hasInput('eventid')) {
+ return (bool) API::Event()->get([
+ 'output' => [],
+ 'eventids' => $this->getInput('eventid')
+ ]);
+ }
+
+ return false;
}
protected function doAction() {
$scriptid = $this->getInput('scriptid');
- $hostid = $this->getInput('hostid');
+ $hostid = $this->getInput('hostid', '');
+ $eventid = $this->getInput('eventid', '');
$data = [
'title' => _('Scripts'),
- 'command' => '',
- 'message' => '',
- 'errors' => null,
+ 'type' => ZBX_SCRIPT_TYPE_WEBHOOK,
+ 'output' => '',
+ 'debug' => [],
+ 'messages' => null,
+ 'success' => false,
'user' => [
'debug_mode' => $this->getDebugMode()
]
];
$scripts = API::Script()->get([
- 'output' => ['name', 'command'],
+ 'output' => ['name', 'type'],
'scriptids' => $scriptid
]);
if ($scripts) {
$script = $scripts[0];
-
- $macros_data = CMacrosResolverHelper::resolve([
- 'config' => 'scriptConfirmation',
- 'data' => [$hostid => [$scriptid => $script['command']]]
- ]);
-
$data['title'] = $script['name'];
- $data['command'] = $macros_data[$hostid][$scriptid];
+ $data['type'] = $script['type'];
- $result = API::Script()->execute([
- 'hostid' => $hostid,
- 'scriptid' => $scriptid
- ]);
+ $execution_params = ['scriptid' => $scriptid];
- if (!$result) {
- error(_('Cannot execute script'));
+ if ($hostid) {
+ $execution_params['hostid'] = $hostid;
}
- elseif ($result['response'] === 'failed') {
- error($result['value']);
+ elseif ($eventid) {
+ $execution_params['eventid'] = $eventid;
}
- else {
- $data['message'] = $result['value'];
+
+ $result = API::Script()->execute($execution_params);
+
+ if ($result) {
+ if ($data['type'] == ZBX_SCRIPT_TYPE_WEBHOOK) {
+ $value = json_decode($result['value']);
+ $result['value'] = json_last_error() ? $result['value'] : json_encode($value, JSON_PRETTY_PRINT);
+ }
+
+ $data['output'] = $result['value'];
+ $data['debug'] = $result['debug'];
+ $data['success'] = true;
+ info(_('Script execution successful.'));
}
}
else {
error(_('No permissions to referred object or it does not exist!'));
}
- $data['errors'] = getMessages();
+ $data['messages'] = getMessages($data['success'], $data['success'] ? null : _('Cannot execute script.'));
$this->setResponse(new CControllerResponseData($data));
}
diff --git a/ui/app/controllers/CControllerProfileUpdate.php b/ui/app/controllers/CControllerProfileUpdate.php
index 3a3ccc87c39..87148563b85 100644
--- a/ui/app/controllers/CControllerProfileUpdate.php
+++ b/ui/app/controllers/CControllerProfileUpdate.php
@@ -79,10 +79,12 @@ class CControllerProfileUpdate extends CController {
case 'web.templates.httpconf.filter.active':
case 'web.templates.items.filter.active':
case 'web.templates.triggers.filter.active':
+ case 'web.token.filter.active':
case 'web.toptriggers.filter.active':
case 'web.tr_events.hats.'.WIDGET_HAT_EVENTACTIONS.'.state':
case 'web.tr_events.hats.'.WIDGET_HAT_EVENTLIST.'.state':
case 'web.user.filter.active':
+ case 'web.user.token.filter.active':
case 'web.usergroup.filter.active':
case 'web.web.filter.active':
$ret = true;
diff --git a/ui/app/controllers/CControllerScriptCreate.php b/ui/app/controllers/CControllerScriptCreate.php
index 7c3d30d6061..f66cd39bcf1 100644
--- a/ui/app/controllers/CControllerScriptCreate.php
+++ b/ui/app/controllers/CControllerScriptCreate.php
@@ -24,17 +24,21 @@ class CControllerScriptCreate extends CController {
protected function checkInput() {
$fields = [
'name' => 'db scripts.name',
- 'type' => 'db scripts.type |in '.ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT.','.ZBX_SCRIPT_TYPE_IPMI,
- 'execute_on' => 'db scripts.execute_on |in '.ZBX_SCRIPT_EXECUTE_ON_AGENT.','.ZBX_SCRIPT_EXECUTE_ON_SERVER.','.ZBX_SCRIPT_EXECUTE_ON_PROXY,
- 'command' => 'db scripts.command |flags '.P_CRLF,
- 'commandipmi' => 'db scripts.command |flags '.P_CRLF,
+ 'type' => 'db scripts.type|in '.ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT.','.ZBX_SCRIPT_TYPE_IPMI.','.ZBX_SCRIPT_TYPE_WEBHOOK,
+ 'execute_on' => 'db scripts.execute_on|in '.ZBX_SCRIPT_EXECUTE_ON_AGENT.','.ZBX_SCRIPT_EXECUTE_ON_SERVER.','.ZBX_SCRIPT_EXECUTE_ON_PROXY,
+ 'command' => 'db scripts.command|flags '.P_CRLF,
+ 'commandipmi' => 'db scripts.command|flags '.P_CRLF,
+ 'parameters' => 'array',
+ 'script' => 'db scripts.command|flags '.P_CRLF,
+ 'timeout' => 'db scripts.timeout|time_unit '.implode(':', [1, 60]),
'description' => 'db scripts.description',
- 'host_access' => 'db scripts.host_access |in '.PERM_READ.','.PERM_READ_WRITE,
+ 'host_access' => 'db scripts.host_access|in '.PERM_READ.','.PERM_READ_WRITE,
'groupid' => 'db scripts.groupid',
'usrgrpid' => 'db scripts.usrgrpid',
- 'hgstype' => ' in 0,1',
+ 'hgstype' => 'in 0,1',
'confirmation' => 'db scripts.confirmation|not_empty',
- 'enable_confirmation' => ' in 1'
+ 'enable_confirmation' => 'in 1',
+ 'form_refresh' => 'int32'
];
$ret = $this->validateInput($fields);
@@ -65,14 +69,27 @@ class CControllerScriptCreate extends CController {
$this->getInputs($script, ['command', 'description', 'usrgrpid', 'groupid', 'host_access', 'confirmation']);
$script['name'] = trimPath($this->getInput('name', ''));
- $script['type'] = $this->getInput('type', ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT);
- $script['execute_on'] = $this->getInput('execute_on', ZBX_SCRIPT_EXECUTE_ON_SERVER);
+ $script['type'] = $this->getInput('type', ZBX_SCRIPT_TYPE_WEBHOOK);
+ $script['execute_on'] = $this->getInput('execute_on', ZBX_SCRIPT_EXECUTE_ON_PROXY);
+
+ if ($script['type'] != ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT) {
+ $script['execute_on'] = ZBX_SCRIPT_EXECUTE_ON_PROXY;
+ }
if ($script['type'] == ZBX_SCRIPT_TYPE_IPMI) {
- if ($this->hasInput('commandipmi')) {
- $script['command'] = $this->getInput('commandipmi');
+ $script['command'] = $this->getInput('commandipmi', '');
+ }
+ elseif ($script['type'] == ZBX_SCRIPT_TYPE_WEBHOOK) {
+ $script['command'] = $this->getInput('script', '');
+ $script['timeout'] = $this->getInput('timeout', DB::getDefault('scripts', 'timeout'));
+ $parameters = $this->getInput('parameters', []);
+
+ if (array_key_exists('name', $parameters) && array_key_exists('value', $parameters)) {
+ $script['parameters'] = array_map(function ($name, $value) {
+ return compact('name', 'value');
+ }, $parameters['name'], $parameters['value']
+ );
}
- $script['execute_on'] = ZBX_SCRIPT_EXECUTE_ON_SERVER;
}
if ($this->getInput('hgstype', 1) == 0) {
@@ -90,9 +107,7 @@ class CControllerScriptCreate extends CController {
CMessageHelper::setSuccessTitle(_('Script added'));
}
else {
- $response = new CControllerResponseRedirect((new CUrl('zabbix.php'))
- ->setArgument('action', 'script.edit')
- );
+ $response = new CControllerResponseRedirect((new CUrl('zabbix.php'))->setArgument('action', 'script.edit'));
$response->setFormData($this->getInputAll());
CMessageHelper::setErrorTitle(_('Cannot add script'));
}
diff --git a/ui/app/controllers/CControllerScriptEdit.php b/ui/app/controllers/CControllerScriptEdit.php
index 03aade6d000..ea3d62092cf 100644
--- a/ui/app/controllers/CControllerScriptEdit.php
+++ b/ui/app/controllers/CControllerScriptEdit.php
@@ -29,17 +29,21 @@ class CControllerScriptEdit extends CController {
$fields = [
'scriptid' => 'db scripts.scriptid',
'name' => 'db scripts.name',
- 'type' => 'db scripts.type |in '.ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT.','.ZBX_SCRIPT_TYPE_IPMI,
- 'execute_on' => 'db scripts.execute_on |in '.ZBX_SCRIPT_EXECUTE_ON_AGENT.','.ZBX_SCRIPT_EXECUTE_ON_SERVER.','.ZBX_SCRIPT_EXECUTE_ON_PROXY,
+ 'type' => 'db scripts.type|in '.ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT.','.ZBX_SCRIPT_TYPE_IPMI.','.ZBX_SCRIPT_TYPE_WEBHOOK,
+ 'execute_on' => 'db scripts.execute_on|in '.ZBX_SCRIPT_EXECUTE_ON_AGENT.','.ZBX_SCRIPT_EXECUTE_ON_SERVER.','.ZBX_SCRIPT_EXECUTE_ON_PROXY,
'command' => 'db scripts.command',
'commandipmi' => 'db scripts.command',
+ 'parameters' => 'array',
+ 'script' => 'db scripts.command',
+ 'timeout' => 'db media_type.timeout',
'description' => 'db scripts.description',
- 'host_access' => 'db scripts.host_access |in '.PERM_READ.','.PERM_READ_WRITE,
+ 'host_access' => 'db scripts.host_access|in '.PERM_READ.','.PERM_READ_WRITE,
'groupid' => 'db scripts.groupid',
'usrgrpid' => 'db scripts.usrgrpid',
- 'hgstype' => ' in 0,1',
+ 'hgstype' => 'in 0,1',
'confirmation' => 'db scripts.confirmation',
- 'enable_confirmation' => ' in 1'
+ 'enable_confirmation' => 'in 1',
+ 'form_refresh' => 'int32'
];
$ret = $this->validateInput($fields);
@@ -73,68 +77,74 @@ class CControllerScriptEdit extends CController {
'sid' => $this->getUserSID(),
'scriptid' => 0,
'name' => '',
- 'type' => ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT,
+ 'type' => ZBX_SCRIPT_TYPE_WEBHOOK,
'execute_on' => ZBX_SCRIPT_EXECUTE_ON_AGENT,
'command' => '',
'commandipmi' => '',
+ 'parameters' => [],
+ 'script' => '',
+ 'timeout' => DB::getDefault('scripts', 'timeout'),
'description' => '',
'usrgrpid' => 0,
'groupid' => 0,
'host_access' => PERM_READ,
'confirmation' => '',
- 'enable_confirmation' => 0,
+ 'enable_confirmation' => false,
'hgstype' => 0
];
// get values from the dabatase
if ($this->hasInput('scriptid')) {
$scripts = API::Script()->get([
- 'output' => ['scriptid', 'name', 'type', 'execute_on', 'command', 'description', 'usrgrpid',
- 'groupid', 'host_access', 'confirmation'
+ 'output' => ['scriptid', 'name', 'type', 'execute_on', 'command', 'description', 'usrgrpid', 'groupid',
+ 'host_access', 'confirmation', 'timeout', 'parameters'
],
'scriptids' => $this->getInput('scriptid')
]);
- $script = $scripts[0];
-
- $data['scriptid'] = $script['scriptid'];
- $data['name'] = $script['name'];
- $data['type'] = $script['type'];
- $data['execute_on'] = $script['execute_on'];
- $data['command'] = ($script['type'] == ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT) ? $script['command'] : '';
- $data['commandipmi'] = ($script['type'] == ZBX_SCRIPT_TYPE_IPMI) ? $script['command'] : '';
- $data['description'] = $script['description'];
- $data['usrgrpid'] = $script['usrgrpid'];
- $data['groupid'] = $script['groupid'];
- $data['host_access'] = $script['host_access'];
- $data['confirmation'] = $script['confirmation'];
- $data['enable_confirmation'] = ($script['confirmation'] !== '');
- $data['hgstype'] = ($script['groupid'] != 0) ? 1 : 0;
+ if ($scripts) {
+ $script = $scripts[0];
+
+ $data['scriptid'] = $script['scriptid'];
+ $data['name'] = $script['name'];
+ $data['type'] = $script['type'];
+ $data['execute_on'] = $script['execute_on'];
+ $data['command'] = ($script['type'] == ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT) ? $script['command'] : '';
+ $data['commandipmi'] = ($script['type'] == ZBX_SCRIPT_TYPE_IPMI) ? $script['command'] : '';
+ $data['parameters'] = $script['parameters'];
+ $data['script'] = ($script['type'] == ZBX_SCRIPT_TYPE_WEBHOOK) ? $script['command'] : '';
+ $data['timeout'] = $script['timeout'];
+ $data['description'] = $script['description'];
+ $data['usrgrpid'] = $script['usrgrpid'];
+ $data['groupid'] = $script['groupid'];
+ $data['host_access'] = $script['host_access'];
+ $data['confirmation'] = $script['confirmation'];
+ $data['enable_confirmation'] = ($script['confirmation'] !== '');
+ $data['hgstype'] = ($script['groupid'] != 0) ? 1 : 0;
+ }
}
// overwrite with input variables
- $this->getInputs($data, [
- 'name',
- 'type',
- 'execute_on',
- 'command',
- 'commandipmi',
- 'description',
- 'usrgrpid',
- 'groupid',
- 'host_access',
- 'confirmation',
- 'enable_confirmation',
+ $this->getInputs($data, ['name', 'type', 'execute_on', 'command', 'commandipmi', 'parameters', 'script',
+ 'timeout', 'description', 'usrgrpid', 'groupid', 'host_access', 'confirmation', 'enable_confirmation',
'hgstype'
]);
+ if ($this->hasInput('form_refresh') && array_key_exists('name', $data['parameters'])
+ && array_key_exists('value', $data['parameters'])) {
+ $data['parameters'] = array_map(function ($name, $value) {
+ return compact('name', 'value');
+ }, $data['parameters']['name'], $data['parameters']['value']
+ );
+ }
+
// get host group
if ($data['groupid'] == 0) {
$data['hostgroup'] = null;
}
else {
$hostgroups = API::HostGroup()->get([
- 'groupids' => [$data['groupid']],
- 'output' => ['groupid', 'name']
+ 'output' => ['groupid', 'name'],
+ 'groupids' => [$data['groupid']]
]);
$hostgroup = $hostgroups[0];
diff --git a/ui/app/controllers/CControllerScriptList.php b/ui/app/controllers/CControllerScriptList.php
index c1bc759b98c..a9079b45061 100644
--- a/ui/app/controllers/CControllerScriptList.php
+++ b/ui/app/controllers/CControllerScriptList.php
@@ -102,6 +102,10 @@ class CControllerScriptList extends CController {
$groupids = [];
foreach ($data['scripts'] as &$script) {
+ if ($script['type'] == ZBX_SCRIPT_TYPE_WEBHOOK) {
+ $script['command'] = '';
+ }
+
$script['userGroupName'] = null; // all user groups
$script['hostGroupName'] = null; // all host groups
diff --git a/ui/app/controllers/CControllerScriptUpdate.php b/ui/app/controllers/CControllerScriptUpdate.php
index 96add398f86..5a5deb75e30 100644
--- a/ui/app/controllers/CControllerScriptUpdate.php
+++ b/ui/app/controllers/CControllerScriptUpdate.php
@@ -24,18 +24,22 @@ class CControllerScriptUpdate extends CController {
protected function checkInput() {
$fields = [
'scriptid' => 'fatal|required|db scripts.scriptid',
- 'name' => ' db scripts.name',
- 'type' => ' db scripts.type |in '.ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT.','.ZBX_SCRIPT_TYPE_IPMI,
- 'execute_on' => ' db scripts.execute_on |in '.ZBX_SCRIPT_EXECUTE_ON_AGENT.','.ZBX_SCRIPT_EXECUTE_ON_SERVER.','.ZBX_SCRIPT_EXECUTE_ON_PROXY,
- 'command' => ' db scripts.command |flags '.P_CRLF,
- 'commandipmi' => ' db scripts.command |flags '.P_CRLF,
- 'description' => ' db scripts.description',
- 'host_access' => ' db scripts.host_access |in '.PERM_READ.','.PERM_READ_WRITE,
- 'groupid' => ' db scripts.groupid',
- 'usrgrpid' => ' db scripts.usrgrpid',
- 'hgstype' => ' in 0,1',
- 'confirmation' => ' db scripts.confirmation|not_empty',
- 'enable_confirmation' => ' in 1'
+ 'name' => 'db scripts.name',
+ 'type' => 'db scripts.type|in '.ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT.','.ZBX_SCRIPT_TYPE_IPMI.','.ZBX_SCRIPT_TYPE_WEBHOOK,
+ 'execute_on' => 'db scripts.execute_on|in '.ZBX_SCRIPT_EXECUTE_ON_AGENT.','.ZBX_SCRIPT_EXECUTE_ON_SERVER.','.ZBX_SCRIPT_EXECUTE_ON_PROXY,
+ 'command' => 'db scripts.command|flags '.P_CRLF,
+ 'commandipmi' => 'db scripts.command|flags '.P_CRLF,
+ 'parameters' => 'array',
+ 'script' => 'db scripts.command|flags '.P_CRLF,
+ 'timeout' => 'db scripts.timeout|time_unit '.implode(':', [1, 60]),
+ 'description' => 'db scripts.description',
+ 'host_access' => 'db scripts.host_access|in '.PERM_READ.','.PERM_READ_WRITE,
+ 'groupid' => 'db scripts.groupid',
+ 'usrgrpid' => 'db scripts.usrgrpid',
+ 'hgstype' => 'in 0,1',
+ 'confirmation' => 'db scripts.confirmation|not_empty',
+ 'enable_confirmation' => 'in 1',
+ 'form_refresh' => 'int32'
];
$ret = $this->validateInput($fields);
@@ -74,15 +78,31 @@ class CControllerScriptUpdate extends CController {
$this->getInputs($script, ['scriptid', 'command', 'description', 'usrgrpid', 'groupid', 'host_access']);
$script['name'] = trimPath($this->getInput('name', ''));
- $script['type'] = $this->getInput('type', ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT);
- $script['execute_on'] = $this->getInput('execute_on', ZBX_SCRIPT_EXECUTE_ON_SERVER);
+ $script['type'] = $this->getInput('type', ZBX_SCRIPT_TYPE_WEBHOOK);
+ $script['execute_on'] = $this->getInput('execute_on', ZBX_SCRIPT_EXECUTE_ON_PROXY);
$script['confirmation'] = $this->getInput('confirmation', '');
+ if ($script['type'] != ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT) {
+ $script['execute_on'] = ZBX_SCRIPT_EXECUTE_ON_PROXY;
+ }
+
if ($script['type'] == ZBX_SCRIPT_TYPE_IPMI) {
- if ($this->hasInput('commandipmi')) {
- $script['command'] = $this->getInput('commandipmi');
+ $script['command'] = $this->getInput('commandipmi', '');
+ }
+ elseif ($script['type'] == ZBX_SCRIPT_TYPE_WEBHOOK) {
+ $script['command'] = $this->getInput('script', '');
+ $script['timeout'] = $this->getInput('timeout', DB::getDefault('scripts', 'timeout'));
+ $script['parameters'] = [];
+ $parameters = $this->getInput('parameters', []);
+
+ if (array_key_exists('name', $parameters) && array_key_exists('value', $parameters)) {
+ $script['parameters'] = array_map(function ($name, $value) {
+ return compact('name', 'value');
+ },
+ $parameters['name'],
+ $parameters['value']
+ );
}
- $script['execute_on'] = ZBX_SCRIPT_EXECUTE_ON_SERVER;
}
if ($this->getInput('hgstype', 1) == 0) {
diff --git a/ui/app/controllers/CControllerTokenCreate.php b/ui/app/controllers/CControllerTokenCreate.php
new file mode 100644
index 00000000000..b63b3bfccf7
--- /dev/null
+++ b/ui/app/controllers/CControllerTokenCreate.php
@@ -0,0 +1,110 @@
+<?php declare(strict_types=1);
+/*
+** Zabbix
+** Copyright (C) 2001-2020 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+class CControllerTokenCreate extends CController {
+
+ protected function checkInput() {
+ $fields = [
+ 'name' => 'db token.name|required|not_empty',
+ 'description' => 'db token.description',
+ 'userid' => 'db users.userid|required',
+ 'expires_state' => 'in 0,1|required',
+ 'expires_at' => 'range_time',
+ 'status' => 'db token.status|required|in '.ZBX_AUTH_TOKEN_ENABLED.','.ZBX_AUTH_TOKEN_DISABLED,
+ 'action_src' => 'fatal|required|in token.edit,user.token.edit',
+ 'action_dst' => 'fatal|required|in token.view,user.token.view'
+ ];
+
+ $ret = $this->validateInput($fields);
+
+ if (!$ret) {
+ switch ($this->getValidationError()) {
+ case self::VALIDATION_ERROR:
+ $location = (new CUrl('zabbix.php'))->setArgument('action', $this->getInput('action_src'));
+ $response = new CControllerResponseRedirect($location);
+ $response->setFormData($this->getInputAll());
+ CMessageHelper::setErrorTitle(_('Cannot add API token'));
+ $this->setResponse($response);
+ break;
+ case self::VALIDATION_FATAL_ERROR:
+ $this->setResponse(new CControllerResponseFatal());
+ break;
+ }
+ }
+
+ return $ret;
+ }
+
+ protected function checkPermissions() {
+ if (CWebUser::isGuest()) {
+ return false;
+ }
+
+ return $this->checkAccess(CRoleHelper::ACTIONS_MANAGE_API_TOKENS);
+ }
+
+ protected function doAction() {
+ $this->getInputs($token, ['name', 'description', 'userid', 'expires_at', 'status']);
+
+ $token['expires_at'] = $this->getInput('expires_state')
+ ? (new DateTime($token['expires_at']))->getTimestamp()
+ : 0;
+
+ $result = API::Token()->create($token);
+
+ if ($result) {
+ ['tokenids' => $tokenids] = $result;
+ [['token' => $auth_token]] = API::Token()->generate($tokenids);
+
+ $response = new CControllerResponseRedirect((new CUrl('zabbix.php'))
+ ->setArgumentSID()
+ ->setArgument('action', $this->getInput('action_dst'))
+ );
+
+ [$user] = (CWebUser::$data['userid'] != $token['userid'])
+ ? API::User()->get([
+ 'output' => ['alias', 'name', 'surname'],
+ 'userids' => $token['userid']
+ ])
+ : [CWebUser::$data];
+
+ $response->setFormData([
+ 'name' => $token['name'],
+ 'user' => getUserFullname($user),
+ 'auth_token' => $auth_token,
+ 'expires_at' => $token['expires_at'],
+ 'description' => $token['description'],
+ 'status' => $token['status']
+ ]);
+
+ CMessageHelper::setSuccessTitle(_('API token added'));
+ }
+ else {
+ $response = new CControllerResponseRedirect((new CUrl('zabbix.php'))
+ ->setArgument('action', $this->getInput('action_src'))
+ );
+ $response->setFormData($this->getInputAll());
+ CMessageHelper::setErrorTitle(_('Cannot add API token'));
+ }
+
+ $this->setResponse($response);
+ }
+}
diff --git a/ui/app/controllers/CControllerTokenDelete.php b/ui/app/controllers/CControllerTokenDelete.php
new file mode 100644
index 00000000000..5763f0ceaa8
--- /dev/null
+++ b/ui/app/controllers/CControllerTokenDelete.php
@@ -0,0 +1,69 @@
+<?php declare(strict_types=1);
+/*
+** Zabbix
+** Copyright (C) 2001-2020 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+class CControllerTokenDelete extends CController {
+
+ protected function checkInput() {
+ $fields = [
+ 'tokenids' => 'required|array_db token.tokenid',
+ 'action_src' => 'required|in token.list,user.token.list'
+ ];
+
+ $ret = $this->validateInput($fields);
+
+ if (!$ret) {
+ $this->setResponse(new CControllerResponseFatal());
+ }
+
+ return $ret;
+ }
+
+ protected function checkPermissions() {
+ if (CWebUser::isGuest()) {
+ return false;
+ }
+
+ return $this->checkAccess(CRoleHelper::ACTIONS_MANAGE_API_TOKENS);
+ }
+
+ protected function doAction() {
+ $tokenids = $this->getInput('tokenids');
+
+ $result = API::Token()->delete($tokenids);
+
+ $deleted = count($tokenids);
+
+ $response = new CControllerResponseRedirect((new CUrl('zabbix.php'))
+ ->setArgument('action', $this->getInput('action_src'))
+ ->setArgument('page', CPagerHelper::loadPage($this->getInput('action_src'), null))
+ );
+
+ if ($result) {
+ $response->setFormData(['uncheck' => '1']);
+ CMessageHelper::setSuccessTitle(_n('API token deleted', 'API tokens deleted', $deleted));
+ }
+ else {
+ CMessageHelper::setErrorTitle(_n('Cannot delete API token', 'Cannot delete API tokens', $deleted));
+ }
+
+ $this->setResponse($response);
+ }
+}
diff --git a/ui/app/controllers/CControllerTokenDisable.php b/ui/app/controllers/CControllerTokenDisable.php
new file mode 100644
index 00000000000..dc68bd3ec8a
--- /dev/null
+++ b/ui/app/controllers/CControllerTokenDisable.php
@@ -0,0 +1,71 @@
+<?php declare(strict_types=1);
+/*
+** Zabbix
+** Copyright (C) 2001-2020 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+class CControllerTokenDisable extends CController {
+
+ protected function checkInput() {
+ $fields = [
+ 'tokenids' => 'required|array_db token.tokenid',
+ 'action_src' => 'required|in token.list,user.token.list'
+ ];
+
+ $ret = $this->validateInput($fields);
+
+ if (!$ret) {
+ $this->setResponse(new CControllerResponseFatal());
+ }
+
+ return $ret;
+ }
+
+ protected function checkPermissions() {
+ if (CWebUser::isGuest()) {
+ return false;
+ }
+
+ return $this->checkAccess(CRoleHelper::ACTIONS_MANAGE_API_TOKENS);
+ }
+
+ protected function doAction() {
+ $tokens = [];
+
+ foreach ($this->getInput('tokenids') as $tokenid) {
+ $tokens[] = ['tokenid' => $tokenid, 'status' => ZBX_AUTH_TOKEN_DISABLED];
+ }
+
+ $result = API::Token()->update($tokens);
+ $updated = count($tokens);
+ $response = new CControllerResponseRedirect((new CUrl('zabbix.php'))
+ ->setArgument('action', $this->getInput('action_src'))
+ ->setArgument('page', CPagerHelper::loadPage($this->getInput('action_src'), null))
+ );
+
+ if ($result) {
+ $response->setFormData(['uncheck' => '1']);
+ CMessageHelper::setSuccessTitle(_n('API token disabled', 'API tokens disabled', $updated));
+ }
+ else {
+ CMessageHelper::setErrorTitle(_n('Cannot disable API token', 'Cannot disable API tokens', $updated));
+ }
+
+ $this->setResponse($response);
+ }
+}
diff --git a/ui/app/controllers/CControllerTokenEdit.php b/ui/app/controllers/CControllerTokenEdit.php
new file mode 100644
index 00000000000..7fd13ae019a
--- /dev/null
+++ b/ui/app/controllers/CControllerTokenEdit.php
@@ -0,0 +1,110 @@
+<?php declare(strict_types=1);
+/*
+** Zabbix
+** Copyright (C) 2001-2020 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+class CControllerTokenEdit extends CController {
+
+ protected function init() {
+ $this->disableSIDValidation();
+ }
+
+ protected function checkInput() {
+ $fields = [
+ 'tokenid' => 'db token.tokenid',
+ 'name' => 'db token.name',
+ 'description' => 'db token.description',
+ 'userid' => 'db users.userid',
+ 'expires_state' => 'in 0,1',
+ 'expires_at' => 'string',
+ 'status' => 'db token.status|in '.ZBX_AUTH_TOKEN_ENABLED.','.ZBX_AUTH_TOKEN_DISABLED
+ ];
+
+ $ret = $this->validateInput($fields);
+
+ if (!$ret) {
+ $this->setResponse(new CControllerResponseFatal());
+ }
+
+ return $ret;
+ }
+
+ protected function checkPermissions() {
+ if (CWebUser::isGuest()) {
+ return false;
+ }
+
+ return ($this->checkAccess(CRoleHelper::ACTIONS_MANAGE_API_TOKENS)
+ && $this->checkAccess(CRoleHelper::UI_ADMINISTRATION_GENERAL)
+ );
+ }
+
+ protected function doAction() {
+ if ($this->hasInput('tokenid')) {
+ $tokens = API::Token()->get([
+ 'output' => ['tokenid', 'userid', 'name', 'description', 'expires_at', 'status'],
+ 'tokenids' => $this->getInput('tokenid')
+ ]);
+
+ if (!$tokens) {
+ access_deny(ACCESS_DENY_PAGE);
+ }
+
+ $data = $tokens[0];
+
+ if ($data['expires_at'] != 0) {
+ $data['expires_at'] = date(DATE_TIME_FORMAT_SECONDS, (int) $data['expires_at']);
+ $data['expires_state'] = '1';
+ }
+ else {
+ $data['expires_at'] = null;
+ $data['expires_state'] = '0';
+ }
+ }
+ else {
+ $data = [
+ 'tokenid' => 0,
+ 'userid' => 0,
+ 'name' => '',
+ 'description' => '',
+ 'expires_at' => null,
+ 'expires_state' => '1',
+ 'status' => ZBX_AUTH_TOKEN_ENABLED
+ ];
+ }
+
+ $data['ms_user'] = [];
+ $this->getInputs($data, ['userid', 'name', 'description', 'expires_at', 'expires_state', 'status']);
+
+ if ($data['userid'] != 0) {
+ [$user] = (CWebUser::$data['userid'] != $data['userid'])
+ ? API::User()->get([
+ 'output' => ['alias', 'name', 'surname'],
+ 'userids' => $data['userid']
+ ])
+ : [CWebUser::$data];
+
+ $data['ms_user'] = [['id' => $user['userid'], 'name' => getUserFullname($user)]];
+ }
+
+ $response = new CControllerResponseData($data);
+ $response->setTitle(_('API tokens'));
+ $this->setResponse($response);
+ }
+}
diff --git a/ui/app/controllers/CControllerTokenEnable.php b/ui/app/controllers/CControllerTokenEnable.php
new file mode 100644
index 00000000000..1f6381b2ba6
--- /dev/null
+++ b/ui/app/controllers/CControllerTokenEnable.php
@@ -0,0 +1,71 @@
+<?php declare(strict_types=1);
+/*
+** Zabbix
+** Copyright (C) 2001-2020 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+class CControllerTokenEnable extends CController {
+
+ protected function checkInput() {
+ $fields = [
+ 'tokenids' => 'required|array_db token.tokenid',
+ 'action_src' => 'required|in token.list,user.token.list'
+ ];
+
+ $ret = $this->validateInput($fields);
+
+ if (!$ret) {
+ $this->setResponse(new CControllerResponseFatal());
+ }
+
+ return $ret;
+ }
+
+ protected function checkPermissions() {
+ if (CWebUser::isGuest()) {
+ return false;
+ }
+
+ return $this->checkAccess(CRoleHelper::ACTIONS_MANAGE_API_TOKENS);
+ }
+
+ protected function doAction() {
+ $tokens = [];
+
+ foreach ($this->getInput('tokenids') as $tokenid) {
+ $tokens[] = ['tokenid' => $tokenid, 'status' => ZBX_AUTH_TOKEN_ENABLED];
+ }
+
+ $result = API::Token()->update($tokens);
+ $updated = count($tokens);
+ $response = new CControllerResponseRedirect((new CUrl('zabbix.php'))
+ ->setArgument('action', $this->getInput('action_src'))
+ ->setArgument('page', CPagerHelper::loadPage($this->getInput('action_src'), null))
+ );
+
+ if ($result) {
+ $response->setFormData(['uncheck' => '1']);
+ CMessageHelper::setSuccessTitle(_n('API token enabled', 'API tokens enabled', $updated));
+ }
+ else {
+ CMessageHelper::setErrorTitle(_n('Cannot enable API token', 'Cannot enable API tokens', $updated));
+ }
+
+ $this->setResponse($response);
+ }
+}
diff --git a/ui/app/controllers/CControllerTokenList.php b/ui/app/controllers/CControllerTokenList.php
new file mode 100644
index 00000000000..40ebae99564
--- /dev/null
+++ b/ui/app/controllers/CControllerTokenList.php
@@ -0,0 +1,196 @@
+<?php declare(strict_types=1);
+/*
+** Zabbix
+** Copyright (C) 2001-2020 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+class CControllerTokenList extends CController {
+
+ protected function init() {
+ $this->disableSIDValidation();
+ }
+
+ protected function checkInput() {
+ $fields = [
+ 'sort' => 'in name,user,expires_at,creator,lastaccess,status',
+ 'sortorder' => 'in '.ZBX_SORT_DOWN.','.ZBX_SORT_UP,
+ 'uncheck' => 'in 1',
+ 'filter_set' => 'in 1',
+ 'filter_rst' => 'in 1',
+ 'filter_name' => 'string',
+ 'filter_userids' => 'array_db users.userid',
+ 'filter_expires_state' => 'in 1',
+ 'filter_expires_days' => 'int32',
+ 'filter_creator_userids' => 'array_db users.userid',
+ 'filter_status' => 'in -1,'.ZBX_AUTH_TOKEN_ENABLED.','.ZBX_AUTH_TOKEN_DISABLED,
+ 'page' => 'ge 1'
+ ];
+
+ $ret = $this->validateInput($fields);
+
+ if (!$ret) {
+ $this->setResponse(new CControllerResponseFatal());
+ }
+
+ return $ret;
+ }
+
+ protected function checkPermissions() {
+ if (CWebUser::isGuest()) {
+ return false;
+ }
+
+ return ($this->checkAccess(CRoleHelper::ACTIONS_MANAGE_API_TOKENS)
+ && $this->checkAccess(CRoleHelper::UI_ADMINISTRATION_GENERAL)
+ );
+ }
+
+ protected function doAction() {
+ $sort_field = $this->getInput('sort', CProfile::get('web.token.list.sort', 'name'));
+ $sort_order = $this->getInput('sortorder', CProfile::get('web.token.list.sortorder', ZBX_SORT_UP));
+
+ CProfile::update('web.token.list.sort', $sort_field, PROFILE_TYPE_STR);
+ CProfile::update('web.token.list.sortorder', $sort_order, PROFILE_TYPE_STR);
+
+ if ($this->hasInput('filter_set')) {
+ CProfile::update('web.token.filter_name', $this->getInput('filter_name', ''), PROFILE_TYPE_STR);
+ CProfile::updateArray('web.token.filter_userids', $this->getInput('filter_userids', []), PROFILE_TYPE_ID);
+ CProfile::update('web.token.filter_expires_state', $this->getInput('filter_expires_state', 0),
+ PROFILE_TYPE_INT
+ );
+ CProfile::update('web.token.filter_expires_days', $this->getInput('filter_expires_days', 14),
+ PROFILE_TYPE_INT
+ );
+ CProfile::updateArray('web.token.filter_creator_userids', $this->getInput('filter_creator_userids', []),
+ PROFILE_TYPE_ID
+ );
+ CProfile::update('web.token.filter_status', $this->getInput('filter_status', -1), PROFILE_TYPE_INT);
+ }
+ elseif ($this->hasInput('filter_rst')) {
+ CProfile::delete('web.token.filter_name');
+ CProfile::deleteIdx('web.token.filter_userids');
+ CProfile::delete('web.token.filter_expires_state');
+ CProfile::delete('web.token.filter_expires_days');
+ CProfile::deleteIdx('web.token.filter_creator_userids');
+ CProfile::delete('web.token.filter_status');
+ }
+
+ $filter = [
+ 'name' => CProfile::get('web.token.filter_name', ''),
+ 'userids' => CProfile::getArray('web.token.filter_userids', []),
+ 'expires_state' => CProfile::get('web.token.filter_expires_state', 0),
+ 'expires_days' => CProfile::get('web.token.filter_expires_days', 14),
+ 'creator_userids' => CProfile::getArray('web.token.filter_creator_userids', []),
+ 'status' => CProfile::get('web.token.filter_status', -1)
+ ];
+
+ $data = [
+ 'ms_users' => [],
+ 'ms_creators' => [],
+ 'uncheck' => $this->hasInput('uncheck'),
+ 'sort' => $sort_field,
+ 'sortorder' => $sort_order,
+ 'filter' => $filter,
+ 'profileIdx' => 'web.token.filter',
+ 'active_tab' => CProfile::get('web.token.filter.active', 1)
+ ];
+
+ $limit = CSettingsHelper::get(CSettingsHelper::SEARCH_LIMIT) + 1;
+ $data['tokens'] = API::Token()->get([
+ 'output' => ['tokenid', 'name', 'userid', 'expires_at', 'created_at', 'creator_userid', 'lastaccess',
+ 'status'
+ ],
+ 'userids' => $filter['userids'] ? $filter['userids'] : null,
+ 'valid_at' => $filter['expires_state'] ? time() : null,
+ 'expired_at' => $filter['expires_state']
+ ? bcadd((string) time(), bcmul($filter['expires_days'], (string) SEC_PER_DAY, 0), 0)
+ : null,
+ 'search' => [
+ 'name' => ($filter['name'] === '') ? null : $filter['name']
+ ],
+ 'filter' => [
+ 'creator_userid' => $filter['creator_userids'] ? $filter['creator_userids'] : null,
+ 'status' => ($filter['status'] == -1) ? null : $filter['status']
+ ],
+ 'limit' => $limit,
+ 'preservekeys' => true
+ ]);
+
+ if ($data['tokens'] === false) {
+ $data['tokens'] = [];
+ }
+
+ $userids = array_column($data['tokens'], 'userid', 'userid');
+ $userids += array_column($data['tokens'], 'creator_userid', 'creator_userid');
+ $userids += array_flip($filter['userids']);
+ $userids += array_flip($filter['creator_userids']);
+
+ $users = $userids
+ ? API::User()->get([
+ 'output' => ['alias', 'name', 'surname'],
+ 'userids' => array_keys($userids),
+ 'preservekeys' => true
+ ])
+ : [];
+
+ $now = time();
+ array_walk($data['tokens'], function (array &$token) use ($users, $now) {
+ $token['user'] = getUserFullname($users[$token['userid']]);
+
+ $token['creator'] = array_key_exists($token['creator_userid'], $users)
+ ? getUserFullname($users[$token['creator_userid']])
+ : null;
+
+ $token['is_expired'] = $token['expires_at']
+ ? $now > $token['expires_at']
+ : false;
+ });
+
+ CArrayHelper::sort($data['tokens'], [['field' => $sort_field, 'order' => $sort_order]]);
+
+ foreach ($filter['userids'] as $userid) {
+ if (!array_key_exists($userid, $users)) {
+ continue;
+ }
+
+ $data['ms_users'][] = ['id' => $userid, 'name' => getUserFullname($users[$userid])];
+ }
+
+ CArrayHelper::sort($data['ms_users'], ['name']);
+
+ foreach ($filter['creator_userids'] as $userid) {
+ if (!array_key_exists($userid, $users)) {
+ continue;
+ }
+
+ $data['ms_creators'][] = ['id' => $userid, 'name' => getUserFullname($users[$userid])];
+ }
+
+ CArrayHelper::sort($data['ms_creators'], ['name']);
+
+ $page_num = $this->getInput('page', 1);
+ CPagerHelper::savePage('token.list', $page_num);
+ $data['paging'] = CPagerHelper::paginate($page_num, $data['tokens'], $sort_order,
+ (new CUrl('zabbix.php'))->setArgument('action', $this->getAction())
+ );
+
+ $response = new CControllerResponseData($data);
+ $response->setTitle(_('API tokens'));
+ $this->setResponse($response);
+ }
+}
diff --git a/ui/app/controllers/CControllerTokenUpdate.php b/ui/app/controllers/CControllerTokenUpdate.php
new file mode 100644
index 00000000000..c8fd67f925f
--- /dev/null
+++ b/ui/app/controllers/CControllerTokenUpdate.php
@@ -0,0 +1,127 @@
+<?php declare(strict_types=1);
+/*
+** Zabbix
+** Copyright (C) 2001-2020 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+class CControllerTokenUpdate extends CController {
+
+ protected function checkInput() {
+ $fields = [
+ 'tokenid' => 'db token.tokenid|required|fatal',
+ 'name' => 'db token.name|required|not_empty',
+ 'description' => 'db token.description',
+ 'expires_state' => 'in 0,1|required',
+ 'expires_at' => 'range_time',
+ 'status' => 'db token.status|required|in '.ZBX_AUTH_TOKEN_ENABLED.','.ZBX_AUTH_TOKEN_DISABLED,
+ 'action_src' => 'fatal|required|in token.edit,user.token.edit',
+ 'action_dst' => 'fatal|required|in token.list,user.token.list,token.view,user.token.view',
+ 'regenerate' => 'in 1'
+ ];
+
+ $ret = $this->validateInput($fields);
+
+ if (!$ret) {
+ switch ($this->getValidationError()) {
+ case self::VALIDATION_ERROR:
+ $location = (new CUrl('zabbix.php'))
+ ->setArgument('tokenid', $this->getInput('tokenid'))
+ ->setArgument('action', $this->getInput('action_src'));
+ $response = new CControllerResponseRedirect($location);
+ $response->setFormData($this->getInputAll());
+ CMessageHelper::setErrorTitle(_('Cannot update API token'));
+ $this->setResponse($response);
+ break;
+ case self::VALIDATION_FATAL_ERROR:
+ $this->setResponse(new CControllerResponseFatal());
+ break;
+ }
+ }
+
+ return $ret;
+ }
+
+ protected function checkPermissions() {
+ if (CWebUser::isGuest()) {
+ return false;
+ }
+
+ return $this->checkAccess(CRoleHelper::ACTIONS_MANAGE_API_TOKENS);
+ }
+
+ protected function doAction() {
+ $this->getInputs($token, ['tokenid', 'name', 'description', 'expires_at', 'status']);
+
+ $token['expires_at'] = $this->getInput('expires_state')
+ ? (new DateTime($token['expires_at']))->getTimestamp()
+ : 0;
+
+ $result = API::Token()->update($token);
+
+ if ($result) {
+ if ($this->hasInput('regenerate')) {
+ ['tokenids' => $tokenids] = $result;
+ [['userid' => $userid]] = API::Token()->get([
+ 'output' => ['userid'],
+ 'tokenids' => $tokenids
+ ]);
+ [['token' => $auth_token]] = API::Token()->generate($tokenids);
+
+ $response = new CControllerResponseRedirect((new CUrl('zabbix.php'))
+ ->setArgumentSID()
+ ->setArgument('action', $this->getInput('action_dst'))
+ );
+
+ [$user] = (CWebUser::$data['userid'] != $userid)
+ ? API::User()->get([
+ 'output' => ['alias', 'name', 'surname'],
+ 'userids' => $userid
+ ])
+ : [CWebUser::$data];
+
+ $response->setFormData([
+ 'name' => $token['name'],
+ 'user' => getUserFullname($user),
+ 'auth_token' => $auth_token,
+ 'expires_at' => $token['expires_at'],
+ 'description' => $token['description'],
+ 'status' => $token['status']
+ ]);
+ }
+ else {
+ $response = new CControllerResponseRedirect((new CUrl('zabbix.php'))
+ ->setArgument('action', $this->getInput('action_dst'))
+ ->setArgument('page', CPagerHelper::loadPage($this->getInput('action_dst'), null))
+ );
+ $response->setFormData(['uncheck' => '1']);
+ }
+
+ CMessageHelper::setSuccessTitle(_('API token updated'));
+ }
+ else {
+ $response = new CControllerResponseRedirect((new CUrl('zabbix.php'))
+ ->setArgument('action', $this->getInput('action_src'))
+ ->setArgument('tokenid', $this->getInput('tokenid'))
+ );
+ $response->setFormData($this->getInputAll());
+ CMessageHelper::setErrorTitle(_('Cannot update API token'));
+ }
+
+ $this->setResponse($response);
+ }
+}
diff --git a/ui/app/controllers/CControllerTokenView.php b/ui/app/controllers/CControllerTokenView.php
new file mode 100644
index 00000000000..031fe34e772
--- /dev/null
+++ b/ui/app/controllers/CControllerTokenView.php
@@ -0,0 +1,59 @@
+<?php declare(strict_types=1);
+/*
+** Zabbix
+** Copyright (C) 2001-2020 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+class CControllerTokenView extends CController {
+
+ protected function checkInput() {
+ $fields = [
+ 'name' => 'required',
+ 'user' => 'required',
+ 'auth_token' => 'required',
+ 'description' => 'required',
+ 'expires_at' => 'required',
+ 'status' => 'db token.status|in '.ZBX_AUTH_TOKEN_ENABLED.','.ZBX_AUTH_TOKEN_DISABLED.'|required'
+ ];
+
+ $ret = $this->validateInput($fields);
+
+ if (!$ret) {
+ $this->setResponse(new CControllerResponseFatal());
+ }
+
+ return $ret;
+ }
+
+ protected function checkPermissions() {
+ if (CWebUser::isGuest()) {
+ return false;
+ }
+
+ return ($this->checkAccess(CRoleHelper::ACTIONS_MANAGE_API_TOKENS)
+ && $this->checkAccess(CRoleHelper::UI_ADMINISTRATION_GENERAL)
+ );
+ }
+
+ protected function doAction() {
+ $data = $this->getInputAll();
+ $response = new CControllerResponseData($data);
+ $response->setTitle(_('API tokens'));
+ $this->setResponse($response);
+ }
+}
diff --git a/ui/app/controllers/CControllerUserTokenEdit.php b/ui/app/controllers/CControllerUserTokenEdit.php
new file mode 100644
index 00000000000..5ed65e3c5d4
--- /dev/null
+++ b/ui/app/controllers/CControllerUserTokenEdit.php
@@ -0,0 +1,94 @@
+<?php declare(strict_types=1);
+/*
+** Zabbix
+** Copyright (C) 2001-2020 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+class CControllerUserTokenEdit extends CController {
+
+ protected function init() {
+ $this->disableSIDValidation();
+ }
+
+ protected function checkInput() {
+ $fields = [
+ 'tokenid' => 'db token.tokenid',
+ 'name' => 'db token.name',
+ 'description' => 'db token.description',
+ 'expires_state' => 'in 0,1',
+ 'expires_at' => 'string',
+ 'status' => 'db token.status|in '.ZBX_AUTH_TOKEN_ENABLED.','.ZBX_AUTH_TOKEN_DISABLED
+ ];
+
+ $ret = $this->validateInput($fields);
+
+ if (!$ret) {
+ $this->setResponse(new CControllerResponseFatal());
+ }
+
+ return $ret;
+ }
+
+ protected function checkPermissions() {
+ if (CWebUser::isGuest()) {
+ return false;
+ }
+
+ return $this->checkAccess(CRoleHelper::ACTIONS_MANAGE_API_TOKENS);
+ }
+
+ protected function doAction() {
+ if ($this->hasInput('tokenid')) {
+ $tokens = API::Token()->get([
+ 'output' => ['tokenid', 'name', 'description', 'expires_at', 'status'],
+ 'tokenids' => $this->getInput('tokenid')
+ ]);
+
+ if (!$tokens) {
+ access_deny(ACCESS_DENY_PAGE);
+ }
+
+ $data = $tokens[0];
+
+ if ($data['expires_at'] != 0) {
+ $data['expires_at'] = date(DATE_TIME_FORMAT_SECONDS, (int) $data['expires_at']);
+ $data['expires_state'] = '1';
+ }
+ else {
+ $data['expires_at'] = null;
+ $data['expires_state'] = '0';
+ }
+ }
+ else {
+ $data = [
+ 'tokenid' => 0,
+ 'name' => '',
+ 'description' => '',
+ 'expires_at' => null,
+ 'expires_state' => '1',
+ 'status' => ZBX_AUTH_TOKEN_ENABLED
+ ];
+ }
+
+ $this->getInputs($data, ['name', 'description', 'expires_at', 'expires_state', 'status']);
+
+ $response = new CControllerResponseData($data);
+ $response->setTitle(_('API tokens'));
+ $this->setResponse($response);
+ }
+}
diff --git a/ui/app/controllers/CControllerUserTokenList.php b/ui/app/controllers/CControllerUserTokenList.php
new file mode 100644
index 00000000000..6f7e7b1be94
--- /dev/null
+++ b/ui/app/controllers/CControllerUserTokenList.php
@@ -0,0 +1,140 @@
+<?php declare(strict_types=1);
+/*
+** Zabbix
+** Copyright (C) 2001-2020 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+class CControllerUserTokenList extends CController {
+
+ protected function init() {
+ $this->disableSIDValidation();
+ }
+
+ protected function checkInput() {
+ $fields = [
+ 'sort' => 'in name,expires_at,lastaccess,status',
+ 'sortorder' => 'in '.ZBX_SORT_DOWN.','.ZBX_SORT_UP,
+ 'uncheck' => 'in 1',
+ 'filter_set' => 'in 1',
+ 'filter_rst' => 'in 1',
+ 'filter_name' => 'string',
+ 'filter_expires_state' => 'in 1',
+ 'filter_expires_days' => 'int32',
+ 'filter_status' => 'in -1,'.ZBX_AUTH_TOKEN_ENABLED.','.ZBX_AUTH_TOKEN_DISABLED,
+ 'page' => 'ge 1'
+ ];
+
+ $ret = $this->validateInput($fields);
+
+ if (!$ret) {
+ $this->setResponse(new CControllerResponseFatal());
+ }
+
+ return $ret;
+ }
+
+ protected function checkPermissions() {
+ if (CWebUser::isGuest()) {
+ return false;
+ }
+
+ return $this->checkAccess(CRoleHelper::ACTIONS_MANAGE_API_TOKENS);
+ }
+
+ protected function doAction() {
+ $sort_field = $this->getInput('sort', CProfile::get('web.user.token.list.sort', 'name'));
+ $sort_order = $this->getInput('sortorder', CProfile::get('web.user.token.list.sortorder', ZBX_SORT_UP));
+
+ CProfile::update('web.user.token.list.sort', $sort_field, PROFILE_TYPE_STR);
+ CProfile::update('web.user.token.list.sortorder', $sort_order, PROFILE_TYPE_STR);
+
+ if ($this->hasInput('filter_set')) {
+ CProfile::update('web.user.token.filter_name', $this->getInput('filter_name', ''), PROFILE_TYPE_STR);
+ CProfile::update('web.user.token.filter_expires_state', $this->getInput('filter_expires_state', 0),
+ PROFILE_TYPE_INT
+ );
+ CProfile::update('web.user.token.filter_expires_days', $this->getInput('filter_expires_days', 14),
+ PROFILE_TYPE_INT
+ );
+ CProfile::update('web.user.token.filter_status', $this->getInput('filter_status', -1), PROFILE_TYPE_INT);
+ }
+ elseif ($this->hasInput('filter_rst')) {
+ CProfile::delete('web.user.token.filter_name');
+ CProfile::delete('web.user.token.filter_expires_state');
+ CProfile::delete('web.user.token.filter_expires_days');
+ CProfile::delete('web.user.token.filter_status');
+ }
+
+ $filter = [
+ 'name' => CProfile::get('web.user.token.filter_name', ''),
+ 'expires_state' => CProfile::get('web.user.token.filter_expires_state', 0),
+ 'expires_days' => CProfile::get('web.user.token.filter_expires_days', 14),
+ 'status' => CProfile::get('web.user.token.filter_status', -1)
+ ];
+
+ $data = [
+ 'uncheck' => $this->hasInput('uncheck'),
+ 'sort' => $sort_field,
+ 'sortorder' => $sort_order,
+ 'filter' => $filter,
+ 'profileIdx' => 'web.user.token.filter',
+ 'active_tab' => CProfile::get('web.user.token.filter.active', 1)
+ ];
+
+ $limit = CSettingsHelper::get(CSettingsHelper::SEARCH_LIMIT) + 1;
+ $data['tokens'] = API::Token()->get([
+ 'output' => ['tokenid', 'name', 'expires_at', 'created_at', 'lastaccess', 'status'],
+ 'userids' => CWebUser::$data['userid'],
+ 'valid_at' => $filter['expires_state'] ? time() : null,
+ 'expired_at' => $filter['expires_state']
+ ? bcadd((string) time(), bcmul($filter['expires_days'], (string) SEC_PER_DAY, 0), 0)
+ : null,
+ 'search' => [
+ 'name' => ($filter['name'] === '') ? null : $filter['name']
+ ],
+ 'filter' => [
+ 'status' => ($filter['status'] == -1) ? null : $filter['status']
+ ],
+ 'limit' => $limit,
+ 'preservekeys' => true
+ ]);
+
+ if ($data['tokens'] === false) {
+ $data['tokens'] = [];
+ }
+
+ $now = time();
+ array_walk($data['tokens'], function (array &$token) use ($now) {
+ $token['is_expired'] = $token['expires_at']
+ ? $now > $token['expires_at']
+ : false;
+ });
+
+ CArrayHelper::sort($data['tokens'], [['field' => $sort_field, 'order' => $sort_order]]);
+
+ $page_num = $this->getInput('page', 1);
+ CPagerHelper::savePage('user.token.list', $page_num);
+ $data['paging'] = CPagerHelper::paginate($page_num, $data['tokens'], $sort_order,
+ (new CUrl('zabbix.php'))->setArgument('action', $this->getAction())
+ );
+
+ $response = new CControllerResponseData($data);
+ $response->setTitle(_('API tokens'));
+ $this->setResponse($response);
+ }
+}
diff --git a/ui/app/controllers/CControllerUserTokenView.php b/ui/app/controllers/CControllerUserTokenView.php
new file mode 100644
index 00000000000..d49d03f4419
--- /dev/null
+++ b/ui/app/controllers/CControllerUserTokenView.php
@@ -0,0 +1,56 @@
+<?php declare(strict_types=1);
+/*
+** Zabbix
+** Copyright (C) 2001-2020 Zabbix SIA
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+**/
+
+
+class CControllerUserTokenView extends CController {
+
+ protected function checkInput() {
+ $fields = [
+ 'name' => 'required',
+ 'auth_token' => 'required',
+ 'description' => 'required',
+ 'expires_at' => 'required',
+ 'status' => 'db token.status|in '.ZBX_AUTH_TOKEN_ENABLED.','.ZBX_AUTH_TOKEN_DISABLED.'|required'
+ ];
+
+ $ret = $this->validateInput($fields);
+
+ if (!$ret) {
+ $this->setResponse(new CControllerResponseFatal());
+ }
+
+ return $ret;
+ }
+
+ protected function checkPermissions() {
+ if (CWebUser::isGuest()) {
+ return false;
+ }
+
+ return $this->checkAccess(CRoleHelper::ACTIONS_MANAGE_API_TOKENS);
+ }
+
+ protected function doAction() {
+ $data = $this->getInputAll();
+ $response = new CControllerResponseData($data);
+ $response->setTitle(_('API tokens'));
+ $this->setResponse($response);
+ }
+}
diff --git a/ui/app/controllers/CControllerUserroleCreate.php b/ui/app/controllers/CControllerUserroleCreate.php
index c7fbdeda9ea..2b1128b2d33 100644
--- a/ui/app/controllers/CControllerUserroleCreate.php
+++ b/ui/app/controllers/CControllerUserroleCreate.php
@@ -74,6 +74,7 @@ class CControllerUserroleCreate extends CControllerUserroleEditGeneral {
'actions_change_severity' => 'in 0,1',
'actions_add_problem_comments' => 'in 0,1',
'actions_execute_scripts' => 'in 0,1',
+ 'actions_manage_api_tokens' => 'in 0,1',
'modules' => 'array',
'api_mode' => 'in 0,1',
'api_methods' => 'array'
diff --git a/ui/app/controllers/CControllerUserroleEdit.php b/ui/app/controllers/CControllerUserroleEdit.php
index 869049e32d0..03afaa57c41 100644
--- a/ui/app/controllers/CControllerUserroleEdit.php
+++ b/ui/app/controllers/CControllerUserroleEdit.php
@@ -77,6 +77,7 @@ class CControllerUserroleEdit extends CControllerUserroleEditGeneral {
'actions_change_severity' => 'in 0,1',
'actions_add_problem_comments' => 'in 0,1',
'actions_execute_scripts' => 'in 0,1',
+ 'actions_manage_api_tokens' => 'in 0,1',
'ui_default_access' => 'in 0,1',
'modules_default_access' => 'in 0,1',
'actions_default_access' => 'in 0,1',
diff --git a/ui/app/controllers/CControllerUserroleUpdate.php b/ui/app/controllers/CControllerUserroleUpdate.php
index 4cc4519f1b1..c7821cf3144 100644
--- a/ui/app/controllers/CControllerUserroleUpdate.php
+++ b/ui/app/controllers/CControllerUserroleUpdate.php
@@ -73,6 +73,7 @@ class CControllerUserroleUpdate extends CControllerUserroleEditGeneral {
'actions_change_severity' => 'in 0,1',
'actions_add_problem_comments' => 'in 0,1',
'actions_execute_scripts' => 'in 0,1',
+ 'actions_manage_api_tokens' => 'in 0,1',
'ui_default_access' => 'in 0,1',
'modules_default_access' => 'in 0,1',
'actions_default_access' => 'in 0,1',
diff --git a/ui/app/controllers/CControllerWidgetHostAvailView.php b/ui/app/controllers/CControllerWidgetHostAvailView.php
index 43f7ae91124..20eb83c765a 100644
--- a/ui/app/controllers/CControllerWidgetHostAvailView.php
+++ b/ui/app/controllers/CControllerWidgetHostAvailView.php
@@ -34,14 +34,7 @@ class CControllerWidgetHostAvailView extends CControllerWidget {
protected function doAction() {
$fields = $this->getForm()->getFieldsData();
- $type_fields = [
- INTERFACE_TYPE_AGENT => 'available',
- INTERFACE_TYPE_SNMP => 'snmp_available',
- INTERFACE_TYPE_JMX => 'jmx_available',
- INTERFACE_TYPE_IPMI => 'ipmi_available'
- ];
-
- $interface_types = array_keys($type_fields);
+ $interface_types = [INTERFACE_TYPE_AGENT, INTERFACE_TYPE_SNMP, INTERFACE_TYPE_JMX, INTERFACE_TYPE_IPMI];
// Sanitize non-existing interface types.
$fields['interface_type'] = array_values(array_intersect($interface_types, $fields['interface_type']));
@@ -52,28 +45,34 @@ class CControllerWidgetHostAvailView extends CControllerWidget {
$hosts_total = array_fill_keys($interface_types, 0);
$hosts_count = array_fill_keys($interface_types, [
- HOST_AVAILABLE_UNKNOWN => 0,
- HOST_AVAILABLE_TRUE => 0,
- HOST_AVAILABLE_FALSE => 0
+ INTERFACE_AVAILABLE_UNKNOWN => 0,
+ INTERFACE_AVAILABLE_TRUE => 0,
+ INTERFACE_AVAILABLE_FALSE => 0
]);
$db_hosts = API::Host()->get([
- 'output' => ['available', 'snmp_available', 'jmx_available', 'ipmi_available'],
- 'selectInterfaces' => ['interfaceid', 'type'],
+ 'output' => [],
+ 'selectInterfaces' => ['type', 'available'],
'groupids' => $groupids,
'filter' => ($fields['maintenance'] == HOST_MAINTENANCE_STATUS_OFF)
? ['status' => HOST_STATUS_MONITORED, 'maintenance_status' => HOST_MAINTENANCE_STATUS_OFF]
: ['status' => HOST_STATUS_MONITORED]
]);
+ $availability_priority = [INTERFACE_AVAILABLE_FALSE, INTERFACE_AVAILABLE_UNKNOWN, INTERFACE_AVAILABLE_TRUE];
foreach ($db_hosts as $host) {
- $interfaces = [];
- foreach ($host['interfaces'] as $val) {
- $interfaces[$val['type']] = true;
+ $host_interfaces = array_fill_keys($interface_types, []);
+
+ foreach ($host['interfaces'] as $interface) {
+ $host_interfaces[$interface['type']][] = $interface['available'];
}
- foreach (array_keys($interfaces) as $type) {
- $hosts_count[$type][$host[$type_fields[$type]]]++;
+ $host_interfaces = array_filter($host_interfaces);
+
+ foreach ($host_interfaces as $type => $interfaces) {
+ $interfaces_availability = array_intersect($availability_priority, $interfaces);
+ $available = reset($interfaces_availability);
+ $hosts_count[$type][$available]++;
$hosts_total[$type]++;
}
}