/** * Checks if the given array of objects is valid. * * @param array $value * * @return bool */ public function validate($value) { if (!is_array($value)) { $this->error($this->messageInvalid); return false; } // check if it's empty if (!$this->empty && !$value) { $this->error($this->messageEmpty); return false; } // check for objects with duplicate values if ($this->uniqueField) { if ($duplicate = CArrayHelper::findDuplicate($value, $this->uniqueField, $this->uniqueField2)) { $this->error($this->messageDuplicate, $duplicate[$this->uniqueField]); return false; } } return true; }
/** * Check duplicate step names. * * @throws APIException if duplicate step name is found. * * @param array $httpTest * @param array $dbHttpTest */ protected function checkDuplicateSteps(array $httpTest, array $dbHttpTest = array()) { if ($duplicate = CArrayHelper::findDuplicate($httpTest['steps'], 'name')) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Web scenario step "%1$s" already exists.', $duplicate['name'])); } }
/** * Validates the input parameters for the create() method. * * @param array $hosts hosts data array * * @throws APIException if the input is invalid. */ protected function validateCreate(array $hosts) { $host_db_fields = ['host' => null]; $groupids = []; foreach ($hosts as &$host) { // Validate mandatory fields. if (!check_db_fields($host_db_fields, $host)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Wrong fields for host "%1$s".', array_key_exists('host', $host) ? $host['host'] : '')); } // Validate "host" field. if (!preg_match('/^' . ZBX_PREG_HOST_FORMAT . '$/', $host['host'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect characters used for host name "%s".', $host['host'])); } // If visible name is not given or empty it should be set to host name. Required for duplicate checks. if (!array_key_exists('name', $host) || !trim($host['name'])) { $host['name'] = $host['host']; } // Validate "groups" field. if (!array_key_exists('groups', $host) || !is_array($host['groups']) || !$host['groups']) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('No groups for host "%1$s".', $host['host'])); } $groupids = array_merge($groupids, zbx_objectValues($host['groups'], 'groupid')); } unset($host); // Check for duplicate "host" and "name" fields. $duplicate = CArrayHelper::findDuplicate($hosts, 'host'); if ($duplicate) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Duplicate host. Host with the same host name "%s" already exists in data.', $duplicate['host'])); } $duplicate = CArrayHelper::findDuplicate($hosts, 'name'); if ($duplicate) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Duplicate host. Host with the same visible name "%s" already exists in data.', $duplicate['name'])); } // Validate permissions to host groups. if ($groupids) { $db_groups = API::HostGroup()->get(['output' => ['groupid'], 'groupids' => $groupids, 'editable' => true, 'preservekeys' => true]); } foreach ($hosts as $host) { foreach ($host['groups'] as $group) { if (!array_key_exists($group['groupid'], $db_groups)) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!')); } } } $inventory_fields = zbx_objectValues(getHostInventories(), 'db_field'); $status_validator = new CLimitedSetValidator(['values' => [HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED], 'messageInvalid' => _('Incorrect status for host "%1$s".')]); $host_names = []; foreach ($hosts as $host) { if (!array_key_exists('interfaces', $host) || !is_array($host['interfaces']) || !$host['interfaces']) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('No interfaces for host "%s".', $host['host'])); } if (array_key_exists('status', $host)) { $status_validator->setObjectName($host['host']); $this->checkValidator($host['status'], $status_validator); } if (array_key_exists('inventory', $host) && $host['inventory']) { if (array_key_exists('inventory_mode', $host) && $host['inventory_mode'] == HOST_INVENTORY_DISABLED) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Cannot set inventory fields for disabled inventory.')); } $fields = array_keys($host['inventory']); foreach ($fields as $field) { if (!in_array($field, $inventory_fields)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect inventory field "%s".', $field)); } } } // Collect technical and visible names to check if they exist in hosts and templates. $host_names['host'][$host['host']] = true; $host_names['name'][$host['name']] = true; } $filter = ['host' => array_keys($host_names['host']), 'name' => array_keys($host_names['name'])]; $hosts_exists = $this->get(['output' => ['host', 'name'], 'filter' => $filter, 'searchByAny' => true, 'nopermissions' => true]); foreach ($hosts_exists as $host_exists) { if (array_key_exists($host_exists['host'], $host_names['host'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Host with the same name "%s" already exists.', $host_exists['host'])); } if (array_key_exists($host_exists['name'], $host_names['name'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Host with the same visible name "%s" already exists.', $host_exists['name'])); } } $templates_exists = API::Template()->get(['output' => ['host', 'name'], 'filter' => $filter, 'searchByAny' => true, 'nopermissions' => true]); foreach ($templates_exists as $template_exists) { if (array_key_exists($template_exists['host'], $host_names['host'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Template with the same name "%s" already exists.', $template_exists['host'])); } if (array_key_exists($template_exists['name'], $host_names['name'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Template with the same visible name "%s" already exists.', $template_exists['name'])); } } $this->validateEncryption($hosts); }
/** * Check "mappings" field properties. * * @param array $valuemaps An array of value maps. * @param array $valuemaps[]['mappings'] An array of "mappings" data. * @param string $valuemaps[]['mappings'][]['value'] Original mapping value. * @param string $valuemaps[]['mappings'][]['newvalue'] Value to which the original value is mapped to. * * @throws APIException if the input is invalid. */ protected function checkMappings(array $valuemaps) { $required_fields = ['value', 'newvalue']; foreach ($valuemaps as $valuemap) { if (!array_key_exists('mappings', $valuemap)) { continue; } if (!is_array($valuemap['mappings'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); } elseif (!$valuemap['mappings']) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('At least one mapping should be given for value map "%1$s".', $valuemap['name'])); } foreach ($valuemap['mappings'] as $mapping) { if (!is_array($mapping)) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); } $missing_keys = checkRequiredKeys($mapping, $required_fields); if ($missing_keys) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Mapping is missing parameters: %1$s for value map "%2$s".', implode(', ', $missing_keys), $valuemap['name'])); } else { foreach (['value', 'newvalue'] as $field) { if (is_array($mapping[$field])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); } } } if ($mapping['newvalue'] === '' || $mapping['newvalue'] === null || $mapping['newvalue'] === false) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Empty new value in value map "%1$s".', $valuemap['name'])); } } $duplicate = CArrayHelper::findDuplicate($valuemap['mappings'], 'value'); if ($duplicate) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Duplicate mapping value "%1$s" for value map "%2$s".', $duplicate['value'], $valuemap['name'])); } } }
/** * Validates the input parameters for the update() method. * * @param array $mediatypes * * @throws APIException if the input is invalid. */ protected function validateUpdate(array $mediatypes) { if (self::$userData['type'] != USER_TYPE_SUPER_ADMIN) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('Only Super Admins can edit media types.')); } if (!$mediatypes) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Empty input parameter.')); } // Validate given IDs. $this->checkObjectIds($mediatypes, 'mediatypeid', _('No "%1$s" given for media type.'), _('Empty media type ID.'), _('Incorrect media type ID.')); $mediatypeids = zbx_objectValues($mediatypes, 'mediatypeid'); // Check value map names. $db_mediatypes = API::getApiService()->select('media_type', ['output' => ['mediatypeid', 'type', 'description', 'exec_path', 'status', 'smtp_port', 'smtp_verify_peer', 'smtp_verify_host', 'smtp_authentication'], 'mediatypeids' => $mediatypeids, 'preservekeys' => true]); $check_names = []; foreach ($mediatypes as $mediatype) { // Check if this media type exists. if (!array_key_exists($mediatype['mediatypeid'], $db_mediatypes)) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!')); } // Validate "description" field. if (array_key_exists('description', $mediatype)) { if (is_array($mediatype['description'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); } elseif ($mediatype['description'] === '' || $mediatype['description'] === null || $mediatype['description'] === false) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect value for field "%1$s": %2$s.', 'description', _('cannot be empty'))); } $check_names[$mediatype['description']] = true; } } if ($check_names) { $db_mediatype_names = API::getApiService()->select('media_type', ['output' => ['mediatypeid', 'description'], 'filter' => ['name' => array_keys($check_names)]]); $db_mediatype_names = zbx_toHash($db_mediatype_names, 'description'); foreach ($mediatypes as $mediatype) { if (array_key_exists('description', $mediatype) && array_key_exists($mediatype['description'], $db_mediatype_names) && !idcmp($db_mediatype_names[$mediatype['description']]['mediatypeid'], $mediatype['mediatypeid'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Media type "%1$s" already exists.', $mediatype['description'])); } } } // Populate "description" field, if not set. Type field should not be populated at this point. $mediatypes = $this->extendFromObjects(zbx_toHash($mediatypes, 'mediatypeid'), $db_mediatypes, ['description']); $duplicate_name = CArrayHelper::findDuplicate($mediatypes, 'description'); if ($duplicate_name) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Duplicate "description" value "%1$s" for media type.', $duplicate_name['description'])); } foreach ($mediatypes as $mediatype) { $db_mediatype = $db_mediatypes[$mediatype['mediatypeid']]; // Recheck mandatory fields if type changed. if (array_key_exists('type', $mediatype) && $db_mediatype['type'] != $mediatype['type']) { $this->checkRequiredFieldsByType($mediatype); } else { $optional_fields_by_type = [MEDIA_TYPE_EMAIL => ['smtp_server', 'smtp_helo', 'smtp_email'], MEDIA_TYPE_EXEC => ['exec_path'], MEDIA_TYPE_SMS => ['gsm_modem'], MEDIA_TYPE_JABBER => ['username'], MEDIA_TYPE_EZ_TEXTING => ['exec_path', 'username']]; foreach ($optional_fields_by_type[$db_mediatype['type']] as $field) { if (array_key_exists($field, $mediatype) && ($mediatype[$field] === '' || $mediatype[$field] === null)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Field "%1$s" is missing a value for media type "%2$s".', $field, $mediatype['description'])); } } // Populate "type" field from DB, since it is not set and is required for further validation. $mediatype['type'] = $db_mediatype['type']; } switch ($mediatype['type']) { case MEDIA_TYPE_EZ_TEXTING: if (array_key_exists('exec_path', $mediatype)) { $message_text_limit_validator = new CLimitedSetValidator(['values' => [EZ_TEXTING_LIMIT_USA, EZ_TEXTING_LIMIT_CANADA]]); if ($db_mediatype['exec_path'] !== $mediatype['exec_path'] && !$message_text_limit_validator->validate($mediatype['exec_path'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect value "%1$s" in field "%2$s" for media type "%3$s".', $mediatype['exec_path'], 'exec_path', $mediatype['description'])); } } break; case MEDIA_TYPE_EMAIL: if (array_key_exists('smtp_authentication', $mediatype)) { $smtp_authentication_validator = new CLimitedSetValidator(['values' => [SMTP_AUTHENTICATION_NONE, SMTP_AUTHENTICATION_NORMAL]]); if (!$smtp_authentication_validator->validate($mediatype['smtp_authentication'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect value "%1$s" in field "%2$s" for media type "%3$s".', $mediatype['smtp_authentication'], 'smtp_authentication', $mediatype['description'])); } if ($mediatype['smtp_authentication'] == SMTP_AUTHENTICATION_NORMAL) { // Check 'passwd' field when auth is set to 'normal' manually. if ($db_mediatype['smtp_authentication'] == $mediatype['smtp_authentication'] && array_key_exists('passwd', $mediatype) && ($mediatype['passwd'] === '' || $mediatype['passwd'] === null)) { /* * When auth is set to 'normal', check if password field is set manually. * Otherwise the password is not changed. */ self::exception(ZBX_API_ERROR_PARAMETERS, _s('Password required for media type "%1$s".', $mediatype['description'])); } elseif ($db_mediatype['smtp_authentication'] != $mediatype['smtp_authentication'] && (!array_key_exists('passwd', $mediatype) || $mediatype['passwd'] === '' || $mediatype['passwd'] === null)) { /* * First check if 'passwd' field exists when authentication is changed from * 'none' to 'normal' and then validate it. */ self::exception(ZBX_API_ERROR_PARAMETERS, _s('Password required for media type "%1$s".', $mediatype['description'])); } } } elseif ($db_mediatype['smtp_authentication'] == SMTP_AUTHENTICATION_NORMAL && array_key_exists('passwd', $mediatype) && ($mediatype['passwd'] === '' || $mediatype['passwd'] === null)) { // Check 'passwd' field depeding on authentication set from DB and when it is set to 'normal'. self::exception(ZBX_API_ERROR_PARAMETERS, _s('Password required for media type "%1$s".', $mediatype['description'])); } // Validate optional 'smtp_port' field. if (array_key_exists('smtp_port', $mediatype) && $db_mediatype['smtp_port'] != $mediatype['smtp_port'] && !validatePortNumber($mediatype['smtp_port'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect value "%1$s" in field "%2$s" for media type "%3$s".', $mediatype['smtp_port'], 'smtp_port', $mediatype['description'])); } // Validate optional field 'smtp_security'. if (array_key_exists('smtp_security', $mediatype)) { $smtp_security_validator = new CLimitedSetValidator(['values' => [SMTP_CONNECTION_SECURITY_NONE, SMTP_CONNECTION_SECURITY_STARTTLS, SMTP_CONNECTION_SECURITY_SSL_TLS]]); if (!$smtp_security_validator->validate($mediatype['smtp_security'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect value "%1$s" in field "%2$s" for media type "%3$s".', $mediatype['smtp_security'], 'smtp_security', $mediatype['description'])); } } // Validate optional field 'smtp_verify_peer'. if (array_key_exists('smtp_verify_peer', $mediatype) && $db_mediatype['smtp_verify_peer'] != $mediatype['smtp_verify_peer']) { $smtp_verify_peer_validator = new CLimitedSetValidator(['values' => [0, 1]]); if (!$smtp_verify_peer_validator->validate($mediatype['smtp_verify_peer'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect value "%1$s" in field "%2$s" for media type "%3$s".', $mediatype['smtp_verify_peer'], 'smtp_verify_peer', $mediatype['description'])); } } // Validate optional field 'smtp_verify_host'. if (array_key_exists('smtp_verify_host', $mediatype) && $db_mediatype['smtp_verify_host'] != $mediatype['smtp_verify_host']) { $smtp_verify_host_validator = new CLimitedSetValidator(['values' => [0, 1]]); if (!$smtp_verify_host_validator->validate($mediatype['smtp_verify_host'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect value "%1$s" in field "%2$s" for media type "%3$s".', $mediatype['smtp_verify_host'], 'smtp_verify_host', $mediatype['description'])); } } break; case MEDIA_TYPE_EXEC: if (array_key_exists('exec_params', $mediatype) && $mediatype['exec_params'] !== '') { $pos = strrpos($mediatype['exec_params'], "\n"); if ($pos === false || strlen($mediatype['exec_params']) != $pos + 1) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Script parameters "%1$s" are missing the last new line feed for media type "%2$s".', $mediatype['exec_params'], $mediatype['description'])); } } break; } // Validate optional 'status' field and only when status is changed. if (array_key_exists('status', $mediatype) && $db_mediatype['status'] != $mediatype['status']) { $status_validator = new CLimitedSetValidator(['values' => [MEDIA_TYPE_STATUS_ACTIVE, MEDIA_TYPE_STATUS_DISABLED]]); if (!$status_validator->validate($mediatype['status'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect value "%1$s" in field "%2$s" for media type "%3$s".', $mediatype['status'], 'status', $mediatype['description'])); } } } }
/** * Check item prototype data and set flags field. * * @param array $items an array of items passed by reference * @param array $item['applicationPrototypes'] an array of application prototypes * @param string $item['applicationPrototypes'][]['name'] application prototype name * @param bool $update */ protected function checkInput(array &$items, $update = false) { parent::checkInput($items, $update); // set proper flags to divide normal and discovered items in future processing foreach ($items as &$item) { $item['flags'] = ZBX_FLAG_DISCOVERY_PROTOTYPE; // set default formula value if (!$update && !isset($item['formula'])) { $item['formula'] = '1'; } if (array_key_exists('applicationPrototypes', $item) && is_array($item['applicationPrototypes']) && $item['applicationPrototypes']) { // Check that "name" field exists for application prototypes. foreach ($item['applicationPrototypes'] as $application_prototype) { if (!array_key_exists('name', $application_prototype)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Missing "name" field for application prototype in item prototype "%1$s".', $item['name'])); } if ($application_prototype['name'] === '') { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Empty application prototype name in item prototype "%1$s".', $item['name'])); } if (array_key_exists('templateid', $application_prototype)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Cannot set "templateid" field for application prototype in item prototype "%1$s".', $item['name'])); } } // Check that "name" field has no duplicate values for application prototypes. $duplicate_name = CArrayHelper::findDuplicate($item['applicationPrototypes'], 'name'); if ($duplicate_name) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Duplicate "name" value "%1$s" for application prototype in item prototype "%2$s".', $duplicate_name['name'], $item['name'])); } } } unset($item); }
/** * Validate the input parameters for the update() method. * * @param array $maps maps data array * @param array $db_maps db maps data array * * @throws APIException if the input is invalid. */ protected function validateUpdate(array $maps, array $db_maps) { if (!$maps) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Empty input parameter.')); } $user_data = self::$userData; // Validate given IDs. $this->checkObjectIds($maps, 'sysmapid', _('No "%1$s" given for map.'), _('Empty map ID.'), _('Incorrect map ID.')); $check_names = []; foreach ($maps as $map) { // Check if this map exists and user has write permissions. if (!array_key_exists($map['sysmapid'], $db_maps)) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!')); } // Validate "name" field. if (array_key_exists('name', $map)) { if (is_array($map['name'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); } elseif ($map['name'] === '' || $map['name'] === null || $map['name'] === false) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Map name cannot be empty.')); } if ($db_maps[$map['sysmapid']]['name'] !== $map['name']) { $check_names[] = $map; } } } if ($check_names) { // Check for duplicate names. $duplicate = CArrayHelper::findDuplicate($check_names, 'name'); if ($duplicate) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Duplicate "name" value "%1$s" for map.', $duplicate['name'])); } $db_map_names = $this->get(['output' => ['sysmapid', 'name'], 'filter' => ['name' => zbx_objectValues($check_names, 'name')], 'nopermissions' => true]); $db_map_names = zbx_toHash($db_map_names, 'name'); // Check for existing names. foreach ($check_names as $map) { if (array_key_exists($map['name'], $db_map_names) && bccomp($db_map_names[$map['name']]['sysmapid'], $map['sysmapid']) != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Map "%1$s" already exists.', $map['name'])); } } } $private_validator = new CLimitedSetValidator(['values' => [PUBLIC_SHARING, PRIVATE_SHARING]]); $permission_validator = new CLimitedSetValidator(['values' => [PERM_READ, PERM_READ_WRITE]]); foreach ($maps as $map) { // Check if owner can be set. if (array_key_exists('userid', $map)) { if ($map['userid'] === '' || $map['userid'] === null || $map['userid'] === false) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Map owner cannot be empty.')); } elseif ($map['userid'] != $user_data['userid'] && $user_data['type'] != USER_TYPE_SUPER_ADMIN && $user_data['type'] != USER_TYPE_ZABBIX_ADMIN) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Only administrators can set map owner.')); } } // Unset extra field. unset($db_maps[$map['sysmapid']]['userid']); $map = array_merge($db_maps[$map['sysmapid']], $map); // Check "width" and "height" fields. if ($map['width'] > 65535 || $map['width'] < 1) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect "width" value for map "%1$s".', $map['name'])); } if ($map['height'] > 65535 || $map['height'] < 1) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect "height" value for map "%1$s".', $map['name'])); } if (!$private_validator->validate($map['private'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect "private" value "%1$s" for map "%2$s".', $map['private'], $map['name'])); } $userids = []; // Map user shares. if (array_key_exists('users', $map)) { if (!is_array($map['users'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); } $required_fields = ['userid', 'permission']; foreach ($map['users'] as $share) { // Check required parameters. $missing_keys = checkRequiredKeys($share, $required_fields); if ($missing_keys) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('User sharing is missing parameters: %1$s for map "%2$s".', implode(', ', $missing_keys), $map['name'])); } else { foreach ($required_fields as $field) { if ($share[$field] === '' || $share[$field] === null) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Sharing option "%1$s" is missing a value for map "%2$s".', $field, $map['name'])); } } } if (!$permission_validator->validate($share['permission'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect "permission" value "%1$s" in users for map "%2$s".', $share['permission'], $map['name'])); } if ($map['private'] == PUBLIC_SHARING && $share['permission'] == PERM_READ) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Map "%1$s" is public and read-only sharing is disallowed.', $map['name'])); } if (array_key_exists($share['userid'], $userids)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Duplicate userid "%1$s" in users for map "%2$s".', $share['userid'], $map['name'])); } $userids[$share['userid']] = $share['userid']; } } if (array_key_exists('userid', $map) && $map['userid']) { $userids[$map['userid']] = $map['userid']; } // Users validation. if ($userids) { $db_users = API::User()->get(['userids' => $userids, 'countOutput' => true]); if (count($userids) != $db_users) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect user ID specified for map "%1$s".', $map['name'])); } } // Map user group shares. if (array_key_exists('userGroups', $map)) { if (!is_array($map['userGroups'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); } $shared_user_groupids = []; $required_fields = ['usrgrpid', 'permission']; foreach ($map['userGroups'] as $share) { // Check required parameters. $missing_keys = checkRequiredKeys($share, $required_fields); if ($missing_keys) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('User group sharing is missing parameters: %1$s for map "%2$s".', implode(', ', $missing_keys), $map['name'])); } else { foreach ($required_fields as $field) { if ($share[$field] === '' || $share[$field] === null) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Sharing option "%1$s" is missing a value for map "%2$s".', $field, $map['name'])); } } } if (!$permission_validator->validate($share['permission'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect "permission" value "%1$s" in user groups for map "%2$s".', $share['permission'], $map['name'])); } if ($map['private'] == PUBLIC_SHARING && $share['permission'] == PERM_READ) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Map "%1$s" is public and read-only sharing is disallowed.', $map['name'])); } if (array_key_exists($share['usrgrpid'], $shared_user_groupids)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Duplicate usrgrpid "%1$s" in user groups for map "%2$s".', $share['usrgrpid'], $map['name'])); } $shared_user_groupids[$share['usrgrpid']] = $share['usrgrpid']; } if ($shared_user_groupids) { $db_user_groups = API::UserGroup()->get(['usrgrpids' => $shared_user_groupids, 'countOutput' => true]); if (count($shared_user_groupids) != $db_user_groups) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect user group ID specified for map "%1$s".', $map['name'])); } } unset($shared_user_groupids); } // Map labels. $map_labels = ['label_type' => ['typeName' => _('icon')]]; if (array_key_exists('label_format', $map) && $map['label_format'] == SYSMAP_LABEL_ADVANCED_ON) { $map_labels['label_type_hostgroup'] = ['string' => 'label_string_hostgroup', 'typeName' => _('host group')]; $map_labels['label_type_host'] = ['string' => 'label_string_host', 'typeName' => _('host')]; $map_labels['label_type_trigger'] = ['string' => 'label_string_trigger', 'typeName' => _('trigger')]; $map_labels['label_type_map'] = ['string' => 'label_string_map', 'typeName' => _('map')]; $map_labels['label_type_image'] = ['string' => 'label_string_image', 'typeName' => _('image')]; } foreach ($map_labels as $label_name => $labelData) { if (!array_key_exists($label_name, $map)) { continue; } if (sysmapElementLabel($map[$label_name]) === false) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect %1$s label type value for map "%2$s".', $labelData['typeName'], $map['name'])); } if ($map[$label_name] == MAP_LABEL_TYPE_CUSTOM) { if (!array_key_exists('string', $labelData)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect %1$s label type value for map "%2$s".', $labelData['typeName'], $map['name'])); } if (!array_key_exists($labelData['string'], $map) || zbx_empty($map[$labelData['string']])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Custom label for map "%2$s" elements of type "%1$s" may not be empty.', $labelData['typeName'], $map['name'])); } } if ($label_name === 'label_type_image' && $map[$label_name] == MAP_LABEL_TYPE_STATUS) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect %1$s label type value for map "%2$s".', $labelData['typeName'], $map['name'])); } if ($label_name === 'label_type' || $label_name === 'label_type_host') { continue; } if ($map[$label_name] == MAP_LABEL_TYPE_IP) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect %1$s label type value for map "%2$s".', $labelData['typeName'], $map['name'])); } } // Validating grid options. $possibleGridSizes = [20, 40, 50, 75, 100]; // Grid size. if (array_key_exists('grid_size', $map) && !in_array($map['grid_size'], $possibleGridSizes)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Value "%1$s" is invalid for parameter "grid_show". Choices are: "%2$s".', $map['grid_size'], implode('", "', $possibleGridSizes))); } // Grid auto align. if (array_key_exists('grid_align', $map) && $map['grid_align'] != SYSMAP_GRID_ALIGN_ON && $map['grid_align'] != SYSMAP_GRID_ALIGN_OFF) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Value "%1$s" is invalid for parameter "grid_align". Choices are: "%2$s" and "%3$s"', $map['grid_align'], SYSMAP_GRID_ALIGN_ON, SYSMAP_GRID_ALIGN_OFF)); } // Grid show. if (array_key_exists('grid_show', $map) && $map['grid_show'] != SYSMAP_GRID_SHOW_ON && $map['grid_show'] != SYSMAP_GRID_SHOW_OFF) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Value "%1$s" is invalid for parameter "grid_show". Choices are: "%2$s" and "%3$s".', $map['grid_show'], SYSMAP_GRID_SHOW_ON, SYSMAP_GRID_SHOW_OFF)); } // Urls. if (array_key_exists('urls', $map) && !empty($map['urls'])) { $urlNames = zbx_toHash($map['urls'], 'name'); foreach ($map['urls'] as $url) { if ($url['name'] === '' || $url['url'] === '') { self::exception(ZBX_API_ERROR_PARAMETERS, _s('URL should have both "name" and "url" fields for map "%1$s".', $map['name'])); } if (!array_key_exists($url['name'], $urlNames)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('URL name should be unique for map "%1$s".', $map['name'])); } unset($urlNames[$url['name']]); } } if (array_key_exists('selements', $map) && !is_array($map['selements'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); } // Map selement links. if (array_key_exists('links', $map) && $map['links']) { $selementids = zbx_objectValues($map['selements'], 'selementid'); foreach ($map['links'] as $link) { if (!in_array($link['selementid1'], $selementids)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Link selementid1 field is pointing to a nonexistent map selement ID "%1$s" for map "%2$s".', $link['selementid1'], $map['name'])); } if (!in_array($link['selementid2'], $selementids)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Link selementid2 field is pointing to a nonexistent map selement ID "%1$s" for map "%2$s".', $link['selementid2'], $map['name'])); } } } } }
/** * Validates the input parameters for the update() method. * * @param array $screens * @param array $db_screens array of existing screens with screen IDs as keys. * * @throws APIException if the input is invalid. */ protected function validateUpdate(array $screens, array $db_screens) { if (!$screens) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Empty input parameter.')); } $user_data = self::$userData; // Validate given IDs. $this->checkObjectIds($screens, 'screenid', _('No "%1$s" given for screen.'), _('Empty screen ID.'), _('Incorrect screen ID.')); $check_names = []; foreach ($screens as $screen) { $this->validateScreenSize($screen); if (!array_key_exists($screen['screenid'], $db_screens)) { self::exception(ZBX_API_ERROR_PERMISSIONS, _('No permissions to referred object or it does not exist!')); } } $screens = $this->extendFromObjects(zbx_toHash($screens, 'screenid'), $db_screens, ['name']); foreach ($screens as $screen) { // "templateid" is not allowed if (array_key_exists('templateid', $screen)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Cannot update "templateid" for screen "%1$s".', $screen['name'])); } if (array_key_exists('name', $screen)) { // Validate "name" field. if (array_key_exists('name', $screen)) { if (is_array($screen['name'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); } elseif ($screen['name'] === '' || $screen['name'] === null || $screen['name'] === false) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Screen name cannot be empty.')); } if ($db_screens[$screen['screenid']]['name'] !== $screen['name']) { $check_names[] = $screen; } } } } if ($check_names) { // Check for duplicate names. $duplicate = CArrayHelper::findDuplicate($check_names, 'name'); if ($duplicate) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Duplicate "name" value "%1$s" for screen.', $duplicate['name'])); } $db_screen_names = $this->get(['output' => ['screenid', 'name'], 'filter' => ['name' => zbx_objectValues($check_names, 'name')], 'nopermissions' => true]); $db_screen_names = zbx_toHash($db_screen_names, 'name'); // Check for existing names. foreach ($check_names as $screen) { if (array_key_exists($screen['name'], $db_screen_names) && bccomp($db_screen_names[$screen['name']]['screenid'], $screen['screenid']) != 0) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Screen "%1$s" already exists.', $screen['name'])); } } } $private_validator = new CLimitedSetValidator(['values' => [PUBLIC_SHARING, PRIVATE_SHARING]]); $permission_validator = new CLimitedSetValidator(['values' => [PERM_READ, PERM_READ_WRITE]]); foreach ($screens as $screen) { // Check if owner can be set. if (array_key_exists('userid', $screen)) { if ($screen['userid'] === '' || $screen['userid'] === null || $screen['userid'] === false) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Screen owner cannot be empty.')); } elseif ($screen['userid'] != $user_data['userid'] && $user_data['type'] != USER_TYPE_SUPER_ADMIN && $user_data['type'] != USER_TYPE_ZABBIX_ADMIN) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Only administrators can set screen owner.')); } } // Unset extra field. unset($db_screens[$screen['screenid']]['userid']); $screen = array_merge($db_screens[$screen['screenid']], $screen); if (!$private_validator->validate($screen['private'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect "private" value "%1$s" for screen "%2$s".', $screen['private'], $screen['name'])); } $userids = []; // Screen user shares. if (array_key_exists('users', $screen)) { if (!is_array($screen['users'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); } $required_fields = ['userid', 'permission']; foreach ($screen['users'] as $share) { // Check required parameters. $missing_keys = checkRequiredKeys($share, $required_fields); if ($missing_keys) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('User sharing is missing parameters: %1$s for screen "%2$s".', implode(', ', $missing_keys), $screen['name'])); } else { foreach ($required_fields as $field) { if ($share[$field] === '' || $share[$field] === null) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Sharing option "%1$s" is missing a value for screen "%2$s".', $field, $screen['name'])); } } } if (!$permission_validator->validate($share['permission'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect "permission" value "%1$s" in users for screen "%2$s".', $share['permission'], $screen['name'])); } if ($screen['private'] == PUBLIC_SHARING && $share['permission'] == PERM_READ) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Screen "%1$s" is public and read-only sharing is disallowed.', $screen['name'])); } if (array_key_exists($share['userid'], $userids)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Duplicate userid "%1$s" in users for screen "%2$s".', $share['userid'], $screen['name'])); } $userids[$share['userid']] = $share['userid']; } } if (array_key_exists('userid', $screen) && $screen['userid']) { $userids[$screen['userid']] = $screen['userid']; } // Users validation. if ($userids) { $db_users = API::User()->get(['userids' => $userids, 'countOutput' => true]); if (count($userids) != $db_users) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect user ID specified for screen "%1$s".', $screen['name'])); } } // Screen user group shares. if (array_key_exists('userGroups', $screen)) { if (!is_array($screen['userGroups'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _('Incorrect arguments passed to function.')); } $shared_user_groupids = []; $required_fields = ['usrgrpid', 'permission']; foreach ($screen['userGroups'] as $share) { // Check required parameters. $missing_keys = checkRequiredKeys($share, $required_fields); if ($missing_keys) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('User group sharing is missing parameters: %1$s for screen "%2$s".', implode(', ', $missing_keys), $screen['name'])); } else { foreach ($required_fields as $field) { if ($share[$field] === '' || $share[$field] === null) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Sharing option "%1$s" is missing a value for screen "%2$s".', $field, $screen['name'])); } } } if (!$permission_validator->validate($share['permission'])) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect "permission" value "%1$s" in user groups for screen "%2$s".', $share['permission'], $screen['name'])); } if ($screen['private'] == PUBLIC_SHARING && $share['permission'] == PERM_READ) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Screen "%1$s" is public and read-only sharing is disallowed.', $screen['name'])); } if (array_key_exists($share['usrgrpid'], $shared_user_groupids)) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Duplicate usrgrpid "%1$s" in user groups for screen "%2$s".', $share['usrgrpid'], $screen['name'])); } $shared_user_groupids[$share['usrgrpid']] = $share['usrgrpid']; } if ($shared_user_groupids) { $db_user_groups = API::UserGroup()->get(['usrgrpids' => $shared_user_groupids, 'countOutput' => true]); if (count($shared_user_groupids) != $db_user_groups) { self::exception(ZBX_API_ERROR_PARAMETERS, _s('Incorrect user group ID specified for screen "%1$s".', $screen['name'])); } } unset($shared_user_groupids); } } }