403Webshell
Server IP : 80.87.202.40  /  Your IP : 216.73.216.169
Web Server : Apache
System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64
User : bitrix ( 600)
PHP Version : 8.2.27
Disable Function : NONE
MySQL : OFF |  cURL : ON |  WGET : ON |  Perl : ON |  Python : OFF |  Sudo : ON |  Pkexec : ON
Directory :  /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/sproduction.datasync/lib/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/sproduction.datasync/lib/rest.php
<?php
/**
 *    Rest
 *
 * @mail support@s-production.online
 * @link s-production.online
 */

namespace SProduction\Datasync;

use Bitrix\Main,
    Bitrix\Main\DB\Exception,
    Bitrix\Main\Config\Option,
	SProduction\Datasync\Settings,
	Bitrix\Main\Application;

class Rest
{
    const MODULE_ID = 'sproduction.datasync';
	const BATCH_RESP_RESULT = 'result';
	const BATCH_RESP_ERRORS = 'result_error';
	protected static $MANUAL_RUN = false;
	protected static $STORE_EVENTS_BGR = true;
    static $site = false;
    static $portal = false;
    static $app_id = false;
    static $secret = false;

	/**
	 * Status of running events by asinchronous mode
	 */

	public static function disableStoreEventsBgrRun() {
		self::$STORE_EVENTS_BGR = false;
	}

	public static function isStoreEventsBgrRunEnabled() {
		//FileLog::put('(Rest::isStoreEventsBgrRunEnabled) status ' . (self::$STORE_EVENTS_BGR ? 'true' : 'false'));
		return self::$STORE_EVENTS_BGR;
	}

	/**
	 * Bulk run indicator
	 */

	public static function setBulkRun() {
		self::$MANUAL_RUN = true;
	}

	public static function isBulkRun() {
		return self::$MANUAL_RUN;
	}

	/**
	 * Get Bitrix24 application info
	 */

    public static function getAppInfo() {
		$info = false;
	    if (self::$site === false) {
		    self::$site = Settings::get("site");
	    }
	    if (self::$portal === false) {
		    self::$portal = Settings::get("portal");
	    }
	    if (self::$app_id === false) {
		    self::$app_id = Settings::get("app_id");
	    }
	    if (self::$secret === false) {
		    self::$secret = Settings::get("secret");
	    }
	    if (self::$site && self::$portal && self::$app_id && self::$secret) {
		    $info = [
		    	'site' => self::$site,
		    	'portal' => self::$portal,
		    	'app_id' => self::$app_id,
		    	'secret' => self::$secret,
		    ];
	    }
		return $info;
    }

	/**
	 * Save file with auth data
	 *
	 * @param $info
	 *
	 * @return bool|int
	 */

	public static function saveAuthInfo($info) {
		$res = Settings::save("credentials", $info, true);
		return $res;
	}

	/**
	 * Read auth data
	 *
	 * @return bool|mixed
	 */

	public static function getAuthInfo() {
		$info = Settings::get("credentials", true);
		return $info;
	}

	/**
	 * Get link for application authentication
	 *
	 * @return bool|string
	 */
	public static function getAuthLink() {
		$app_info = self::getAppInfo();
		if (!$app_info) {
			return false;
		}
		$link = $app_info['portal'].'/oauth/authorize/?client_id='.$app_info['app_id'].'&response_type=code';
		return $link;
	}

	/**
     * Get auth token
     */

	public static function restToken($code) {
	    $app_info = self::getAppInfo();
		FileLog::put('(Rest::restToken) code ' . $code);
        if (!$code || !$app_info) {
            return false;
        }

        $query_url = 'https://oauth.bitrix.info/oauth/token/';
        $query_data = http_build_query([
            'grant_type' => 'authorization_code',
            'client_id' => $app_info['app_id'],
            'client_secret' => $app_info['secret'],
            'code' => $code,
        ]);
		if (Settings::get('log_queries') == 'Y') {
			FileLog::put('(Rest::restToken) query ' . $query_url . '?' . $query_data, false);
		}
        $curl = curl_init();
		$curl_opts = [
			CURLOPT_HEADER => false,
			CURLOPT_RETURNTRANSFER => true,
			CURLOPT_URL => $query_url . '?' . $query_data,
		];
		$proxy = Proxy::getRandom();
		if ($proxy) {
			$curl_opts[CURLOPT_PROXYTYPE] = 'HTTP';
			$curl_opts[CURLOPT_PROXY] = $proxy['ip'];
			$curl_opts[CURLOPT_PROXYPORT] = $proxy['port'];
			if ($proxy['login'] && $proxy['password']) {
				$curl_opts[CURLOPT_PROXYUSERPWD] = $proxy['login'] . ':' . $proxy['password'];
			}
		}
		curl_setopt_array($curl, $curl_opts);
        $result = curl_exec($curl);
        curl_close($curl);
        $cred = json_decode($result, true);
		FileLog::put('(Rest::restToken) result ' . print_r($cred, true));

        if (!$cred['error']) {
            // Save new auth credentials
            self::saveAuthInfo($cred);
        }

        return $cred;
    }


