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 CWebUser {
23
24	public static $data = null;
25
26	/**
27	 * Flag used to ignore setting authentication cookie performed checkAuthentication.
28	 */
29	static $set_cookie = true;
30
31	/**
32	 * Flag used to not to extend session lifetime in checkAuthentication.
33	 */
34	static $extend_session = true;
35
36	/**
37	 * Disable automatic cookie setting.
38	 * First checkAuthentication call (performed in initialization phase) will not be sending cookies.
39	 */
40	public static function disableSessionCookie() {
41		self::$set_cookie = false;
42	}
43
44	/**
45	 * Disable automatic session extension.
46	 */
47	public static function disableSessionExtension() {
48		self::$extend_session = false;
49	}
50
51	/**
52	 * Tries to login a user and populates self::$data on success.
53	 *
54	 * @param string $login			user login
55	 * @param string $password		user password
56	 *
57	 * @throws Exception if user cannot be logged in
58	 *
59	 * @return bool
60	 */
61	public static function login($login, $password) {
62		try {
63			self::setDefault();
64
65			self::$data = API::User()->login([
66				'user' => $login,
67				'password' => $password,
68				'userData' => true
69			]);
70
71			if (!self::$data) {
72				throw new Exception();
73			}
74
75			if (self::$data['gui_access'] == GROUP_GUI_ACCESS_DISABLED) {
76				error(_('GUI access disabled.'));
77				throw new Exception();
78			}
79
80			$result = (bool) self::$data;
81
82			if (isset(self::$data['attempt_failed']) && self::$data['attempt_failed']) {
83				CProfile::init();
84				CProfile::update('web.login.attempt.failed', self::$data['attempt_failed'], PROFILE_TYPE_INT);
85				CProfile::update('web.login.attempt.ip', self::$data['attempt_ip'], PROFILE_TYPE_STR);
86				CProfile::update('web.login.attempt.clock', self::$data['attempt_clock'], PROFILE_TYPE_INT);
87				$result &= CProfile::flush();
88			}
89
90			// remove guest session after successful login
91			$result &= DBexecute('DELETE FROM sessions WHERE sessionid='.zbx_dbstr(get_cookie(ZBX_SESSION_NAME)));
92
93			if ($result) {
94				self::setSessionCookie(self::$data['sessionid']);
95			}
96
97			return $result;
98		}
99		catch (Exception $e) {
100			self::setDefault();
101			return false;
102		}
103	}
104
105	/**
106	 * Log-out the current user.
107	 */
108	public static function logout() {
109		self::$data['sessionid'] = self::getSessionCookie();
110
111		if (API::User()->logout([])) {
112			self::$data = null;
113			CSession::destroy();
114			zbx_unsetcookie(ZBX_SESSION_NAME);
115		}
116	}
117
118	public static function checkAuthentication($sessionId) {
119		try {
120			if ($sessionId !== null) {
121				self::$data = API::User()->checkAuthentication([
122					'sessionid' => $sessionId,
123					'extend' => self::$extend_session
124				]);
125			}
126
127			if ($sessionId === null || empty(self::$data)) {
128				self::setDefault();
129				self::$data = API::User()->login([
130					'user' => ZBX_GUEST_USER,
131					'password' => '',
132					'userData' => true
133				]);
134
135				if (empty(self::$data)) {
136					clear_messages(1);
137					throw new Exception();
138				}
139				$sessionId = self::$data['sessionid'];
140			}
141
142			if (self::$data['gui_access'] == GROUP_GUI_ACCESS_DISABLED) {
143				throw new Exception();
144			}
145
146			if (self::$set_cookie) {
147				self::setSessionCookie($sessionId);
148			}
149			else {
150				self::$set_cookie = true;
151			}
152
153			return $sessionId;
154		}
155		catch (Exception $e) {
156			self::setDefault();
157			return false;
158		}
159	}
160
161	/**
162	 * Shorthand method for setting current session ID in cookies.
163	 *
164	 * @param string $sessionId		Session ID string
165	 */
166	public static function setSessionCookie($sessionId) {
167		$autoLogin = self::isGuest() ? false : (bool) self::$data['autologin'];
168
169		zbx_setcookie(ZBX_SESSION_NAME, $sessionId,  $autoLogin ? strtotime('+1 month') : 0);
170	}
171
172	/**
173	 * Retrieves current session ID from cookie named as defined in ZBX_SESSION_NAME.
174	 *
175	 * @return string
176	 */
177	public static function getSessionCookie() {
178		return get_cookie(ZBX_SESSION_NAME);
179	}
180
181	public static function setDefault() {
182		self::$data = [
183			'alias' => ZBX_GUEST_USER,
184			'userid' => 0,
185			'lang' => 'en_gb',
186			'type' => 0,
187			'debug_mode' => false
188		];
189	}
190
191	/**
192	 * Returns the type of the current user.
193	 *
194	 * @static
195	 *
196	 * @return int
197	 */
198	public static function getType() {
199		return self::$data ? self::$data['type'] : 0;
200	}
201
202	/**
203	 * Returns true if debug mode is enabled.
204	 *
205	 * @return bool
206	 */
207	public static function getDebugMode() {
208		return (self::$data && self::$data['debug_mode']);
209	}
210
211	/**
212	 * Returns true if the current user is logged in.
213	 *
214	 * @return bool
215	 */
216	public static function isLoggedIn() {
217		return (self::$data && self::$data['userid']);
218	}
219
220	/**
221	 * Returns true if the user is not logged in or logged in as Guest.
222	 *
223	 * @return bool
224	 */
225	public static function isGuest() {
226		return (self::$data && self::$data['alias'] == ZBX_GUEST_USER);
227	}
228
229	/**
230	 * Return true if guest user has access to frontend.
231	 *
232	 * @return bool
233	 */
234	public static function isGuestAllowed() {
235		$guest = DB::select('users', [
236			'output' => ['userid'],
237			'filter' => ['alias' => ZBX_GUEST_USER]
238		]);
239
240		return check_perm2system($guest[0]['userid'])
241			&& getUserGuiAccess($guest[0]['userid']) != GROUP_GUI_ACCESS_DISABLED;
242	}
243
244	/**
245	 * Returns refresh rate in seconds.
246	 *
247	 * @return int
248	 */
249	public static function getRefresh() {
250		return timeUnitToSeconds(self::$data['refresh']);
251	}
252
253	/**
254	 * Returns interface language attribute value for HTML lang tag.
255	 *
256	 * @return string
257	 */
258	public static function getLang() {
259		return (self::$data) ? substr(self::$data['lang'], 0, strpos(self::$data['lang'], '_')) : 'en';
260	}
261}
262