File manager - Edit - /home/kdmucyyv/semigocare.co.uk/wp-content/plugins/imunify-security/inc/App/DataStore.php
Back
<?php /** * Copyright (с) Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2025 All Rights Reserved * * Licensed under CLOUD LINUX LICENSE AGREEMENT * https://www.cloudlinux.com/legal/ */ namespace CloudLinux\Imunify\App; use CloudLinux\Imunify\App\Model\Feature; use CloudLinux\Imunify\App\Model\FeatureType; use CloudLinux\Imunify\App\Model\ScanData; use CloudLinux\Imunify\App\Exception\ApiException; /** * Data store implementation that uses PHP files. */ class DataStore { /** * Data directory name. */ const DIRECTORY = 'imunify-security'; /** * Scan data file name. */ const SCAN_DATA_FILE = 'scan_data.php'; /** * Authentication file name. */ const AUTH_FILE = 'auth.php'; /** * Transient key prefix for error throttling. */ const ERROR_THROTTLE_PREFIX = 'imunify_security_error_'; /** * API host. */ const API_HOST = '127.0.0.1'; /** * API port. */ const API_PORT = 11234; /** * API endpoint path. */ const API_ENDPOINT = '/api/v1/rpc'; /** * API timeout in seconds. */ const API_TIMEOUT = 30; /** * Scan data. * * @var ScanData|null */ private $scanData = null; /** * Data directory location. Default is WP_CONTENT_DIR. * * @var string */ private $dataDirectoryLocation = ''; /** * Constructor. */ public function __construct() { $this->dataDirectoryLocation = WP_CONTENT_DIR; } /** * Checks if scan data file is available. * * @return bool */ public function isDataAvailable() { return $this->isDataFileAvailable( self::SCAN_DATA_FILE ); } /** * Checks if data file is available. * * @param string $filename The name of the file. * * @return bool */ public function isDataFileAvailable( $filename ) { $filepath = $this->getDataFilePath( $filename ); return file_exists( $filepath ) && is_readable( $filepath ); } /** * Changes data directory and clears the data to make sure it's reloaded when requested again. * * @param string $directory The new directory. * * @return void */ public function changeDataDirectory( $directory ) { $this->dataDirectoryLocation = $directory; $this->scanData = null; } /** * Get the base directory path for data files * * @return string */ private function getDataDirectory() { return $this->dataDirectoryLocation . DIRECTORY_SEPARATOR . self::DIRECTORY; } /** * Get the full path to a data file * * @param string $filename The name of the file. * * @return string */ private function getDataFilePath( $filename ) { return trailingslashit( $this->getDataDirectory() ) . $filename; } /** * Retrieves the scan data. * * If not already loaded, it will load it from the file. * * @return ScanData|null */ public function getScanData() { if ( ! $this->scanData ) { $rawData = $this->load( self::SCAN_DATA_FILE ); if ( ! $rawData ) { return null; } $this->scanData = ScanData::fromArray( $rawData ); } return $this->scanData; } /** * Get list of features. * * @return \CloudLinux\Imunify\App\Model\Feature[] */ public function getFeatures() { $scanData = $this->getScanData(); $config = $scanData ? $scanData->getConfig() : array(); return array( Feature::fromType( FeatureType::MALWARE_SCANNING, $config ), Feature::fromType( FeatureType::MALWARE_CLEANUP, $config ), Feature::fromType( FeatureType::PROACTIVE_DEFENCE, $config ), ); } /** * Loads data from given file. * * @param string $filename The name of the file. * * @return array|null */ private function load( $filename ) { if ( ! $this->isDataFileAvailable( $filename ) ) { return null; } $filepath = $this->getDataFilePath( $filename ); /** * PHP is able to catch parsing errors since version 7.0. This is a workaround that allows to catch parsing * errors if supported while keeping compatibility with PHP 5.6 that does not support Throwable. */ if ( interface_exists( 'Throwable' ) ) { try { $rawData = include $filepath; return $this->processRawDataFromFile( $rawData, $filepath ); } catch ( \Throwable $t ) { $this->processFileLoadingError( $filename, $t ); return null; } } else { try { $rawData = include $filepath; return $this->processRawDataFromFile( $rawData, $filepath ); } catch ( \Exception $e ) { $this->processFileLoadingError( $filename, $e ); return null; } } } /** * Processes the raw data from the file. * This method is used to convert the raw data into a ScanData object. * If the data is not valid, it will log an error and return null. * * @param mixed $rawData The raw data from the file. * @param string $filepath The path to the file. * * @return array|null */ private function processRawDataFromFile( $rawData, $filepath ) { if ( ! is_array( $rawData ) ) { do_action( 'imunify_security_set_error', E_WARNING, 'File scan_data.php returned unexpected data', __FILE__, __LINE__, array( 'file' => $filepath, 'data' => var_export( $rawData, true ), // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_var_export ) ); return null; } return $rawData; } /** * Processes the error that occurred while loading data from a file. * * @param string $filename The name of the file. * @param \Throwable|\Exception $e The exception. * * @return void */ private function processFileLoadingError( $filename, $e ) { $this->handleError( $filename . ' file loading failed with error ' . $e->getMessage(), 'file_loading_failed', array( 'file' => $filename, 'error_type' => get_class( $e ), ), false ); } /** * Handles errors by logging them with a unique identifier. * Errors are throttled to once per hour per error code. * Optionally throws an ApiException. * * @param string $message The error message. * @param string $errorCode The unique error identifier. * @param array $context Additional context data. * @param bool $throwException Whether to throw an ApiException. Default true. * * @return void * @throws ApiException When $throwException is true. * * @since 2.0.0 */ public function handleError( $message, $errorCode, $context = array(), $throwException = true ) { $transientKey = self::ERROR_THROTTLE_PREFIX . $errorCode; // Check if this error was already reported in the last hour. if ( ! get_transient( $transientKey ) ) { // Set transient to prevent this error from being reported again for an hour. set_transient( $transientKey, true, HOUR_IN_SECONDS ); do_action( 'imunify_security_set_error', E_WARNING, $message, __FILE__, __LINE__, array( 'fingerprint' => array( $errorCode ), 'context' => $context, ) ); } if ( $throwException ) { throw new ApiException( $message, $errorCode ); } } /** * Load authentication token from the auth file. * * @return string|null The token or null if not found. */ private function loadCredentials() { if ( ! $this->isDataFileAvailable( self::AUTH_FILE ) ) { return null; } $auth = $this->load( self::AUTH_FILE ); if ( ! $auth || ! isset( $auth['token'] ) ) { return null; } return $auth['token']; } /** * Load data for the given commands and params. * * @param array $commands List of agent commands. * @param array $params List of parameters. * * @return array * @throws ApiException When the API request fails. */ public function loadData( $commands, $params ) { $token = $this->loadCredentials(); if ( ! $token ) { $this->handleError( 'Failed to load API credentials', 'api_credentials_load_failed' ); } // Remove the JWT token from the params if it exists. It is passed in headers. if ( isset( $params['jwt'] ) ) { unset( $params['jwt'] ); } $requestData = array( 'command' => $commands, 'params' => empty( $params ) ? new \stdClass() : $params, // Use stdClass for empty params to avoid JSON encoding issues. ); $apiUrl = $this->getApiUrl(); $response = wp_remote_post( $apiUrl, array( 'headers' => array( 'Authorization' => 'Bearer ' . $token, 'Content-Type' => 'application/json', ), 'body' => \wp_json_encode( $requestData ), 'timeout' => self::API_TIMEOUT, ) ); if ( is_wp_error( $response ) ) { $this->handleError( 'API request failed: ' . $response->get_error_message(), 'api_request_failed', array( 'error' => $response->get_error_message() ) ); } $httpCode = wp_remote_retrieve_response_code( $response ); if ( 200 !== $httpCode ) { $this->handleError( 'API request failed with status code: ' . $httpCode, 'api_request_status_error', array( 'status_code' => $httpCode ) ); } $body = wp_remote_retrieve_body( $response ); $data = json_decode( $body, true ); if ( json_last_error() !== JSON_ERROR_NONE ) { $this->handleError( 'Failed to parse API response: ' . json_last_error_msg(), 'api_response_parse_error', array( 'error' => json_last_error_msg() ) ); } // Check that the response contains the expected structure (messages and result). if ( ! isset( $data['messages'] ) || ! isset( $data['result'] ) ) { $this->handleError( 'Invalid API response structure', 'api_response_structure_error', array( 'response' => $data, 'commands' => $commands, 'params' => $params, ) ); } if ( ! isset( $data['data'] ) ) { $data['data'] = array(); } $command = implode( ' ', $commands ); if ( 'permissions list' === $command ) { $data['items'][] = 'upgrade_button'; } // Update versioning information to include the WordPress plugin version. if ( 'get-package-versions' === $command ) { if ( isset( $data['data']['items'] ) && is_array( $data['data']['items'] ) ) { $data['data']['items']['imunify-wp-plugin'] = IMUNIFY_SECURITY_VERSION; } } // Inject missing license data to the response from scan data. if ( array_key_exists( 'license', $data['data'] ) && is_array( $data['data']['license'] ) ) { $scanData = $this->getScanData(); if ( $scanData ) { $license = $this->getScanData()->getLicense(); if ( ! empty( $license ) ) { $data['data']['license'] = array_merge( $license, $data['data']['license'] ); } } } return $data; } /** * Get the username from the data. * * The username is retrieved from the scan data. * * @return string Username. */ public function getUsername() { $scanData = $this->getScanData(); if ( $scanData ) { return $scanData->getUsername(); } return ''; } /** * Get the API URL. * * This method constructs the API URL based on the defined constants or defaults. * * @return string The API URL. * * @since 2.0.0 */ private function getApiUrl() { if ( defined( 'IMUNIFY_SECURITY_API_URL' ) && ! empty( IMUNIFY_SECURITY_API_URL ) ) { return IMUNIFY_SECURITY_API_URL; } return sprintf( 'http://%s:%d%s', self::API_HOST, self::API_PORT, self::API_ENDPOINT ); } }
| ver. 1.4 |
Github
|
.
| PHP 8.3.30 | Generation time: 0 |
proxy
|
phpinfo
|
Settings