    /**
     * Refresh access token
     *
     * @param array $refresh_token
     * @return bool|mixed
     */

	public static function refreshToken($refresh_token) {
    	$app_info = self::getAppInfo();
        if (!isset($refresh_token) || !$app_info) {
            return false;
        }

		RestLimits::control();

        $query_url = 'https://oauth.bitrix.info/oauth/token/';
        $query_data = http_build_query([
	        'grant_type' => 'refresh_token',
	        'client_id' => $app_info['app_id'],
	        'client_secret' => $app_info['secret'],
	        'refresh_token' => $refresh_token,
        ]);
		if (Settings::get('log_queries') == 'Y') {
			FileLog::put('(Rest::refreshToken) query ' . $query_url . '?' . $query_data, false);
		}
        $curl = curl_init();
		$curl_opts = [
			CURLOPT_HEADER => false,
			CURLOPT_RETURNTRANSFER => true,
			CURLOPT_URL => $query_url . '?' . $query_data,
		];
		$proxy = Proxy::getRandom();
		if ($proxy) {
			$curl_opts[CURLOPT_PROXYTYPE] = 'HTTP';
			$curl_opts[CURLOPT_PROXY] = $proxy['ip'];
			$curl_opts[CURLOPT_PROXYPORT] = $proxy['port'];
			if ($proxy['login'] && $proxy['password']) {
				$curl_opts[CURLOPT_PROXYUSERPWD] = $proxy['login'] . ':' . $proxy['password'];
			}
		}
		curl_setopt_array($curl, $curl_opts);
        $result = curl_exec($curl);
        curl_close($curl);
	    $resp = json_decode($result, true);

		if (isset($resp['error'])) {
			throw new Exception($resp['error_description'], $resp['error']);
		}

        return $resp;
    }


    /**
     * Send rest query to Bitrix24.
     *
     * @param $method - Rest method, ex: methods
     * @param array $params - Method params, ex: []
     * @param array $cred - Authorize data, ex: Array('domain' => 'https://test.bitrix24.com', 'access_token' => '7inpwszbuu8vnwr5jmabqa467rqur7u6')
     * @param boolean $auth_refresh - If authorize is expired, refresh token
     *
     * @return mixed
     */

