/** * Validate the provided session information is correct and current. Load the session. * * @param String $session_id -- The session ID that was returned by a call to login. * @return true -- If the session is valid and loaded. * @return false -- if the session is not valid. */ function validate_authenticated($session_id) { Log::info('Begin: SoapHelperWebServices->validate_authenticated'); if (!empty($session_id)) { // only initialize session once in case this method is called multiple times if (!session_id()) { session_id($session_id); session_start(); } if (!empty($_SESSION['is_valid_session']) && $this->is_valid_ip_address('ip_address') && $_SESSION['type'] == 'user') { global $current_user; require_once 'modules/Users/User.php'; $current_user = new User(); $current_user->retrieve($_SESSION['user_id']); $this->login_success(); Log::info('Begin: SoapHelperWebServices->validate_authenticated - passed'); Log::info('End: SoapHelperWebServices->validate_authenticated'); return true; } Log::debug("calling destroy"); session_destroy(); } LogicHook::instance()->call_custom_logic('Users', 'login_failed'); Log::info('End: SoapHelperWebServices->validate_authenticated - validation failed'); return false; }
/** * Log the user into the application * * @param UserAuth array $user_auth -- Set user_name and password (password needs to be * in the right encoding for the type of authentication the user is setup for. For Base * sugar validation, password is the MD5 sum of the plain text password. * @param String $application -- The name of the application you are logging in from. (Currently unused). * @param array $name_value_list -- Array of name value pair of extra parameters. As of today only 'language' and 'notifyonsave' is supported * @return Array - id - String id is the session_id of the session that was created. * - module_name - String - module name of user * - name_value_list - Array - The name value pair of user_id, user_name, user_language, user_currency_id, user_currency_name, * - user_default_team_id, user_is_admin, user_default_dateformat, user_default_timeformat * @exception 'SoapFault' -- The SOAP error, if any */ public function login($user_auth, $application, $name_value_list = array()) { Log::info('Begin: SugarWebServiceImpl->login'); global $sugar_config, $system_config; $error = new SoapError(); $user = new User(); $success = false; //rrs $system_config = new Administration(); $system_config->retrieveSettings('system'); $authController = new AuthenticationController(); //rrs if (!empty($user_auth['encryption']) && $user_auth['encryption'] === 'PLAIN' && $authController->authController->userAuthenticateClass != "LDAPAuthenticateUser") { $user_auth['password'] = md5($user_auth['password']); } $isLoginSuccess = $authController->login($user_auth['user_name'], $user_auth['password'], array('passwordEncrypted' => true)); $usr_id = $user->retrieve_user_id($user_auth['user_name']); if ($usr_id) { $user->retrieve($usr_id); } if ($isLoginSuccess) { if ($_SESSION['hasExpiredPassword'] == '1') { $error->set_error('password_expired'); Log::fatal('password expired for user ' . $user_auth['user_name']); LogicHook::instance()->call_custom_logic('Users', 'login_failed'); self::$helperObject->setFaultObject($error); return; } if (!empty($user) && !empty($user->id) && !$user->is_group) { $success = true; global $current_user; $current_user = $user; } } else { if ($usr_id && isset($user->user_name) && $user->getPreference('lockout') == '1') { $error->set_error('lockout_reached'); Log::fatal('Lockout reached for user ' . $user_auth['user_name']); LogicHook::instance()->call_custom_logic('Users', 'login_failed'); self::$helperObject->setFaultObject($error); return; } else { if ($authController->authController->userAuthenticateClass == "LDAPAuthenticateUser" && (empty($user_auth['encryption']) || $user_auth['encryption'] !== 'PLAIN')) { $error->set_error('ldap_error'); LogicHook::instance()->call_custom_logic('Users', 'login_failed'); self::$helperObject->setFaultObject($error); return; } else { if (function_exists('mcrypt_cbc')) { $password = self::$helperObject->decrypt_string($user_auth['password']); if ($authController->login($user_auth['user_name'], $password) && isset($_SESSION['authenticated_user_id'])) { $success = true; } } } } } if ($success) { session_start(); global $current_user; //$current_user = $user; self::$helperObject->login_success($name_value_list); $current_user->loadPreferences(); $_SESSION['is_valid_session'] = true; $_SESSION['ip_address'] = query_client_ip(); $_SESSION['user_id'] = $current_user->id; $_SESSION['type'] = 'user'; $_SESSION['avail_modules'] = self::$helperObject->get_user_module_list($current_user); $_SESSION['authenticated_user_id'] = $current_user->id; $_SESSION['unique_key'] = $sugar_config['unique_key']; $current_user->call_custom_logic('after_login'); Log::info('End: SugarWebServiceImpl->login - succesful login'); $nameValueArray = array(); global $current_language; $nameValueArray['user_id'] = self::$helperObject->get_name_value('user_id', $current_user->id); $nameValueArray['user_name'] = self::$helperObject->get_name_value('user_name', $current_user->user_name); $nameValueArray['user_language'] = self::$helperObject->get_name_value('user_language', $current_language); $cur_id = $current_user->getPreference('currency'); $nameValueArray['user_currency_id'] = self::$helperObject->get_name_value('user_currency_id', $cur_id); $nameValueArray['user_is_admin'] = self::$helperObject->get_name_value('user_is_admin', is_admin($current_user)); $nameValueArray['user_default_team_id'] = self::$helperObject->get_name_value('user_default_team_id', $current_user->default_team); $nameValueArray['user_default_dateformat'] = self::$helperObject->get_name_value('user_default_dateformat', $current_user->getPreference('datef')); $nameValueArray['user_default_timeformat'] = self::$helperObject->get_name_value('user_default_timeformat', $current_user->getPreference('timef')); $num_grp_sep = $current_user->getPreference('num_grp_sep'); $dec_sep = $current_user->getPreference('dec_sep'); $nameValueArray['user_number_seperator'] = self::$helperObject->get_name_value('user_number_seperator', empty($num_grp_sep) ? $sugar_config['default_number_grouping_seperator'] : $num_grp_sep); $nameValueArray['user_decimal_seperator'] = self::$helperObject->get_name_value('user_decimal_seperator', empty($dec_sep) ? $sugar_config['default_decimal_seperator'] : $dec_sep); $nameValueArray['mobile_max_list_entries'] = self::$helperObject->get_name_value('mobile_max_list_entries', $sugar_config['wl_list_max_entries_per_page']); $nameValueArray['mobile_max_subpanel_entries'] = self::$helperObject->get_name_value('mobile_max_subpanel_entries', $sugar_config['wl_list_max_entries_per_subpanel']); $currencyObject = new Currency(); $currencyObject->retrieve($cur_id); $nameValueArray['user_currency_name'] = self::$helperObject->get_name_value('user_currency_name', $currencyObject->name); $_SESSION['user_language'] = $current_language; return array('id' => session_id(), 'module_name' => 'Users', 'name_value_list' => $nameValueArray); } LogicHook::instance()->call_custom_logic('Users', 'login_failed'); $error->set_error('invalid_login'); self::$helperObject->setFaultObject($error); Log::info('End: SugarWebServiceImpl->login - failed login'); }
/** * Handle exception * * @param Exception $e */ protected function handleException(Exception $e) { $logicHook = LogicHook::instance(); $dir = ''; Log::fatal("Exception in Controller: [{$e->getMessage()}]:[File: {$e->getFile()}:{$e->getLine()}]"); if (isset($this->bean)) { $logicHook->setBean($this->bean); $dir = $this->bean->module_dir; } LogicHook::instance(); $logicHook->call_custom_logic($dir, "handle_exception", $e); }
if (!empty($_COOKIE['PHPSESSID']) && strcmp($_GET['PHPSESSID'], $_COOKIE['PHPSESSID']) == 0) { session_id($_REQUEST['PHPSESSID']); } else { unset($_GET['PHPSESSID']); } } if (!empty($sugar_config['session_dir'])) { session_save_path($sugar_config['session_dir']); } SugarApplication::preLoadLanguages(); $timedate = TimeDate::getInstance(); $GLOBALS['sugar_version'] = $sugar_version; $GLOBALS['sugar_flavor'] = $sugar_flavor; $GLOBALS['timedate'] = $timedate; $GLOBALS['js_version_key'] = md5($GLOBALS['sugar_config']['unique_key'] . $GLOBALS['sugar_version'] . $GLOBALS['sugar_flavor']); $db = DBManagerFactory::getInstance(); $db->resetQueryCount(); $locale = new Localization(); // Emails uses the REQUEST_URI later to construct dynamic URLs. // IIS does not pass this field to prevent an error, if it is not set, we will assign it to ''. if (!isset($_SERVER['REQUEST_URI'])) { $_SERVER['REQUEST_URI'] = ''; } $current_user = new User(); $current_entity = null; $system_config = new Administration(); $system_config->retrieveSettings(); LogicHook::instance()->call_custom_logic('core', 'after_entry_point'); } //// END SETTING DEFAULT VAR VALUES ///////////////////////////////////////////////////////////////////////////////
/** * Called when a user requests to logout. Should invalidate the session and redirect * to the login page. */ public function logout() { $GLOBALS['current_user']->call_custom_logic('before_logout'); $this->authController->logout(); LogicHook::instance()->call_custom_logic('Users', 'after_logout'); }
/** * Trigger custom logic for this module that is defined for the provided hook * The custom logic file is located under custom/modules/[CURRENT_MODULE]/logic_hooks.php. * That file should define the $hook_version that should be used. * It should also define the $hook_array. The $hook_array will be a two dimensional array * the first dimension is the name of the event, the second dimension is the information needed * to fire the hook. Each entry in the top level array should be defined on a single line to make it * easier to automatically replace this file. There should be no contents of this file that are not replacable. * * $hook_array['before_save'][] = Array(1, testtype, 'custom/modules/Leads/test12.php', 'TestClass', * 'lead_before_save_1'); This sample line creates a before_save hook. The hooks are procesed in the order in * which they are added to the array. The second dimension is an array of: processing index (for sorting before * exporting the array) A logic type hook label/type php file to include php class the method is in php method to * call * * The method signature for version 1 hooks is: * function NAME(&$bean, $event, $arguments) * $bean - $this bean passed in by reference. * $event - The string for the current event (i.e. before_save) * $arguments - An array of arguments that are specific to the event. * * @param string $event * @param array|null $arguments */ function call_custom_logic($event, $arguments = null) { if (!isset($this->processed) || $this->processed == false) { //add some logic to ensure we do not get into an infinite loop if (!empty($this->logicHookDepth[$event])) { if ($this->logicHookDepth[$event] > $this->max_logic_depth) { return; } } else { $this->logicHookDepth[$event] = 0; } //we have to put the increment operator here //otherwise we may never increase the depth for that event in the case //where one event will trigger another as in the case of before_save and after_save //Also keeping the depth per event allow any number of hooks to be called on the bean //and we only will return if one event gets caught in a loop. We do not increment globally //for each event called. $this->logicHookDepth[$event]++; LogicHook::instance($this)->call_custom_logic($this->module_dir, $event, $arguments); $this->logicHookDepth[$event]--; } }
/** * This method will be called from the controller and is not meant to be overridden. */ public function process() { $this->_checkModule(); //trackView has to be here in order to track for breadcrumbs $this->_trackView(); //For the ajaxUI, we need to use output buffering to return the page in an ajax friendly format if ($this->_getOption('json_output')) { ob_start(); if (!empty($_REQUEST['ajax_load']) && !empty($_REQUEST['loadLanguageJS'])) { echo $this->_getModLanguageJS(); } } if ($this->_getOption('show_header')) { $this->displayHeader(); } else { $this->renderJavascript(); } $this->_buildModuleList(); $this->preDisplay(); $this->displayErrors(); $this->display(); LogicHook::instance()->call_custom_logic($this->module, 'after_ui_frame'); // We have to update jsAlerts as soon as possible if (!isset($_SESSION['isMobile']) && ($this instanceof ViewList || $this instanceof ViewDetail || $this instanceof ViewEdit)) { $jsAlerts = new jsAlerts(); echo $jsAlerts->getScript(); } if ($this->_getOption('show_subpanels') && !empty($_REQUEST['record'])) { $this->_displaySubPanels(); } if ($this->action === 'Login') { //this is needed for a faster loading login page ie won't render unless the tables are closed ob_flush(); } if ($this->_getOption('show_footer')) { $this->displayFooter(); } LogicHook::instance()->call_custom_logic('core', 'after_ui_footer'); if ($this->_getOption('json_output')) { $content = ob_get_clean(); $module = $this->module; $ajax_ret = ['content' => mb_detect_encoding($content) == "UTF-8" ? $content : utf8_encode($content), 'menu' => ['module' => $module, 'label' => translate($module), $this->getMenu($module)], 'title' => $this->getBrowserTitle(), 'action' => isset($_REQUEST['action']) ? $_REQUEST['action'] : "", 'record' => isset($_REQUEST['record']) ? $_REQUEST['record'] : "", 'favicon' => $this->getFavicon()]; if (SugarThemeRegistry::current()->name == 'Classic') { $ajax_ret['moduleList'] = $this->displayHeader(true); } if (empty($this->responseTime)) { $this->_calculateFooterMetrics(); } $ajax_ret['responseTime'] = $this->responseTime; $json = getJSONobj(); echo $json->encode($ajax_ret); $GLOBALS['app']->headerDisplayed = false; ob_flush(); } //Do not track if there is no module or if module is not a String $this->_track(); }
/** * Log out of the session. This will destroy the session and prevent other's from using it. * * @param String $session -- Session ID returned by a previous call to login. * @return Empty * @exception 'SoapFault' -- The SOAP error, if any */ function logout($session) { global $current_user; Log::info('Begin: SugarWebServiceImpl->logout'); $error = new SoapError(); if (!self::$helperObject->checkSessionAndModuleAccess($session, 'invalid_session', '', '', '', $error)) { LogicHook::instance()->call_custom_logic('Users', 'after_logout'); Log::info('End: SugarWebServiceImpl->logout'); return; } // if $current_user->call_custom_logic('before_logout'); session_destroy(); LogicHook::instance()->call_custom_logic('Users', 'after_logout'); Log::info('End: SugarWebServiceImpl->logout'); }
* Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License version 3, * these Appropriate Legal Notices must retain the display of the "Powered by * SugarCRM" logo. If the display of the logo is not reasonably feasible for * technical reasons, the Appropriate Legal Notices must display the words * "Powered by SugarCRM". ********************************************************************************/ /********************************************************************************* * Description: TODO: To be written. * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc. * All Rights Reserved. * Contributor(s): ______________________________________.. ********************************************************************************/ // record the last theme the user used $current_user->setPreference('lastTheme', $theme); $GLOBALS['current_user']->call_custom_logic('before_logout'); // submitted by Tim Scott from SugarCRM forums foreach ($_SESSION as $key => $val) { $_SESSION[$key] = ''; // cannot just overwrite session data, causes segfaults in some versions of PHP } if (isset($_COOKIE[session_name()])) { setcookie(session_name(), '', time() - 42000, '/'); } //Update the tracker_sessions table // clear out the authenticating flag session_destroy(); LogicHook::instance()->call_custom_logic('Users', 'after_logout'); /** @var AuthenticationController $authController */ $authController->authController->logout();
function startSession() { $sessionIdCookie = isset($_COOKIE['PHPSESSID']) ? $_COOKIE['PHPSESSID'] : null; if (isset($_REQUEST['MSID'])) { session_id($_REQUEST['MSID']); session_start(); if (!isset($_SESSION['user_id'])) { if (isset($_COOKIE['PHPSESSID'])) { self::setCookie('PHPSESSID', '', time() - 42000, '/'); } sugar_cleanup(false); session_destroy(); exit('Not a valid entry method'); } } else { if (can_start_session()) { session_start(); } } //set the default module to either Home or specified default $default_module = !empty($GLOBALS['sugar_config']['default_module']) ? $GLOBALS['sugar_config']['default_module'] : 'Home'; //set session expired message if login module and action are set to a non login default //AND session id in cookie is set but super global session array is empty if (isset($_REQUEST['login_module']) && isset($_REQUEST['login_action']) && !($_REQUEST['login_module'] == $default_module && $_REQUEST['login_action'] == 'index')) { if (!is_null($sessionIdCookie) && empty($_SESSION)) { self::setCookie('loginErrorMessage', 'LBL_SESSION_EXPIRED', time() + 30, '/'); } } LogicHook::instance()->call_custom_logic('core', 'after_session_start'); }
/** * Log out of the session. This will destroy the session and prevent other's from using it. * * @param String $session -- Session ID returned by a previous call to login. * @return Empty error on success, Error on failure */ function logout($session) { global $current_user; $error = new SoapError(); if (validate_authenticated($session)) { $current_user->call_custom_logic('before_logout'); session_destroy(); LogicHook::instance()->call_custom_logic('Users', 'after_logout'); return $error->get_soap_array(); } $error->set_error('no_session'); LogicHook::instance()->call_custom_logic('Users', 'after_logout'); return $error->get_soap_array(); }
function sugar_cleanup($exit = false) { static $called = false; if ($called) { return; } $called = true; set_include_path(realpath(dirname(__FILE__) . '/..') . PATH_SEPARATOR . get_include_path()); chdir(realpath(dirname(__FILE__) . '/..')); global $sugar_config; LogicHook::instance()->call_custom_logic('core', 'server_round_trip'); //added this check to avoid errors during install. if (empty($sugar_config['dbconfig'])) { if ($exit) { exit; } else { return; } } if (!class_exists('Tracker', true)) { require_once 'modules/Trackers/Tracker.php'; } Tracker::logPage(); // Now write the cached tracker_queries if (!empty($GLOBALS['savePreferencesToDB']) && $GLOBALS['savePreferencesToDB']) { if (isset($GLOBALS['current_user']) && $GLOBALS['current_user'] instanceof User) { $GLOBALS['current_user']->savePreferencesToDB(); } } //check to see if this is not an `ajax call AND the user preference error flag is set if (isset($_SESSION['USER_PREFRENCE_ERRORS']) && $_SESSION['USER_PREFRENCE_ERRORS'] && ($_REQUEST['action'] != 'modulelistmenu' && $_REQUEST['action'] != 'DynamicAction') && ($_REQUEST['action'] != 'favorites' && $_REQUEST['action'] != 'DynamicAction') && (empty($_REQUEST['to_pdf']) || !$_REQUEST['to_pdf']) && (empty($_REQUEST['sugar_body_only']) || !$_REQUEST['sugar_body_only'])) { global $app_strings; //this is not an ajax call and the user preference error flag is set, so reset the flag and print js to flash message $err_mess = $app_strings['ERROR_USER_PREFS']; $_SESSION['USER_PREFRENCE_ERRORS'] = false; echo "\n\t\t<script>\n\t\t\tajaxStatus.flashStatus('{$err_mess}',7000);\n\t\t</script>"; } pre_login_check(); if (class_exists('DBManagerFactory')) { $db = DBManagerFactory::getInstance(); $db->disconnect(); if ($exit) { exit; } } }