1<?php
2/*
3** Zabbix
4** Copyright (C) 2001-2021 Zabbix SIA
5**
6** This program is free software; you can redistribute it and/or modify
7** it under the terms of the GNU General Public License as published by
8** the Free Software Foundation; either version 2 of the License, or
9** (at your option) any later version.
10**
11** This program is distributed in the hope that it will be useful,
12** but WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14** GNU General Public License for more details.
15**
16** You should have received a copy of the GNU General Public License
17** along with this program; if not, write to the Free Software
18** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19**/
20
21
22class CActionCondValidator extends CValidator {
23
24	/**
25	 * Returns true if the given $value is valid, or set's an error and returns false otherwise.
26	 *
27	 * @param array $condition
28	 *
29	 * @return bool
30	 */
31	public function validate($condition) {
32		// Build validators.
33		$discoveryCheckTypeValidator = new CLimitedSetValidator([
34			'values' => array_keys(discovery_check_type2str())
35		]);
36		$discoveryObjectStatusValidator = new CLimitedSetValidator([
37			'values' => array_keys(discovery_object_status2str())
38		]);
39		$triggerSeverityValidator = new CLimitedSetValidator([
40			'values' => [
41				TRIGGER_SEVERITY_NOT_CLASSIFIED,
42				TRIGGER_SEVERITY_INFORMATION,
43				TRIGGER_SEVERITY_WARNING,
44				TRIGGER_SEVERITY_AVERAGE,
45				TRIGGER_SEVERITY_HIGH,
46				TRIGGER_SEVERITY_DISASTER
47			]
48		]);
49		$discoveryObjectValidator = new CLimitedSetValidator([
50			'values' => array_keys(discovery_object2str())
51		]);
52		$eventTypeValidator = new CLimitedSetValidator([
53			'values' => array_keys(eventType())
54		]);
55
56		// Validate condition values depending on condition type.
57		switch ($condition['conditiontype']) {
58			case CONDITION_TYPE_HOST_GROUP:
59			case CONDITION_TYPE_TEMPLATE:
60			case CONDITION_TYPE_TRIGGER:
61			case CONDITION_TYPE_HOST:
62			case CONDITION_TYPE_DRULE:
63			case CONDITION_TYPE_PROXY:
64				if (zbx_empty($condition['value']) || $condition['value'] === '0') {
65					$this->setError(_s('Incorrect value for field "%1$s": %2$s.', 'value', _('cannot be empty')));
66				}
67				elseif (is_array($condition['value'])) {
68					foreach ($condition['value'] as $value) {
69						if (zbx_empty($value) || $value == 0) {
70							$this->setError(
71								_s('Incorrect value for field "%1$s": %2$s.', 'value', _('cannot be empty'))
72							);
73							break;
74						}
75					}
76				}
77				break;
78
79			case CONDITION_TYPE_DCHECK:
80				if (!$condition['value']) {
81					$this->setError(
82						_s('Incorrect value for field "%1$s": %2$s.', 'value', _('cannot be empty'))
83					);
84				}
85				break;
86
87			case CONDITION_TYPE_DOBJECT:
88				if (zbx_empty($condition['value'])) {
89					$this->setError(
90						_s('Incorrect value for field "%1$s": %2$s.', 'value', _('cannot be empty'))
91					);
92				}
93				elseif (!$discoveryObjectValidator->validate($condition['value'])) {
94					$this->setError(_('Incorrect action condition discovery object.'));
95				}
96				break;
97
98			case CONDITION_TYPE_TIME_PERIOD:
99				$time_period_parser = new CTimePeriodsParser(['usermacros' => true]);
100
101				if ($time_period_parser->parse($condition['value']) != CParser::PARSE_SUCCESS) {
102					$this->setError(_('Invalid time period.'));
103				}
104				break;
105
106			case CONDITION_TYPE_DHOST_IP:
107				$ip_range_parser = new CIPRangeParser(['v6' => ZBX_HAVE_IPV6, 'dns' => false, 'max_ipv4_cidr' => 30]);
108				if (zbx_empty($condition['value'])) {
109					$this->setError(_s('Incorrect value for field "%1$s": %2$s.', 'value', _('cannot be empty')));
110				}
111				elseif (!$ip_range_parser->parse($condition['value'])) {
112					$this->setError(_s('Invalid action condition: %1$s.', $ip_range_parser->getError()));
113				}
114				break;
115
116			case CONDITION_TYPE_DSERVICE_TYPE:
117				if (zbx_empty($condition['value'])) {
118					$this->setError(_s('Incorrect value for field "%1$s": %2$s.', 'value', _('cannot be empty')));
119				}
120				elseif (!$discoveryCheckTypeValidator->validate($condition['value'])) {
121					$this->setError(_('Incorrect action condition discovery check.'));
122				}
123				break;
124
125			case CONDITION_TYPE_DSERVICE_PORT:
126				if (zbx_empty($condition['value'])) {
127					$this->setError(_s('Incorrect value for field "%1$s": %2$s.', 'value', _('cannot be empty')));
128				}
129				elseif (!validate_port_list($condition['value'])) {
130					$this->setError(_s('Incorrect action condition port "%1$s".', $condition['value']));
131				}
132				break;
133
134			case CONDITION_TYPE_DSTATUS:
135				if (zbx_empty($condition['value'])) {
136					$this->setError(_s('Incorrect value for field "%1$s": %2$s.', 'value', _('cannot be empty')));
137				}
138				elseif (!$discoveryObjectStatusValidator->validate($condition['value'])) {
139					$this->setError(_('Incorrect action condition discovery status.'));
140				}
141				break;
142
143			case CONDITION_TYPE_SUPPRESSED:
144				if (!zbx_empty($condition['value'])) {
145					$this->setError(_s('Incorrect value for field "%1$s": %2$s.', 'value', _('should be empty')));
146				}
147				break;
148
149			case CONDITION_TYPE_TRIGGER_SEVERITY:
150				if (zbx_empty($condition['value'])) {
151					$this->setError(_s('Incorrect value for field "%1$s": %2$s.', 'value', _('cannot be empty')));
152				}
153				elseif (!$triggerSeverityValidator->validate($condition['value'])) {
154					$this->setError(_('Incorrect action condition trigger severity.'));
155				}
156				break;
157
158			case CONDITION_TYPE_EVENT_TYPE:
159				if (zbx_empty($condition['value'])) {
160					$this->setError(_s('Incorrect value for field "%1$s": %2$s.', 'value', _('cannot be empty')));
161				}
162				elseif (!$eventTypeValidator->validate($condition['value'])) {
163					$this->setError(_('Incorrect action condition event type.'));
164				}
165				break;
166
167			case CONDITION_TYPE_TRIGGER_NAME:
168			case CONDITION_TYPE_DUPTIME:
169			case CONDITION_TYPE_DVALUE:
170			case CONDITION_TYPE_APPLICATION:
171			case CONDITION_TYPE_HOST_NAME:
172			case CONDITION_TYPE_HOST_METADATA:
173			case CONDITION_TYPE_EVENT_TAG:
174				if (zbx_empty($condition['value'])) {
175					$this->setError(_s('Incorrect value for field "%1$s": %2$s.', 'value', _('cannot be empty')));
176				}
177				break;
178
179			case CONDITION_TYPE_EVENT_TAG_VALUE:
180				if (!is_string($condition['value2']) || $condition['value2'] === '') {
181					$this->setError(_s('Incorrect value for field "%1$s": %2$s.', 'value2', _('cannot be empty')));
182				}
183				elseif (!is_string($condition['value'])) {
184					$this->setError(
185						_s('Incorrect value for field "%1$s": %2$s.', 'value', _('a character string is expected'))
186					);
187				}
188				elseif (array_key_exists('operator', $condition) && $condition['value'] === ''
189						&& ($condition['operator'] == CONDITION_OPERATOR_LIKE
190							|| $condition['operator'] == CONDITION_OPERATOR_NOT_LIKE)) {
191					$this->setError(_s('Incorrect value for field "%1$s": %2$s.', 'value', _('cannot be empty')));
192				}
193				break;
194
195			default:
196				$this->setError(_('Incorrect action condition type.'));
197		}
198
199		// If no error is not set, return true.
200		return !(bool) $this->getError();
201	}
202}
203