config->item('userdata'); // make sure these are the same as in Debug_model.php function migrate_userdata() $allowed_types = [ 'basedir', // special type to return the base user directory without the type subdirectory 'eqsl_card', 'qsl_card', 'qslpostcard_images' // has no legacy path ]; // validate path type if (!in_array($pathorurl, ['u', 'p', 'b'])) { log_message('error', 'Invalid pathorurl passed to getUserdataPath: ' . $pathorurl); return false; // invalid pathorurl } if (!in_array($type, $allowed_types)) { log_message('error', 'Invalid type passed to getUserdataPath: ' . $type); return false; // invalid type } if (isset($userdata_dir)) { if (!valid_uid($user_id)) { $user_id = $CI->session->userdata('user_id'); } // check if there is a user_id in the session data and it's not empty if (valid_uid($user_id)) { // create the folder (not for 'basedir', which is the user's base directory itself) if ($type != 'basedir' && !file_exists(realpath(APPPATH . '../') . '/' . $userdata_dir . '/' . $user_id . '/' . $type)) { mkdir(realpath(APPPATH . '../') . '/' . $userdata_dir . '/' . $user_id . '/' . $type, 0755, true); } // and return it if ($pathorurl == 'u') { return $userdata_dir . '/' . $user_id . '/' . $type; } else if ($pathorurl == 'p' && $type != 'basedir') { return realpath(APPPATH . '../') . '/' . $userdata_dir . '/' . $user_id . '/' . $type; } else if ($pathorurl == 'b' && $type == 'basedir') { return realpath(APPPATH . '../') . '/' . $userdata_dir . '/' . $user_id; } } else { log_message('info', 'getUserdataPath(); Can not get ' . $type . ' path because no user_id in session data'); } } else { // if the config option is not set we just return the old path return $this->legacyPaths($type, $pathorurl); } } /** * @deprecated Use getUserdataPath('eqsl_card') instead. * Kept as a fallback for the brief window during a git update where an * older view might still call this method before it gets removed. */ function getPathEqsl($pathorurl = 'u', $user_id = null) { return $this->getUserdataPath('eqsl_card', $pathorurl, $user_id); } /** * @deprecated Use getUserdataPath('qsl_card') instead. * Kept as a fallback for the brief window during a git update where an * older view might still call this method before it gets removed. */ function getPathQsl($pathorurl = 'u', $user_id = null) { return $this->getUserdataPath('qsl_card', $pathorurl, $user_id); } private function legacyPaths($type, $pathorurl = 'u') { switch ($type) { case 'eqsl_card': $path = 'images/eqsl_card_images'; break; case 'qsl_card': $path = 'assets/qslcard'; break; default: log_message('error', 'Invalid type passed to legacyPaths(): ' . $type); return false; } // 'u' returns the web-relative path, anything else the absolute filesystem path if ($pathorurl == 'u') { return $path; } else { return realpath(APPPATH . '../') . '/' . $path; } } function delete_user_files($user_id) { $CI = & get_instance(); if (!valid_uid($user_id)) { log_message('error', 'delete_user_files() called with invalid user_id: ' . $user_id); return false; } $userdata_dir = $CI->config->item('userdata'); if (isset($userdata_dir)) { $base_path = $this->getUserdataPath('basedir', 'b', $user_id); // get the base path for the user if (file_exists($base_path)) { if (!$this->_delete_directory($base_path)) { log_message('error', 'delete_user_files(); Failed to fully delete user files for user_id: ' . $user_id); return false; } log_message('debug', 'delete_user_files(); Deleted user files for user_id: ' . $user_id); } else { log_message('debug', 'delete_user_files(); No user files to delete for user_id: ' . $user_id); } } else { log_message('debug', 'delete_user_files(); No userdata directory configured, so no user files to delete for user_id: ' . $user_id); } return true; } private function _delete_directory($dir) { if (!file_exists($dir)) { return true; } if (!is_dir($dir)) { return unlink($dir); } foreach (scandir($dir) as $item) { if ($item == '.' || $item == '..') { continue; } if (!$this->_delete_directory($dir . DIRECTORY_SEPARATOR . $item)) { return false; } } return rmdir($dir); } function make_update_path($path) { $CI = & get_instance(); $path = "updates/" . $path; $datadir = $CI->config->item('datadir'); if(!$datadir) { return $path; } return $datadir . "/" . $path; } /** * Generate a CSRF token, store it in the session under $key, and return it * for injection into view data. */ function csrf_generate($key) { $CI = &get_instance(); $token = bin2hex(random_bytes(32)); $CI->session->set_userdata($key, $token); return $token; } /** * Verify the submitted csrf_token POST field against the session value for * $key. Rotates the token on success. Returns true on success, false on failure. */ function csrf_verify($key) { $CI = &get_instance(); $submitted = $CI->input->post('csrf_token', TRUE); $stored = $CI->session->userdata($key); if (empty($submitted) || empty($stored) || !hash_equals($stored, $submitted)) { return false; } $CI->session->set_userdata($key, bin2hex(random_bytes(32))); return true; } function cache_buster($filepath) { // make sure $filepath starts with a slash if (substr($filepath, 0, 1) !== '/') $filepath = '/' . $filepath; $CI = & get_instance(); $fullpath = empty($CI->config->item('directory')) ? $_SERVER['DOCUMENT_ROOT'] . $filepath : $_SERVER['DOCUMENT_ROOT'] . '/' . $CI->config->item('directory') . $filepath; // We comment out this line because latest teste at LA8AJA's XAMPP setup showed that it works even without it // So we will keep it simple and just use the $filepath as is, since it seems to work fine on both Linux and Windows setups // $fullpath = rtrim($_SERVER['DOCUMENT_ROOT'], '/\\') . str_replace('/', DIRECTORY_SEPARATOR, $filepath); // $filepath is always a hard-coded, app-relative asset path from callers // (never user input), so $fullpath is not attacker-controlled. if (file_exists($fullpath)) { // nosemgrep: php.lang.security.injection.tainted-filename.tainted-filename return base_url($filepath) . '?v=' . filemtime($fullpath); // nosemgrep: php.lang.security.injection.tainted-filename.tainted-filename } else { log_message('error', 'CACHE BUSTER: File does not exist: ' . $fullpath); } return base_url($filepath); } }