    public static function execute($method, array $params = [], $cred = false, $auth_refresh = true, $only_res=true, $err_repeate=true, $force_cache = false) {
		// Get from cache
	    if (RestCache::hasValue($method, $params, $only_res)) {
		    FileLog::put('(Rest::execute) get method ' . $method . ' cache');
			return RestCache::get($method, $params, $only_res);
	    }
	    FileLog::put('(Rest::execute) execute method ' . $method);

	    $app_info = self::getAppInfo();
	    if (!$app_info) {
		    return false;
	    }
	    if (!$cred) {
		    $cred = self::getAuthInfo();
	    }

	    RestLimits::control();

	    // Command to the REST server
	    $access_token = $cred["access_token"] ?? '';
        $query_url = $app_info['portal'] . '/rest/' . $method;
        $query_data = http_build_query(array_merge($params, ['auth' => $access_token]));
		if (Settings::get('log_queries') == 'Y') {
			FileLog::put('(Rest::execute) query ' . $query_url . '?' . $query_data, false);
		}
        $curl = curl_init();
	    $curl_opts = [
		    CURLOPT_POST           => true,
		    CURLOPT_HEADER         => false,
		    CURLOPT_RETURNTRANSFER => true,
		    CURLOPT_SSL_VERIFYPEER => true,
		    CURLOPT_URL            => $query_url,
		    CURLOPT_POSTFIELDS     => $query_data,
	    ];
		$proxy = Proxy::getRandom();
		if ($proxy) {
			$curl_opts[CURLOPT_PROXYTYPE] = 'HTTP';
			$curl_opts[CURLOPT_PROXY] = $proxy['ip'];
			$curl_opts[CURLOPT_PROXYPORT] = $proxy['port'];
			if ($proxy['login'] && $proxy['password']) {
				$curl_opts[CURLOPT_PROXYUSERPWD] = $proxy['login'] . ':' . $proxy['password'];
			}
		}
	    curl_setopt_array($curl, $curl_opts);
        $result = curl_exec($curl);
        curl_close($curl);
        $resp = json_decode($result, true);

	    // Error to the log
	    if (isset($resp['error']) || isset($resp['error_description'])) {
		    FileLog::put('(Rest::execute) query "' . $method . '" error: ' . $resp['error_description'] . ' [' . $resp['error'] . ']');
		    // If token expired then refresh it
		    if (in_array($resp['error'], ['expired_token', 'invalid_token'])) {
			    if ($auth_refresh) {
			    	// Try to get new access token
				    $i = 0;
			    	do {
			    		if ($i > 0) {
			    			sleep(1);
					    }
					    try {
						    $cred = self::refreshToken($cred['refresh_token']);
					    } catch (\Exception $e) {
						    FileLog::put('(Rest::execute) query "' . $method . '" refresh token error: ' . $e->getMessage() . ' [' . $e->getCode() . ']');
					    }
					    $i++;
				    } while (!$cred["access_token"] && $i <= 3);
			    	if (is_array($cred)) {
					    foreach ($cred as $k => $value) {
						    $cred_log[$k] = mb_strimwidth($value, 0, 8, '***');
					    }
				    }
				    FileLog::put('(Rest::execute) query "' . $method . '" repeat result: ' . print_r($cred_log, true));
				    if ($cred["access_token"]) {
					    // Save new auth credentials
					    self::saveAuthInfo($cred);
					    // Execute again
					    $resp = self::execute($method, $params, $cred, false, false);
				    }
			    }
		    }
			// Access denied
		    elseif (in_array($resp['error'], ['200040300050'])) {}
		    // Other errors
		    else {
			    // Query limit
		        if (in_array($resp['error'], ['QUERY_LIMIT_EXCEEDED'])) {
					RestLimits::processQueryLimitError();
		        }
				if ($err_repeate) {
					$i = 0;
					while ((($resp['error'] ?? false) || ($resp['error_description'] ?? false)) && $i < 2) {
						usleep(500000);
						// Execute again
						try {
							$resp = self::execute($method, $params, $cred, $auth_refresh, false, false);
						}
						catch (\Exception $e) {
							FileLog::put('(Rest::execute) query "' . $method . '" repeat error: ' . $e->getMessage() . ' [' . $e->getCode() . ']');
						}
						$i++;
					}
				}
				// Return exception
			    if (($resp['error'] ?? false) || ($resp['error_description'] ?? false)) {
				    FileLog::put('(Rest::execute) query "' . $method . '" exception');
				    throw new Exception($resp['error_description'], $resp['error']);
			    }
		    }
	    }

        // Get results
        if ($only_res) {
	        $result = is_array($resp) ? $resp['result'] : false;
        }
        else {
	        $result = $resp;
        }

	    // Save cache
	    if (!isset($resp['error']) && !isset($resp['error_description'])) {
		    RestCache::add($method, $params, $only_res, $result, $force_cache);
	    }

		// Wakeup DB for long process
        if (self::isBulkRun()) {
	        self::updateDBConnection();
        }

        return $result;
    }

	public static function executeGetFlat($method, array $params = [], $cred = false) {
		FileLog::put('(Rest::executeGetFlat) method ' . $method);
		$app_info = self::getAppInfo();
		if ( ! $app_info) {
			return false;
		}
		if ( ! $cred) {
			$cred = self::getAuthInfo();
		}
		// Command to the REST server
		$query_url = $app_info['portal'] . '/rest/' . $method;
		$query_data = http_build_query(array_merge($params, ['auth' => $cred["access_token"]]));
		return $query_url . '?' . $query_data;
	}


	/**
	 * Batch request
	 */

	public static function batch(array $req_list, $cred = false, $force_cache = false) {
		$result = [];
		// Info for log
		$methods = [];
		foreach ($req_list as $item) {
			$methods[] = $item['method'];
		}
		FileLog::put('(Rest::batch) methods ' . implode(', ', $methods));
		if (!empty($req_list)) {
			$req_limit = 50;
			$req_count  = ceil(count($req_list) / $req_limit);
			for ($i = 0; $i < $req_count; $i ++) {
				$req_list_f = [];
				$j = 0;
				foreach ($req_list as $req_code => $req_item) {
					if ($j >= $i * $req_limit && $j < ($i + 1) * $req_limit) {
						// Prepare first request
						$k = $j - $i * $req_limit;
						if ($i > 0 && $k == 0) {
							if (isset($req_item['params']) && isset($req_item['params']['filter'])) {
								foreach ($req_item['params']['filter'] as $key => $value) {
									$res_value = '';
									$matches = [];
									preg_match('/(\$result)(\[\w*\])+/i', $value, $matches);
									if (!empty($matches)) {
										$res_request = $matches[0];
										$execute_string = $res_request;
										$execute_string = str_replace('$result', '$result[result]', $execute_string);
										$execute_string = '$res_value = ' . preg_replace('/\[(\w*\D\w*)\]/', '["$1"]', $execute_string) . ';';
										eval($execute_string);
										$req_item['params']['filter'][$key] = str_replace($res_request, $res_value, $value);
									}
								}
							}
						}
						// Add request to list
						$params = isset($req_item['params']) ? http_build_query($req_item['params']) : '';
						$req_list_f[$req_code] = $req_item['method'] . '?' . $params;
					}
					$j++;
				}
				if ( ! empty($req_list_f)) {
					$resp   = self::execute('batch', [
						"halt" => false,
						"cmd"  => $req_list_f,
					], $cred, true, true, true, $force_cache);
					if (is_array($resp)) {
						$result = array_merge_recursive($result, $resp ?? []);
					}
				}
			}
		}
		return $result;
	}


