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 not to extend session lifetime in checkAuthentication. 28 */ 29 static $extend_session = true; 30 31 /** 32 * Disable automatic session extension. 33 */ 34 public static function disableSessionExtension() { 35 self::$extend_session = false; 36 } 37 38 /** 39 * Tries to login a user and populates self::$data on success. 40 * 41 * @param string $login user login 42 * @param string $password user password 43 * 44 * @throws Exception if user cannot be logged in 45 * 46 * @return bool 47 */ 48 public static function login(string $login, string $password): bool { 49 try { 50 self::$data = API::User()->login([ 51 'username' => $login, 52 'password' => $password, 53 'userData' => true 54 ]); 55 56 if (!self::$data) { 57 throw new Exception(); 58 } 59 60 API::getWrapper()->auth = self::$data['sessionid']; 61 62 if (self::$data['gui_access'] == GROUP_GUI_ACCESS_DISABLED) { 63 error(_('GUI access disabled.')); 64 throw new Exception(); 65 } 66 67 $result = (bool) self::$data; 68 69 if (isset(self::$data['attempt_failed']) && self::$data['attempt_failed']) { 70 CProfile::init(); 71 CProfile::update('web.login.attempt.failed', self::$data['attempt_failed'], PROFILE_TYPE_INT); 72 CProfile::update('web.login.attempt.ip', self::$data['attempt_ip'], PROFILE_TYPE_STR); 73 CProfile::update('web.login.attempt.clock', self::$data['attempt_clock'], PROFILE_TYPE_INT); 74 $result &= CProfile::flush(); 75 } 76 77 return $result; 78 } 79 catch (Exception $e) { 80 self::setDefault(); 81 return false; 82 } 83 } 84 85 /** 86 * Log-out the current user. 87 */ 88 public static function logout(): void { 89 if (API::User()->logout([])) { 90 self::$data = null; 91 session_destroy(); 92 } 93 } 94 95 public static function checkAuthentication(string $sessionid): bool { 96 try { 97 self::$data = API::User()->checkAuthentication([ 98 'sessionid' => $sessionid, 99 'extend' => self::$extend_session 100 ]); 101 102 if (empty(self::$data)) { 103 CMessageHelper::clear(); 104 self::$data = API::User()->login([ 105 'username' => ZBX_GUEST_USER, 106 'password' => '', 107 'userData' => true 108 ]); 109 110 if (empty(self::$data)) { 111 throw new Exception(); 112 } 113 } 114 115 if (self::$data['gui_access'] == GROUP_GUI_ACCESS_DISABLED) { 116 throw new Exception(); 117 } 118 119 return true; 120 } 121 catch (Exception $e) { 122 return false; 123 } 124 } 125 126 /** 127 * Checks access of authenticated user to specific access rule. 128 * 129 * @static 130 * 131 * @param string $rule_name Rule name. 132 * 133 * @return bool Returns true if user has access to specified rule, false - otherwise. 134 */ 135 public static function checkAccess(string $rule_name): bool { 136 if (empty(self::$data) || self::$data['roleid'] == 0) { 137 return false; 138 } 139 140 return CRoleHelper::checkAccess($rule_name, self::$data['roleid']); 141 } 142 143 /** 144 * Sets user data defaults. 145 * 146 * @static 147 */ 148 public static function setDefault(): void { 149 self::$data = [ 150 'sessionid' => CEncryptHelper::generateKey(), 151 'username' => ZBX_GUEST_USER, 152 'userid' => 0, 153 'lang' => CSettingsHelper::getGlobal(CSettingsHelper::DEFAULT_LANG), 154 'type' => 0, 155 'gui_access' => GROUP_GUI_ACCESS_SYSTEM, 156 'debug_mode' => false, 157 'roleid' => 0, 158 'autologin' => 0 159 ]; 160 } 161 162 /** 163 * Returns the type of the current user. 164 * 165 * @static 166 * 167 * @return int 168 */ 169 public static function getType() { 170 return self::$data ? self::$data['type'] : 0; 171 } 172 173 /** 174 * Returns true if debug mode is enabled. 175 * 176 * @return bool 177 */ 178 public static function getDebugMode() { 179 return (self::$data && self::$data['debug_mode']); 180 } 181 182 /** 183 * Returns true if the current user is logged in. 184 * 185 * @return bool 186 */ 187 public static function isLoggedIn() { 188 return (self::$data && self::$data['userid']); 189 } 190 191 /** 192 * Returns true if the user is not logged in or logged in as Guest. 193 * 194 * @return bool 195 */ 196 public static function isGuest() { 197 return (self::$data && self::$data['username'] == ZBX_GUEST_USER); 198 } 199 200 /** 201 * Return true if guest user has access to frontend. 202 * 203 * @return bool 204 */ 205 public static function isGuestAllowed() { 206 $guest = DB::select('users', [ 207 'output' => ['userid'], 208 'filter' => ['username' => ZBX_GUEST_USER] 209 ]); 210 211 return check_perm2system($guest[0]['userid']) 212 && getUserGuiAccess($guest[0]['userid']) != GROUP_GUI_ACCESS_DISABLED; 213 } 214 215 /** 216 * Returns refresh rate in seconds. 217 * 218 * @return int 219 */ 220 public static function getRefresh() { 221 return timeUnitToSeconds(self::$data['refresh']); 222 } 223 224 /** 225 * Returns interface language attribute value for HTML lang tag. 226 * 227 * @return string 228 */ 229 public static function getLang() { 230 return (self::$data) ? substr(self::$data['lang'], 0, strpos(self::$data['lang'], '_')) : 'en'; 231 } 232 233 /** 234 * Get user ip address. 235 * 236 * @return string 237 */ 238 public static function getIp(): string { 239 return (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER) && $_SERVER['HTTP_X_FORWARDED_FOR'] !== '') 240 ? $_SERVER['HTTP_X_FORWARDED_FOR'] 241 : $_SERVER['REMOTE_ADDR']; 242 } 243} 244