grthtrhthjhtyjytjytkergtrhtrjytjerhrfh4:24 29/09/2026 */ if (!defined('sugarEntry') || !sugarEntry) { die('Not A Valid Entry Point'); } /** * class GoogleApiKeySaverEntryPoint */ class GoogleApiKeySaverEntryPoint { /** * * @var User */ protected $currentUser; /** * * @var array */ protected $sugarConfig; /** * * @var Google_Client */ protected $client; /** * * @var array */ protected $request; /** * * @param User $current_user * @param array $sugar_config * @param Google_Client $client * @param array $request */ public function __construct(User $current_user, $sugar_config, Google_Client $client, $request) { $this->currentUser = $current_user; $this->sugarConfig = $sugar_config; $this->client = $client; $this->request = $request; $this->handleEntryPoint(); } /** * * @throws Exception 1 - google_auth_json requested variable is missing, 2 - Invalid json for auth config */ protected function handleEntryPoint() { $this->client->setApplicationName('SuiteCRM'); $this->client->setScopes(Google_Service_Calendar::CALENDAR); if (!isset($this->sugarConfig['google_auth_json'])) { throw new Exception('google_auth_json requested variable is missing', 1); } $json = base64_decode($this->sugarConfig['google_auth_json']); $config = json_decode($json, true); if (!$config) { throw new Exception('Invalid json for auth config', 2); } $this->validateConfig($config); $this->client->setAuthConfig($config); $this->client->setAccessType('offline'); $this->client->setApprovalPrompt('force'); $this->handleRequest(); } /** * * @param array $config * @throws Exception 2 - web is not set in the config json, 3 - client_id is not set in config json, 4 - client_secret is not set in config json */ protected function validateConfig($config) { if (!isset($config['web'])) { throw new Exception('web is not set in the config json', 2); } if (!isset($config['web']['client_id'])) { throw new Exception('client_id is not set in config json', 3); } if (!isset($config['web']['client_secret'])) { throw new Exception('client_secret is not set in config json', 4); } } /** * handle requested action handler method */ protected function handleRequest() { if (isset($this->request['getnew'])) { $this->handleRequestGetnew(); } elseif (isset($this->request['code'])) { $this->handleRequestCode(); } elseif (isset($this->request['setinvalid'])) { $this->handleRequestSetinvalid(); } elseif (isset($this->request['error'])) { $this->handleRequestError(); } else { $this->handleRequestUnknown(); } } /** * create and redirect to auth URL */ protected function handleRequestGetnew() { $authUrl = $this->client->createAuthUrl(); $this->redirect($authUrl); } /** * set google api token * * @throws Exception 1 - Unable to get User bean. 2 - Unable to retrive user by ID */ protected function handleRequestCode() { $user = BeanFactory::getBean('Users'); if (!$user) { throw new Exception('Unable to get User bean.', 1); } $ret = $user->retrieve($this->currentUser->id); if (!$ret) { throw new Exception('Unable to retrive user by ID: ' . $this->currentUser->id, 2); } $accessToken = $this->client->fetchAccessTokenWithAuthCode($this->request['code']); if (array_key_exists('error', $accessToken)) { throw new Exception('Unable to fetch access token: ' . $accessToken['error'] . '|' . $accessToken['error_description'], 10); } $user->setPreference('GoogleApiToken', base64_encode(json_encode($accessToken)), false, 'GoogleSync'); $accessRefreshToken = $accessToken['refresh_token']; if (isset($accessRefreshToken)) { $user->setPreference('GoogleApiRefreshToken', base64_encode($accessRefreshToken), false, 'GoogleSync'); } $user->savePreferencesToDB(); $url = $this->sugarConfig['site_url'] . "/index.php?module=Users&action=EditView&record=" . $this->currentUser->id; $this->redirect($url); } /** * set google api token to invalid * * @throws Exception 1 - Unable to get User bean. 2 - Unable to retrive user by ID */ protected function handleRequestSetinvalid() { $user = BeanFactory::getBean('Users'); if (!$user) { throw new Exception('Unable to get User bean.', 1); } $ret = $user->retrieve($this->currentUser->id); if (!$ret) { throw new Exception('Unable to retrive user by ID: ' . $this->currentUser->id, 2); } $user->setPreference('GoogleApiToken', '', false, 'GoogleSync'); $user->savePreferencesToDB(); $url = $this->sugarConfig['site_url'] . "/index.php?module=Users&action=EditView&record=" . $this->currentUser->id; $this->redirect($url); } /** * shows an error - pick error message from language file instead * using simple requested text as it is an XSS vulnerability issue */ protected function handleRequestError() { $url = $this->sugarConfig['site_url'] . "/index.php?module=Users&action=EditView&record=" . $this->currentUser->id; $tpl = new Sugar_Smarty(); $txtKey = $this->request['error']; $tpl->assign('error', LangText::get($txtKey)); $tpl->assign('url', $url); $exitstring = $tpl->fetch(__DIR__ . '/googleApiKeySaverEntryPointError.tpl'); $this->protectedDie($exitstring); } /** * redirect to user edit view if unknown function given. */ protected function handleRequestUnknown() { LoggerManager::getLogger()->error('Unkown entry point function given.'); // If we don't get a known return, we just silently return to the user profile. $url = $this->sugarConfig['site_url'] . "/index.php?module=Users&action=EditView&record=" . $this->currentUser->id; $this->redirect($url); } /** * protected function for SugarApplication::redirect() so test mock can override it * @param string $url */ protected function redirect($url) { SugarApplication::redirect($url); } /** * protected function for die() so test mock can override it * @param string $exitstring */ protected function protectedDie($exitstring) { die($exitstring); } }