	/**
	 * Universal list
	 */

	public static function getList($method, $sub_array='', $params=[], $limit=0) {
		$list = [];
		$resp = self::execute($method, $params, false, true, false);
		$count = $resp['total'];
		if ($count) {
			$req_list = [];
			$req_count = ceil($count / 50);
			// List without counting
			if (isset($params['order']['id']) && $params['order']['id'] == 'asc') {
				$params['start'] = - 1;
				$params['count_total'] = 'N';
				for ($i = 0; $i < $req_count; $i ++) {
					$last_result = '$result[' . ($i - 1) . ']';
					if ($sub_array) {
						$last_result .= '[' . $sub_array . ']';
					}
					$last_result .= '[49][id]';
					$params['filter']['>id'] = $i ? $last_result : 0;
					$req_list[$i] = [
						'method' => $method,
						'params' => $params,
					];
				}
			} // List with counting
			else {
				for ($i=0; $i < $req_count; $i++) {
					$next = $i * 50;
					$params['start'] = $next;
					$req_list[$i] = [
						'method' => $method,
						'params' => $params,
					];
				}
			}
			$resp = self::batch($req_list);
			foreach ($resp[self::BATCH_RESP_RESULT] as $step_list) {
				if ($sub_array) {
					$step_list = $step_list[$sub_array];
				}
				if (is_array($step_list)) {
					foreach ($step_list as $item) {
						if ( ! $limit || $i < $limit) {
							$list[] = $item;
							$i ++;
						}
					}
				}
			}
		}
		return $list;
	}

	public static function getBgrRequestSecret() {
		$secret = Settings::get('bgr_request_secret');
		if (!$secret) {
			$secret = md5(time());
			Settings::save('bgr_request_secret', $secret);
		}
		return $secret;
	}

	/**
	 * Send request on background
	 */

	public static function sendBgrRequest($uri, $data) {
		$success = false;
		$data['secret_key'] = self::getBgrRequestSecret();
		$data['log_label'] = FileLog::getLabel();
		$app_info = self::getAppInfo();
		$site = $app_info['site'];
		$url_info = parse_url($site);
		$is_https = $url_info['scheme'] == 'https' ? true : false;
		$server = $url_info['host'];
		$query_url = ($is_https ? 'https://' : 'http://') . $server . $uri;
		$query_data = http_build_query($data);
//		FileLog::put('(Rest::sendBgrRequest) query ' . $query_url . '?' . $query_data);
		if ($server) {
			$try_limit = Settings::get('bgr_req_repeat_cnt') ? : 1;
			for ($i=1; $i<=$try_limit && !$success; $i++) {
				$curl = curl_init();
				$curl_opts = [
					CURLOPT_POST           => true,
					CURLOPT_HEADER         => false,
					CURLOPT_RETURNTRANSFER => true,
					CURLOPT_SSL_VERIFYPEER => false,
					CURLOPT_URL            => $query_url,
					CURLOPT_POSTFIELDS     => $query_data,
					CURLOPT_FRESH_CONNECT  => true,
				];
				if (self::isStoreEventsBgrRunEnabled()) {
					$timeout = (int)Settings::get('curl_bgr_timeout') ? : 5;
					$curl_opts[CURLOPT_TIMEOUT] = $timeout;
				}
				curl_setopt_array($curl, $curl_opts);
				curl_exec($curl);
				$info = curl_getinfo($curl);
				$success = ((int)$info['http_code'] < 300) && ($info['request_size'] > 0);
				FileLog::put('(Rest::sendBgrRequest) response ' . (! $success ? 'failure' : 'success'));
				if (!$success) {
					FileLog::put('(Rest::sendBgrRequest) info ' . print_r($info, true));
				}
				curl_close($curl);
			}
		}
		return $success;
	}

	public static function checkConnection() {
		$res = false;
		if (Rest::getAppInfo() && Rest::getAuthInfo()) {
			$res = true;
		}
		return $res;
	}

	public static function updateDBConnection() {
		$config = Application::getConnection()->getConfiguration();
		$link = mysqli_connect($config['host'], $config['login'], $config['password'], $config['database']);
		if ($link) {
			mysqli_close($link);
		}
	}

}

Youez - 2016 - github.com/yon3zu
LinuXploit