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
21class CActionCondValidator extends CValidator {
22
23	/**
24	 * Returns true if the given $value is valid, or set's an error and returns false otherwise.
25	 *
26	 *
27	 * @param $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		$triggerValueValidator = new CLimitedSetValidator([
53			'values' => array_keys(trigger_value2str())
54		]);
55		$eventTypeValidator = new CLimitedSetValidator([
56			'values' => array_keys(eventType())
57		]);
58
59		$conditionValue = $condition['value'];
60		// validate condition values depending on condition type
61		switch ($condition['conditiontype']) {
62			case CONDITION_TYPE_HOST_GROUP:
63				if (!$conditionValue) {
64					$this->setError(_('Empty action condition.'));
65				}
66				break;
67
68			case CONDITION_TYPE_TEMPLATE:
69				if (!$conditionValue) {
70					$this->setError(_('Empty action condition.'));
71				}
72				break;
73
74			case CONDITION_TYPE_TRIGGER:
75				if (!$conditionValue) {
76					$this->setError(_('Empty action condition.'));
77				}
78				break;
79
80			case CONDITION_TYPE_HOST:
81				if (!$conditionValue) {
82					$this->setError(_('Empty action condition.'));
83				}
84				break;
85
86			case CONDITION_TYPE_DRULE:
87				if (!$conditionValue) {
88					$this->setError(_('Empty action condition.'));
89				}
90				break;
91
92			case CONDITION_TYPE_DCHECK:
93				if (!$conditionValue) {
94					$this->setError(_('Empty action condition.'));
95				}
96				break;
97
98			case CONDITION_TYPE_PROXY:
99				if (!$conditionValue) {
100					$this->setError(_('Empty action condition.'));
101				}
102				break;
103
104			case CONDITION_TYPE_DOBJECT:
105				if (zbx_empty($conditionValue)) {
106					$this->setError(_('Empty action condition.'));
107				}
108				elseif (!$discoveryObjectValidator->validate($conditionValue)) {
109					$this->setError(_('Incorrect action condition discovery object.'));
110				}
111				break;
112
113			case CONDITION_TYPE_TIME_PERIOD:
114				$time_period_parser = new CTimePeriodsParser(['usermacros' => true]);
115
116				if ($time_period_parser->parse($conditionValue) != CParser::PARSE_SUCCESS) {
117					$this->setError(_('Invalid time period.'));
118				}
119				break;
120
121			case CONDITION_TYPE_DHOST_IP:
122				$ip_range_parser = new CIPRangeParser(['v6' => ZBX_HAVE_IPV6, 'dns' => false, 'max_ipv4_cidr' => 30]);
123				if (zbx_empty($conditionValue)) {
124					$this->setError(_('Empty action condition.'));
125				}
126				elseif (!$ip_range_parser->parse($conditionValue)) {
127					$this->setError(_s('Invalid action condition: %1$s.', $ip_range_parser->getError()));
128				}
129				break;
130
131			case CONDITION_TYPE_DSERVICE_TYPE:
132				if (zbx_empty($conditionValue)) {
133					$this->setError(_('Empty action condition.'));
134				}
135				elseif (!$discoveryCheckTypeValidator->validate($conditionValue)) {
136					$this->setError(_('Incorrect action condition discovery check.'));
137				}
138				break;
139
140			case CONDITION_TYPE_DSERVICE_PORT:
141				if (zbx_empty($conditionValue)) {
142					$this->setError(_('Empty action condition.'));
143				}
144				elseif (!validate_port_list($conditionValue)) {
145					$this->setError(_s('Incorrect action condition port "%1$s".', $conditionValue));
146				}
147				break;
148
149			case CONDITION_TYPE_DSTATUS:
150				if (zbx_empty($conditionValue)) {
151					$this->setError(_('Empty action condition.'));
152				}
153				elseif (!$discoveryObjectStatusValidator->validate($conditionValue)) {
154					$this->setError(_('Incorrect action condition discovery status.'));
155				}
156				break;
157
158			case CONDITION_TYPE_SUPPRESSED:
159				if (!zbx_empty($conditionValue)) {
160					$this->setError(_('Action condition value must be empty.'));
161				}
162				break;
163
164			case CONDITION_TYPE_TRIGGER_SEVERITY:
165				if (zbx_empty($conditionValue)) {
166					$this->setError(_('Empty action condition.'));
167				}
168				elseif (!$triggerSeverityValidator->validate($conditionValue)) {
169					$this->setError(_('Incorrect action condition trigger severity.'));
170				}
171				break;
172
173			case CONDITION_TYPE_EVENT_TYPE:
174				if (zbx_empty($conditionValue)) {
175					$this->setError(_('Empty action condition.'));
176				}
177				elseif (!$eventTypeValidator->validate($conditionValue)) {
178					$this->setError(_('Incorrect action condition event type.'));
179				}
180				break;
181
182			case CONDITION_TYPE_TRIGGER_NAME:
183			case CONDITION_TYPE_DUPTIME:
184			case CONDITION_TYPE_DVALUE:
185			case CONDITION_TYPE_APPLICATION:
186			case CONDITION_TYPE_HOST_NAME:
187			case CONDITION_TYPE_HOST_METADATA:
188			case CONDITION_TYPE_EVENT_TAG:
189				if (zbx_empty($conditionValue)) {
190					$this->setError(_('Empty action condition.'));
191				}
192				break;
193
194			case CONDITION_TYPE_EVENT_TAG_VALUE:
195				if (!is_string($condition['value']) || $condition['value'] === '' ||
196						!is_string($condition['value2']) || $condition['value2'] === '') {
197					$this->setError(_('Empty action condition.'));
198				}
199				break;
200
201			default:
202				$this->setError(_('Incorrect action condition type.'));
203		}
204
205		// If no error is not set, return true.
206		return !(bool) $this->getError();
207	}
208}
209