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
22abstract class CController {
23
24	const VALIDATION_OK = 0;
25	const VALIDATION_ERROR = 1;
26	const VALIDATION_FATAL_ERROR = 2;
27
28	/**
29	 * Action name, so that controller knows what action he is executing.
30	 *
31	 * @var string
32	 */
33	private $action;
34
35	/**
36	 * Response oject generated by controller.
37	 *
38	 * @var string
39	 */
40	private $response;
41
42	/**
43	 * Result of input validation, one of VALIDATION_OK, VALIDATION_ERROR, VALIDATION_FATAL_ERROR.
44	 *
45	 * @var string
46	 */
47	private $validationResult;
48
49	/**
50	 * Input parameters retrieved from global $_REQUEST after validation.
51	 *
52	 * @var string
53	 */
54	public $input = [];
55
56	/**
57	 * SID validation flag, if true SID must be validated.
58	 *
59	 * @var bool
60	 */
61	private $validateSID = true;
62
63	public function __construct() {
64		CSession::start();
65		$this->init();
66	}
67
68	/**
69	 * Initialization function that can be overridden later.
70	 *
71	 * @return var
72	 */
73	protected function init() {
74	}
75
76	/**
77	 * Set controller action name.
78	 *
79	 * @return var
80	 */
81	public function setAction($action) {
82		$this->action = $action;
83	}
84
85	/**
86	 * Set controller response.
87	 *
88	 * @return var
89	 */
90	public function setResponse($response) {
91		$this->response = $response;
92	}
93
94	/**
95	 * Return controller response object.
96	 *
97	 * @return var
98	 */
99	public function getResponse() {
100		return $this->response;
101	}
102
103	/**
104	 * Return controller action name.
105	 *
106	 * @return var
107	 */
108	public function getAction() {
109		return $this->action;
110	}
111
112	/**
113	 * Return debug mode.
114	 *
115	 * @return var
116	 */
117	public function getDebugMode() {
118		return CWebUser::getDebugMode();
119	}
120
121	/**
122	 * Return user type.
123	 *
124	 * @return var
125	 */
126	public function getUserType() {
127		return CWebUser::getType();
128	}
129
130	/**
131	 * Return user SID, first 16 bytes of session ID.
132	 *
133	 * @return var
134	 */
135	public function getUserSID() {
136		$sessionid = CWebUser::getSessionCookie();
137
138		if ($sessionid === null || strlen($sessionid) < 16) {
139			return null;
140		}
141
142		return substr($sessionid, 16, 16);
143	}
144
145	/**
146	 * Validate input parameters.
147	 *
148	 * @return var
149	 */
150	public function validateInput($validationRules) {
151		if (CSession::keyExists('formData')) {
152			$input = array_merge($_REQUEST, CSession::getValue('formData'));
153			CSession::unsetValue(['formData']);
154		}
155		else {
156			$input = $_REQUEST;
157		}
158
159		$validator = new CNewValidator($input, $validationRules);
160
161		foreach ($validator->getAllErrors() as $error) {
162			info($error);
163		}
164
165		if ($validator->isErrorFatal()) {
166			$this->validationResult = self::VALIDATION_FATAL_ERROR;
167		}
168		else if ($validator->isError()) {
169			$this->input = $validator->getValidInput();
170			$this->validationResult = self::VALIDATION_ERROR;
171		}
172		else {
173			$this->input = $validator->getValidInput();
174			$this->validationResult = self::VALIDATION_OK;
175		}
176
177		return ($this->validationResult == self::VALIDATION_OK);
178	}
179
180	/**
181	 * Return validation result.
182	 *
183	 * @return var
184	 */
185	public function getValidationError() {
186		return $this->validationResult;
187	}
188
189	/**
190	 * Check if input parameter exists.
191	 *
192	 * @return var
193	 */
194	public function hasInput($var) {
195		return array_key_exists($var, $this->input);
196	}
197
198	/**
199	 * Get single input parameter.
200	 *
201	 * @return var
202	 */
203	public function getInput($var, $default = null) {
204		if ($default === null) {
205			return $this->input[$var];
206		}
207		else {
208			return array_key_exists($var, $this->input) ? $this->input[$var] : $default;
209		}
210	}
211
212	/**
213	 * Get several input parameters.
214	 *
215	 * @return var
216	 */
217	public function getInputs(&$var, $names) {
218		foreach ($names as $name) {
219			if ($this->hasInput($name)) {
220				$var[$name] = $this->getInput($name);
221			}
222		}
223	}
224
225	/**
226	 * Return all input parameters.
227	 *
228	 * @return var
229	 */
230	public function getInputAll() {
231		return $this->input;
232	}
233
234	/**
235	 * Check user permissions.
236	 *
237	 * @abstract
238	 *
239	 * @return var
240	 */
241	abstract protected function checkPermissions();
242
243	/**
244	 * Validate input parameters.
245	 *
246	 * @abstract
247	 *
248	 * @return var
249	 */
250	abstract protected function checkInput();
251
252	/**
253	 * Validate session ID (SID).
254	 *
255	 * @return var
256	 */
257	public function disableSIDvalidation() {
258		$this->validateSID = false;
259	}
260
261	/**
262	 * Validate session ID (SID).
263	 *
264	 * @return var
265	 */
266	protected function checkSID() {
267		$sessionid = CWebUser::getSessionCookie();
268
269		if ($sessionid === null || !isset($_REQUEST['sid'])) {
270			return false;
271		}
272
273		return ($_REQUEST['sid'] === substr($sessionid, 16, 16));
274	}
275
276	/**
277	 * Execute action and generate response object.
278	 *
279	 * @abstract
280	 *
281	 * @return var
282	 */
283	abstract protected function doAction();
284
285	/**
286	 * Main controller processing routine. Returns response object: data, redirect or fatal redirect.
287	 *
288	 * @return var
289	 */
290	final public function run() {
291		if ($this->validateSID && !$this->checkSID()) {
292			access_deny(ACCESS_DENY_PAGE);
293		}
294
295		if ($this->checkInput()) {
296			if ($this->checkPermissions() !== true) {
297				access_deny(ACCESS_DENY_PAGE);
298			}
299			$this->doAction();
300		}
301
302		if (CProfile::isModified()) {
303			DBstart();
304			$result = CProfile::flush();
305			DBend($result);
306		}
307
308		return $this->getResponse();
309	}
310}
311