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	 * Disable automatic cookie setting.
33	 * First checkAuthentication call (performed in initialization phase) will not be sending cookies.
34	 */
35	public static function disableSessionCookie() {
36		self::$set_cookie = false;
37	}
38
39	/**
40	 * Tries to login a user and populates self::$data on success.
41	 *
42	 * @param string $login			user login
43	 * @param string $password		user password
44	 *
45	 * @throws Exception if user cannot be logged in
46	 *
47	 * @return bool
48	 */
49	public static function login($login, $password) {
50		try {
51			self::setDefault();
52
53			self::$data = API::User()->login([
54				'user' => $login,
55				'password' => $password,
56				'userData' => true
57			]);
58
59			if (!self::$data) {
60				throw new Exception();
61			}
62
63			if (self::$data['gui_access'] == GROUP_GUI_ACCESS_DISABLED) {
64				error(_('GUI access disabled.'));
65				throw new Exception();
66			}
67
68			$result = (bool) self::$data;
69
70			if (isset(self::$data['attempt_failed']) && self::$data['attempt_failed']) {
71				CProfile::init();
72				CProfile::update('web.login.attempt.failed', self::$data['attempt_failed'], PROFILE_TYPE_INT);
73				CProfile::update('web.login.attempt.ip', self::$data['attempt_ip'], PROFILE_TYPE_STR);
74				CProfile::update('web.login.attempt.clock', self::$data['attempt_clock'], PROFILE_TYPE_INT);
75				$result &= CProfile::flush();
76			}
77
78			// remove guest session after successful login
79			$result &= DBexecute('DELETE FROM sessions WHERE sessionid='.zbx_dbstr(get_cookie('zbx_sessionid')));
80
81			if ($result) {
82				self::setSessionCookie(self::$data['sessionid']);
83
84				add_audit_ext(AUDIT_ACTION_LOGIN, AUDIT_RESOURCE_USER, self::$data['userid'], '', null, null, null);
85			}
86
87			return $result;
88		}
89		catch (Exception $e) {
90			self::setDefault();
91			return false;
92		}
93	}
94
95	/**
96	 * Log-out the current user.
97	 */
98	public static function logout() {
99		self::$data['sessionid'] = self::getSessionCookie();
100		self::$data = API::User()->logout([]);
101		CSession::destroy();
102		zbx_unsetcookie('zbx_sessionid');
103	}
104
105	public static function checkAuthentication($sessionId) {
106		try {
107			if ($sessionId !== null) {
108				self::$data = API::User()->checkAuthentication([$sessionId]);
109			}
110
111			if ($sessionId === null || empty(self::$data)) {
112				self::setDefault();
113				self::$data = API::User()->login([
114					'user' => ZBX_GUEST_USER,
115					'password' => '',
116					'userData' => true
117				]);
118
119				if (empty(self::$data)) {
120					clear_messages(1);
121					throw new Exception();
122				}
123				$sessionId = self::$data['sessionid'];
124			}
125
126			if (self::$data['gui_access'] == GROUP_GUI_ACCESS_DISABLED) {
127				throw new Exception();
128			}
129
130			if (self::$set_cookie) {
131				self::setSessionCookie($sessionId);
132			}
133			else {
134				self::$set_cookie = true;
135			}
136
137			return $sessionId;
138		}
139		catch (Exception $e) {
140			self::setDefault();
141			return false;
142		}
143	}
144
145	/**
146	 * Shorthand method for setting current session ID in cookies.
147	 *
148	 * @param string $sessionId		Session ID string
149	 */
150	public static function setSessionCookie($sessionId) {
151		$autoLogin = self::isGuest() ? false : (bool) self::$data['autologin'];
152
153		zbx_setcookie('zbx_sessionid', $sessionId,  $autoLogin ? strtotime('+1 month') : 0);
154	}
155
156	/**
157	 * Retrieves current session ID from zbx_sessionid cookie.
158	 *
159	 * @return string
160	 */
161	public static function getSessionCookie() {
162		return get_cookie('zbx_sessionid');
163	}
164
165	public static function setDefault() {
166		self::$data = [
167			'alias' => ZBX_GUEST_USER,
168			'userid' => 0,
169			'lang' => 'en_gb',
170			'type' => '0',
171			'debug_mode' => false
172		];
173	}
174
175	/**
176	 * Returns the type of the current user.
177	 *
178	 * @static
179	 *
180	 * @return int
181	 */
182	public static function getType() {
183		return self::$data['type'];
184	}
185
186	/**
187	 * Returns true if debug mode is enabled.
188	 *
189	 * @return bool
190	 */
191	public static function getDebugMode() {
192		return (self::$data['debug_mode']);
193	}
194
195	/**
196	 * Returns true if the current user is logged in.
197	 *
198	 * @return bool
199	 */
200	public static function isLoggedIn() {
201		return (self::$data['userid']);
202	}
203
204	/**
205	 * Returns true if the user is not logged in or logged in as Guest.
206	 *
207	 * @return bool
208	 */
209	public static function isGuest() {
210		return (self::$data['alias'] == ZBX_GUEST_USER);
211	}
212}
213