From 73b3a01bc0470bf38ef80a552ca13d8f8e202bc6 Mon Sep 17 00:00:00 2001 From: Mike Koch Date: Thu, 10 Aug 2017 21:51:59 -0400 Subject: [PATCH] Version checks are now asynchronous --- admin/admin_settings.php | 299 ++++++------------ .../System/HeskVersionController.php | 56 ++++ api/index.php | 82 +++-- 3 files changed, 218 insertions(+), 219 deletions(-) create mode 100644 api/Controllers/System/HeskVersionController.php diff --git a/admin/admin_settings.php b/admin/admin_settings.php index 6f686d97..fcf24ec4 100644 --- a/admin/admin_settings.php +++ b/admin/admin_settings.php @@ -355,86 +355,121 @@ $modsForHesk_settings = mfh_getSettings(); : - - + - ' . $hesklang['hud'] . ' '; - } elseif ($latest != -1) { - // Is this a beta/dev version? - if (strpos($hesk_settings['hesk_version'], 'beta') || strpos($hesk_settings['hesk_version'], 'dev') || strpos($hesk_settings['hesk_version'], 'RC')) { - echo ' ' . $hesklang['beta'] . ' '; ?> ' . $hesklang['hnw'] . ' '; ?> - - + - + + + + + + + + + - + target="_blank"> + : - - + - ' . $hesklang['beta'] . ' '; ?> ' . $hesklang['mfh_up_to_date'] . ''; - } else { - ?> - - - + - + + + + + + + + - - + + @@ -3935,130 +3970,6 @@ $modsForHesk_settings = mfh_getSettings(); } - function hesk_checkVersion() - { - global $hesk_settings; - - if ($latest = hesk_getLatestVersion()) { - if (strlen($latest) > 12) { - return -1; - } elseif ($latest == $hesk_settings['hesk_version']) { - return true; - } else { - return $latest; - } - } else { - return -1; - } - - } // END hesk_checkVersion() - - - function hesk_getLatestVersion() - { - global $hesk_settings; - - // Do we have a cached version file? - if (file_exists(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest.txt')) { - if (preg_match('/^(\d+)\|([\d.]+)+$/', @file_get_contents(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest.txt'), $matches) && (time() - intval($matches[1])) < 3600) { - return $matches[2]; - } - } - - // No cached file or older than 3600 seconds, try to get an update - $hesk_version_url = 'https://hesk.com/version'; - - // Try using cURL - if (function_exists('curl_init')) { - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $hesk_version_url); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 6); - $latest = curl_exec($ch); - curl_close($ch); - return hesk_cacheLatestVersion($latest); - } - - // Try using a simple PHP function instead - if ($latest = @file_get_contents($hesk_version_url)) { - return hesk_cacheLatestVersion($latest); - } - - // Can't check automatically, will need a manual check - return false; - - } // END hesk_getLatestVersion() - - function hesk_cacheLatestVersion($latest) - { - global $hesk_settings; - - @file_put_contents(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest.txt', time() . '|' . $latest); - - return $latest; - - } // END hesk_cacheLatestVersion() - - function hesk_checkMfhVersion($currentVersion) - { - if ($latest = hesk_getMfhLatestVersion()) { - if (strlen($latest) > 12) { - return -1; - } elseif ($latest == $currentVersion) { - return true; - } else { - return $latest; - } - } else { - return -1; - } - } - - function hesk_getMfhLatestVersion() - { - global $hesk_settings; - - // Do we have a cached version file? - if (file_exists(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest-mfh.txt')) { - if (preg_match('/^(\d+)\|([\d.]+)+$/', @file_get_contents(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest-mfh.txt'), $matches) && (time() - intval($matches[1])) < 3600) { - return $matches[2]; - } - } - - // No cached file or older than 3600 seconds, try to get an update - $hesk_version_url = 'http://mods-for-hesk.mkochcs.com/latestversion.php'; - - // Try using cURL - if (function_exists('curl_init')) { - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $hesk_version_url); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 6); - $latest = curl_exec($ch); - curl_close($ch); - return hesk_cacheMfhLatestVersion($latest); - } - - // Try using a simple PHP function instead - if ($latest = file_get_contents($hesk_version_url)) { - return hesk_cacheMfhLatestVersion($latest); - } - - // Can't check automatically, will need a manual check - return false; - } - - function hesk_cacheMfhLatestVersion($latest) - { - global $hesk_settings; - - @file_put_contents(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest-mfh.txt', time() . '|' . $latest); - - return $latest; - - } - - function hesk_testLanguage($return_options = 0) { global $hesk_settings, $hesklang, $modsForHesk_settings; diff --git a/api/Controllers/System/HeskVersionController.php b/api/Controllers/System/HeskVersionController.php new file mode 100644 index 00000000..c07122ed --- /dev/null +++ b/api/Controllers/System/HeskVersionController.php @@ -0,0 +1,56 @@ + $matches[2])); + } + + // Try using cURL + if (function_exists('curl_init')) { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 6); + $latest = curl_exec($ch); + curl_close($ch); + + self::cacheLatestVersion($latest, $fileName, $hesk_settings); + + return output(array('version' => $latest)); + } + + // Try using a simple PHP function instead + if ($latest = @file_get_contents($url)) { + self::cacheLatestVersion($latest, $fileName, $hesk_settings); + + return output(array('version' => $latest)); + } + + // Can't check automatically, will need a manual check + return http_response_code(408); + } + + private static function cacheLatestVersion($latest, $fileName, $hesk_settings) { + @file_put_contents(__DIR__ . '/../../../' . $hesk_settings['cache_dir'] . '/' . $fileName, + time() . '|' . $latest); + } +} \ No newline at end of file diff --git a/api/index.php b/api/index.php index 672bbf8b..63879505 100644 --- a/api/index.php +++ b/api/index.php @@ -15,26 +15,37 @@ function handle404() { ), 404); } -function before() { - if (defined('HESK_DEMO') && $_SERVER['REQUEST_METHOD'] !== 'GET') { +function globalBefore() { + if (defined('HESK_DEMO') && $_SERVER['REQUEST_METHOD'] === 'GET') { print_error('Demo Mode', 'Only read-only commands are available in demo mode!', null, 401); die(); } +} + +function internalHandler() { + buildUserContextFromSession(); +} +function authTokenHandler() { + assertApiIsEnabled(); + $token = \BusinessLogic\Helpers::getHeader('X-AUTH-TOKEN'); + buildUserContext($token); +} + +function internalOrAuthHandler() { $internalUse = \BusinessLogic\Helpers::getHeader('X-INTERNAL-CALL'); if ($internalUse === 'true') { - buildUserContextFromSession(); - } elseif (preg_match('/\/v1\/tickets\/.+\/attachments\/\d+/', $_SERVER['PATH_INFO'])) { - //-- TODO Clean this up - return; + internalHandler(); } else { - assertApiIsEnabled(); - $token = \BusinessLogic\Helpers::getHeader('X-AUTH-TOKEN'); - buildUserContext($token); + authTokenHandler(); } } +function publicHandler() { + //-- No-op +} + function assertApiIsEnabled() { global $applicationContext, $hesk_settings; @@ -172,34 +183,55 @@ function fatalErrorShutdownHandler() { } } -Link::before('before'); +Link::before('globalBefore'); Link::all(array( // Categories - '/v1/categories' => [\Controllers\Categories\CategoryController::class . '::printAllCategories'], - '/v1/categories/{i}' => \Controllers\Categories\CategoryController::class, + '/v1/categories' => action(\Controllers\Categories\CategoryController::class . '::printAllCategories'), + '/v1/categories/{i}' => action(\Controllers\Categories\CategoryController::class), // Tickets - '/v1/tickets' => \Controllers\Tickets\CustomerTicketController::class, + '/v1/tickets' => action(\Controllers\Tickets\CustomerTicketController::class), // Tickets - Staff - '/v1/staff/tickets/{i}' => \Controllers\Tickets\StaffTicketController::class, + '/v1/staff/tickets/{i}' => action(\Controllers\Tickets\StaffTicketController::class), // Attachments - '/v1/tickets/{a}/attachments/{i}' => \Controllers\Attachments\PublicAttachmentController::class . '::getRaw', - '/v1/staff/tickets/{i}/attachments' => \Controllers\Attachments\StaffTicketAttachmentsController::class, - '/v1/staff/tickets/{i}/attachments/{i}' => \Controllers\Attachments\StaffTicketAttachmentsController::class, + '/v1/tickets/{a}/attachments/{i}' => action(\Controllers\Attachments\PublicAttachmentController::class . '::getRaw'), + '/v1/staff/tickets/{i}/attachments' => action(\Controllers\Attachments\StaffTicketAttachmentsController::class), + '/v1/staff/tickets/{i}/attachments/{i}' => action(\Controllers\Attachments\StaffTicketAttachmentsController::class), // Statuses - '/v1/statuses' => \Controllers\Statuses\StatusController::class, + '/v1/statuses' => action(\Controllers\Statuses\StatusController::class), // Settings - '/v1/settings' => \Controllers\Settings\SettingsController::class, + '/v1/settings' => action(\Controllers\Settings\SettingsController::class), /* Internal use only routes */ // Resend email response - '/v1-internal/staff/tickets/{i}/resend-email' => \Controllers\Tickets\ResendTicketEmailToCustomerController::class, + '/v1-internal/staff/tickets/{i}/resend-email' => + action(\Controllers\Tickets\ResendTicketEmailToCustomerController::class, SecurityHandler::INTERNAL), // Custom Navigation - '/v1-internal/custom-navigation/all' => \Controllers\Navigation\CustomNavElementController::class . '::getAll', - '/v1-internal/custom-navigation' => \Controllers\Navigation\CustomNavElementController::class, - '/v1-internal/custom-navigation/{i}' => \Controllers\Navigation\CustomNavElementController::class, - '/v1-internal/custom-navigation/{i}/sort/{s}' => \Controllers\Navigation\CustomNavElementController::class . '::sort', + '/v1-internal/custom-navigation/all' => + action(\Controllers\Navigation\CustomNavElementController::class . '::getAll', SecurityHandler::INTERNAL), + '/v1-internal/custom-navigation' => + action(\Controllers\Navigation\CustomNavElementController::class, SecurityHandler::INTERNAL), + '/v1-internal/custom-navigation/{i}' => + action(\Controllers\Navigation\CustomNavElementController::class, SecurityHandler::INTERNAL), + '/v1-internal/custom-navigation/{i}/sort/{s}' => + action(\Controllers\Navigation\CustomNavElementController::class . '::sort', SecurityHandler::INTERNAL), + + '/v1-public/hesk-version' => + action(\Controllers\System\HeskVersionController::class . '::getHeskVersion', SecurityHandler::OPEN), + '/v1-public/mods-for-hesk-version' => + action(\Controllers\System\HeskVersionController::class . '::getModsForHeskVersion', SecurityHandler::OPEN), // Any URL that doesn't match goes to the 404 handler '404' => 'handle404' -)); \ No newline at end of file +)); + +function action($class, $securityHandler = SecurityHandler::AUTH_TOKEN) { + return [$class, $class, $securityHandler]; +} + +class SecurityHandler { + const OPEN = 'publicHandler'; + const INTERNAL = 'internalHandler'; + const AUTH_TOKEN = 'authTokenHandler'; + const INTERNAL_OR_AUTH_TOKEN = 'internalOrAuthHandler'; +} \ No newline at end of file