disableCsrfValidation(); } protected function checkInput(): bool { $fields = [ 'eventsource' => 'required|db actions.eventsource|in '.implode(',', [ EVENT_SOURCE_TRIGGERS, EVENT_SOURCE_DISCOVERY, EVENT_SOURCE_AUTOREGISTRATION, EVENT_SOURCE_INTERNAL, EVENT_SOURCE_SERVICE ]), 'recovery' => 'db operations.recovery', 'actionid' => 'db actions.actionid', 'operationid' => 'db operations.operationid', 'operationtype' => 'db operations.operationtype', 'data' => 'array', 'row_index' => 'int32' ]; $ret = $this->validateInput($fields) && $this->validateInputConstraints(); if (!$ret) { $this->setResponse( new CControllerResponseData(['main_block' => json_encode([ 'error' => [ 'messages' => array_column(get_and_clear_messages(), 'message') ] ])]) ); } return $ret; } protected function validateInputConstraints(): bool { $eventsource = $this->getInput('eventsource'); $recovery = $this->getInput('recovery'); $allowed_operations = getAllowedOperations($eventsource); if (!array_key_exists($recovery, $allowed_operations)) { error(_('Unsupported operation.')); return false; } return true; } protected function checkPermissions(): bool { if ($this->getUserType() >= USER_TYPE_ZABBIX_ADMIN) { if (!$this->getInput('actionid', '0')) { return true; } return (bool) API::Action()->get([ 'output' => [], 'actionids' => $this->getInput('actionid') ]); } return false; } protected function doAction(): void { $operation = $this->getInput('data', []) + $this->defaultOperationObject(); $eventsource = (int) $this->getInput('eventsource'); $recovery = (int) $this->getInput('recovery'); $operation_types = $this->popupConfigOperationTypes($eventsource, $recovery); foreach ($operation_types as $type) { $operation_type[$type['value']] = $type['name']; } $media_types = API::MediaType()->get(['output' => ['mediatypeid', 'name', 'status']]); CArrayHelper::sort($media_types, ['name']); $media_types = array_values($media_types); $operation['row_index'] = $this->getInput('row_index', -1); $operation_data = $this->getData($operation); if (array_key_exists('user_group', $operation_data)) { $operation['opmessage_grp'] = $operation_data['user_group']; } if (array_key_exists('users', $operation_data)) { $operation['opmessage_usr'] = $operation_data['users']; } if (array_key_exists('opcommand_hst', $operation)) { $current_host = null; foreach ($operation['opcommand_hst'] as $opcommand_hst) { if ($opcommand_hst['hostid'] == 0) { $current_host = ['id' => 0]; } } if (array_key_exists('opcommand_hst', $operation_data)) { $operation['opcommand_hst'] = $operation_data['opcommand_hst']; } $operation['opcommand_hst'][] = $current_host; } if (array_key_exists('opcommand_grp', $operation_data)) { $operation['opcommand_grp'] = $operation_data['opcommand_grp']; } if (array_key_exists('opgroup', $operation_data)) { $operation['opgroup'] = $operation_data['opgroup']; } if (array_key_exists('optemplate', $operation_data)) { $operation['optemplate'] = $operation_data['optemplate']; } if (array_key_exists('optag', $operation_data)) { $operation['optag'] = $operation_data['optag']; } $data = [ 'eventsource' => $eventsource, 'actionid' => $this->getInput('actionid', 0), 'recovery' => $recovery, 'operation' => $operation, 'operation_types' => $operation_type, 'mediatype_options' => $media_types, 'user' => ['debug_mode' => $this->getDebugMode()] ]; $this->setResponse(new CControllerResponseData($data)); } /** * Returns necessary operation 'element' data for operation popup multiselects. * * @param array $operation Operation object. * * @return array */ private function getData(array $operation): array { $result = []; if ($operation['opmessage_grp']) { $user_groups = CArrayHelper::renameObjectsKeys(API::UserGroup()->get([ 'output' => ['usrgrpid', 'name'], 'usrgrpids' => array_column($operation['opmessage_grp'], 'usrgrpid') ]), ['usrgrpid' => 'id']); CArrayHelper::sort($user_groups, ['name']); $result['user_group'] = array_values($user_groups); } if ($operation['opmessage_usr']) { $users = CArrayHelper::renameObjectsKeys(API::User()->get([ 'output' => ['userid', 'username', 'name', 'surname'], 'userids' => array_column($operation['opmessage_usr'], 'userid') ]), ['userid' => 'id']); $fullnames = []; foreach ($users as $user) { $fullnames[$user['id']] = getUserFullname($user); $user['name'] = $fullnames[$user['id']]; $result['users'][] = $user; } CArrayHelper::sort($result['users'], ['name']); } if ($operation['opcommand_hst']) { if ($operation['opcommand_hst'][0]['hostid'] == 0) { unset($operation['opcommand_hst'][0]); } if (count($operation['opcommand_hst']) > 0) { $hosts = CArrayHelper::renameObjectsKeys(API::Host()->get([ 'output' => ['hostid', 'name'], 'hostids' => array_column($operation['opcommand_hst'], 'hostid') ]), ['hostid' => 'id']); CArrayHelper::sort($hosts, ['name']); $result['opcommand_hst'] = array_values($hosts); } } if ($operation['opcommand_grp']) { $groups = CArrayHelper::renameObjectsKeys(API::HostGroup()->get([ 'output' => ['groupid', 'name'], 'groupids' => array_column($operation['opcommand_grp'], 'groupid') ]), ['groupid' => 'id']); CArrayHelper::sort($groups, ['name']); $result['opcommand_grp'] = array_values($groups); } if ($operation['opgroup']) { $groups = CArrayHelper::renameObjectsKeys(API::HostGroup()->get([ 'output' => ['groupid', 'name'], 'groupids' => array_column($operation['opgroup'], 'groupid') ]), ['groupid' => 'id']); CArrayHelper::sort($groups, ['name']); $result['opgroup'] = array_values($groups); } if ($operation['optemplate']) { $templates = CArrayHelper::renameObjectsKeys(API::Template()->get([ 'output' => ['templateid', 'name'], 'templateids' => array_column($operation['optemplate'], 'templateid') ]), ['templateid' => 'id']); CArrayHelper::sort($templates, ['name']); $result['optemplate'] = array_values($templates); } if ($operation['optag']) { CArrayHelper::sort($operation['optag'], ['tag', 'value']); $result['optag'] = array_values($operation['optag']); } return $result; } /** * Returns default Operation. * * @return array */ private function defaultOperationObject(): array { return [ 'opmessage_usr' => [], 'opmessage_grp' => [], 'opmessage' => [ 'subject' => '', 'message' => '', 'mediatypeid' => '0', 'default_msg' => '1' ], 'operationtype' => '0', 'esc_step_from' => '1', 'esc_step_to' => '1', 'esc_period' => '0', 'opcommand_hst' => [], 'opcommand_grp' => [], 'evaltype' => (string) CONDITION_EVAL_TYPE_AND_OR, 'opconditions' => [], 'opgroup' => [], 'optag' => [], 'optemplate' => [], 'opinventory' => [ 'inventory_mode' => (string) HOST_INVENTORY_MANUAL ], 'opcommand' => [ 'scriptid' => '0' ] ]; } /** * Returns "operation type" configuration fields for given operation in given source. * * @param int $eventsource Action event source. * @param int $recovery Action operation mode. Possible values: * ACTION_OPERATION, ACTION_RECOVERY_OPERATION, ACTION_UPDATE_OPERATION * * @return array */ private function popupConfigOperationTypes(int $eventsource, int $recovery): array { $operation_type_options = []; $scripts_allowed = false; // First determine if scripts are allowed for this action type. foreach (getAllowedOperations($eventsource)[$recovery] as $operation_type) { if ($operation_type == OPERATION_TYPE_COMMAND) { $scripts_allowed = true; break; } } // Then remove Remote command from dropdown list. foreach (getAllowedOperations($eventsource)[$recovery] as $operation_type) { if ($operation_type == OPERATION_TYPE_COMMAND) { continue; } $operation_type_options[] = [ 'value' => 'cmd['.$operation_type.']', 'name' => operation_type2str($operation_type) ]; } if ($scripts_allowed) { $db_scripts = API::Script()->get([ 'output' => ['scriptid', 'name'], 'filter' => ['scope' => ZBX_SCRIPT_SCOPE_ACTION] ]); if ($db_scripts) { CArrayHelper::sort($db_scripts, ['name']); foreach ($db_scripts as $db_script) { $operation_type_options[] = [ 'value' => 'scriptid['.$db_script['scriptid'].']', 'name' => $db_script['name'] ]; } } } return $operation_type_options; } }