%PDF- %PDF-
Direktori : /home/bitrix/www/bitrix/modules/rest/classes/general/ |
Current File : /home/bitrix/www/bitrix/modules/rest/classes/general/rest_provider.php |
<? use Bitrix\Main\ArgumentNullException; use Bitrix\Main\Config\Option; use Bitrix\Main\Entity; use Bitrix\Main\Loader; use Bitrix\Rest\RestException; use Bitrix\Rest\AccessException; use Bitrix\OAuth; class CRestProvider extends \IRestService { const ERROR_BATCH_LENGTH_EXCEEDED = 'ERROR_BATCH_LENGTH_EXCEEDED'; const ERROR_BATCH_METHOD_NOT_ALLOWED = 'ERROR_BATCH_METHOD_NOT_ALLOWED'; // default license shown instead of absent or unknown const LICENSE_DEFAULT = "project"; // controller group id => rest license id protected static $licenseList = array( "project" => "project", "corporation" => "corporation", "company" => "company", "team" => "team", "demo" => "demo", "nfr" => "nfr", "tf" => "tf", "crm" => "crm", ); protected static $arApp = null; protected static $arScope = null; protected static $arMethodsList = null; public function getDescription() { if(!is_array(self::$arMethodsList)) { $globalMethods = array( \CRestUtil::GLOBAL_SCOPE => array( 'batch' => array(__CLASS__, 'methodsBatch'), 'scope' => array(__CLASS__, 'scopeList'), 'methods' => array(__CLASS__, 'methodsList'), 'server.time' => array(__CLASS__, 'getServerTime'), ), ); $ownMethods = array( \CRestUtil::GLOBAL_SCOPE => array( 'app.option.get' => array(__CLASS__, 'appOptionGet'), 'app.option.set' => array(__CLASS__, 'appOptionSet'), 'user.option.get' => array(__CLASS__, 'userOptionGet'), 'user.option.set' => array(__CLASS__, 'userOptionSet'), \CRestUtil::EVENTS => array( 'OnAppUninstall' => array( 'rest', 'OnRestAppDelete', array(__CLASS__, 'OnAppEvent'), array( "sendAuth" => false, "category" => \Bitrix\Rest\Sqs::CATEGORY_IMPORTANT, ) ), 'OnAppInstall' => array( 'rest', 'OnRestAppInstall', array(__CLASS__, 'OnAppEvent'), array( "sendRefreshToken" => true, "category" => \Bitrix\Rest\Sqs::CATEGORY_IMPORTANT, ) ), 'OnAppUpdate' => array( 'rest', 'OnRestAppUpdate', array(__CLASS__, 'OnAppEvent'), array( "sendRefreshToken" => true, "category" => \Bitrix\Rest\Sqs::CATEGORY_IMPORTANT, ) ), 'OnAppPayment' => array( 'bitrix24', 'OnAfterAppPaid', array(__CLASS__, 'OnAppPayment'), array( "category" => \Bitrix\Rest\Sqs::CATEGORY_IMPORTANT, ) ), 'OnAppTest' => array( 'rest', 'OnRestAppTest', array(__CLASS__, 'OnAppEvent'), array( "sendRefreshToken" => true, ) ), 'OnAppMethodConfirm' => array( 'rest', 'OnRestAppMethodConfirm', array(__CLASS__, 'OnAppEvent'), array( "sendAuth" => false, "category" => \Bitrix\Rest\Sqs::CATEGORY_IMPORTANT, ) ), ), ), ); if(!\Bitrix\Main\ModuleManager::isModuleInstalled('oauth')) { $ownMethods[\CRestUtil::GLOBAL_SCOPE]['app.info'] = array(__CLASS__, 'appInfo'); } $arDescription = array(); foreach(GetModuleEvents("rest", "OnRestServiceBuildDescription", true) as $arEvent) { $res = ExecuteModuleEventEx($arEvent); if(is_array($res)) { $arDescription = array_merge_recursive($res, $arDescription); } } self::$arMethodsList = array_merge_recursive( $globalMethods, $ownMethods, $arDescription ); if(!array_key_exists('profile', self::$arMethodsList[\CRestUtil::GLOBAL_SCOPE])) { self::$arMethodsList[\CRestUtil::GLOBAL_SCOPE]['profile'] = array( 'callback' => array(__CLASS__, 'getProfile'), 'options' => array(), ); } array_change_key_case(self::$arMethodsList, CASE_LOWER); foreach(self::$arMethodsList as $scope => $arScopeMethods) { self::$arMethodsList[$scope] = array_change_key_case(self::$arMethodsList[$scope], CASE_LOWER); if( array_key_exists(\CRestUtil::EVENTS, self::$arMethodsList[$scope]) && is_array(self::$arMethodsList[$scope][\CRestUtil::EVENTS]) ) { self::$arMethodsList[$scope][\CRestUtil::EVENTS] = array_change_key_case(self::$arMethodsList[$scope][\CRestUtil::EVENTS], CASE_UPPER); } if( array_key_exists(\CRestUtil::PLACEMENTS, self::$arMethodsList[$scope]) && is_array(self::$arMethodsList[$scope][\CRestUtil::PLACEMENTS]) ) { self::$arMethodsList[$scope][\CRestUtil::PLACEMENTS] = array_change_key_case(self::$arMethodsList[$scope][\CRestUtil::PLACEMENTS], CASE_UPPER); } } } return self::$arMethodsList; } public static function getProfile($params, $n, \CRestServer $server) { global $USER; if(!$USER->isAuthorized()) { throw new \Bitrix\Rest\AccessException("User authorization required"); } $dbRes = CUser::getById($USER->getId()); $userInfo = $dbRes->fetch(); $result = array(); if($userInfo['ACTIVE'] == 'Y') { $result = array( 'ID' => $userInfo['ID'], 'ADMIN' => \CRestUtil::isAdmin(), 'NAME' => $userInfo['NAME'], 'LAST_NAME' => $userInfo['LAST_NAME'], 'PERSONAL_GENDER' => $userInfo['PERSONAL_GENDER'], ); if($userInfo['PERSONAL_PHOTO'] > 0) { $result['PERSONAL_PHOTO'] = \CRestUtil::GetFile($userInfo["PERSONAL_PHOTO"]); } $result['TIME_ZONE'] = $userInfo['TIME_ZONE']; $result['TIME_ZONE_OFFSET'] = $userInfo['TIME_ZONE_OFFSET'] + date('Z'); $securityState = array( "ID" => $result['ID'], "NAME" => $result['NAME'], "LAST_NAME" => $result['LAST_NAME'], ); $server->setSecurityState($securityState); } return $result; } public static function methodsBatch($arQuery, $start, \CRestServer $server) { $arQuery = array_change_key_case($arQuery, CASE_UPPER); $bHalt = (bool)$arQuery['HALT']; $arResult = array( 'result' => array(), 'next' => array(), 'total' => array(), 'time' => array(), 'error' => array(), ); if(isset($arQuery['CMD'])) { $cnt = 0; $authData = $server->getAuth(); foreach ($arQuery['CMD'] as $key => $call) { if(($cnt++) < \CRestUtil::BATCH_MAX_LENGTH) { $queryData = parse_url($call); $method = $queryData['path']; $query = $queryData['query']; $arParams = \CRestUtil::ParseBatchQuery($query, $arResult); if($method === \CRestUtil::METHOD_DOWNLOAD || $method === \CRestUtil::METHOD_UPLOAD) { $res = array('error' => self::ERROR_BATCH_METHOD_NOT_ALLOWED, 'error_description' => 'Method is not allowed for batch usage'); } else { if(is_array($authData)) { foreach($authData as $authParam => $authValue) { $arParams[$authParam] = $authValue; } } $pseudoServer = new \CRestServerBatchItem(array( 'CLASS' => __CLASS__, 'METHOD' => $method, 'QUERY' => $arParams )); $pseudoServer->setApplicationId($server->getClientId()); $pseudoServer->setAuthKeys(array_keys($authData)); $pseudoServer->setAuthData($server->getAuthData()); $pseudoServer->setAuthType($server->getAuthType()); $res = $pseudoServer->process(); unset($pseudoServer); } } else { $res = array('error' => self::ERROR_BATCH_LENGTH_EXCEEDED, 'error_description' => 'Max batch length exceeded'); } if(is_array($res)) { if(isset($res['error'])) { $res['error'] = $res; } foreach ($res as $k=>$v) { $arResult[$k][$key] = $v; } } if($res['error'] && $bHalt) { break; } } } return array( 'result' => $arResult['result'], 'result_error' => $arResult['error'], 'result_total' => $arResult['total'], 'result_next' => $arResult['next'], 'result_time' => $arResult['time'], ); } public static function scopeList($arQuery, $n, \CRestServer $server) { $arQuery = array_change_key_case($arQuery, CASE_UPPER); if($arQuery['FULL'] == true) { $arScope = \CRestUtil::getScopeList($server->getServiceDescription()); } else { $arScope = self::getScope($server); } return $arScope; } public static function methodsList($arQuery, $n, \CRestServer $server) { $arMethods = $server->getServiceDescription(); $arScope = array(\CRestUtil::GLOBAL_SCOPE); $arResult = array(); $arQuery = array_change_key_case($arQuery, CASE_UPPER); if(isset($arQuery['SCOPE'])) { if($arQuery['SCOPE'] != '') $arScope = array($arQuery['SCOPE']); } elseif($arQuery['FULL'] == true) { $arScope = array_keys($arMethods); } else { $arScope = self::getScope($server); $arScope[] = \CRestUtil::GLOBAL_SCOPE; } foreach ($arMethods as $scope => $arScopeMethods) { if(in_array($scope, $arScope)) { unset($arScopeMethods[\CRestUtil::METHOD_DOWNLOAD]); unset($arScopeMethods[\CRestUtil::METHOD_UPLOAD]); unset($arScopeMethods[\CRestUtil::EVENTS]); unset($arScopeMethods[\CRestUtil::PLACEMENTS]); foreach($arScopeMethods as $method => $methodDesc) { if(isset($methodDesc["options"]) && $methodDesc["options"]["private"] === true) { unset($arScopeMethods[$method]); } } $arResult = array_merge($arResult, array_keys($arScopeMethods)); } } return $arResult; } public static function appInfo($params, $n, \CRestServer $server) { if(\Bitrix\Main\ModuleManager::isModuleInstalled('bitrix24')) { $licenseInfo = COption::GetOptionString("main", "~controller_group_name"); list($lang, $licenseName, $additional) = explode("_", $licenseInfo, 3); if(!array_key_exists($licenseName, static::$licenseList)) { $licenseName = static::LICENSE_DEFAULT; } if(!$lang) { $lang = LANGUAGE_ID; } $license = $lang."_".static::$licenseList[$licenseName]; } else { $license = LANGUAGE_ID.'_selfhosted'; } if($server->getClientId()) { $arApp = self::getApp($server); $info = \Bitrix\Rest\AppTable::getAppStatusInfo($arApp, ''); $res = array( 'ID' => $arApp['ID'], 'CODE' => $arApp['CODE'], 'VERSION' => intval($arApp['VERSION']), 'STATUS' => $info['STATUS'], 'INSTALLED' => $arApp['INSTALLED'] == \Bitrix\Rest\AppTable::INSTALLED, 'PAYMENT_EXPIRED' => $info['PAYMENT_EXPIRED'], 'DAYS' => $info['DAYS_LEFT'], 'LICENSE' => $license, 'LANGUAGE_ID' => \CRestUtil::getLanguage(), ); $server->setSecurityState($res); } elseif($server->getPasswordId()) { $res = array( 'SCOPE' => static::getScope($server), 'LICENSE' => $license, ); } else { throw new AccessException("Application context required"); } foreach(GetModuleEvents('rest', 'OnRestAppInfo', true) as $event) { $eventData = ExecuteModuleEventEx($event, array($server, &$res)); if(is_array($eventData)) { if(!isset($res['ADDITIONAL'])) { $res['ADDITIONAL'] = array(); } $res['ADDITIONAL'] = array_merge($res['ADDITIONAL'], $eventData); } } return $res; } /** * Gets application option values * * @param array $params array([option => option_name]) * @param int $n Standard pagination param * @param CRestServer $server Standard Server object link * * @return array|mixed|null|string * * @throws AccessException * @throws ArgumentNullException * @throws \Bitrix\Main\ArgumentOutOfRangeException */ public static function appOptionGet($params, $n, \CRestServer $server) { global $USER; if(!$server->getClientId()) { throw new AccessException("Application context required"); } if(!$USER->IsAuthorized()) { throw new AccessException("User authorization required"); } $appOptions = Option::get("rest", "options_".$server->getClientId(), ""); if(strlen($appOptions) > 0) { $appOptions = unserialize($appOptions); } else { $appOptions = array(); } if(isset($params['option'])) { return isset($appOptions[$params['option']]) ? $appOptions[$params['option']] : null; } else { return $appOptions; } } /** * Sets application options values * * @param array $params array(option_name => option_value) || array(options => array(option_name => option_value,....)) * @param int $n Standard pagination param * @param CRestServer $server Standard Server object link * * @return true * * @throws AccessException * @throws ArgumentNullException * @throws \Bitrix\Main\ArgumentOutOfRangeException */ public static function appOptionSet($params, $n, \CRestServer $server) { if(!$server->getClientId()) { throw new AccessException("Application context required"); } if(!isset($params["options"])) { $params['options'] = $params; } if(count($params['options']) <= 0) { throw new ArgumentNullException('options'); } if(\CRestUtil::isAdmin()) { $appOptions = Option::get("rest", "options_".$server->getClientId(), ""); if(strlen($appOptions) > 0) { $appOptions = unserialize($appOptions); } else { $appOptions = array(); } foreach($params['options'] as $key => $value) { $appOptions[$key] = $value; } Option::set('rest', "options_".$server->getClientId(), serialize($appOptions)); } else { throw new AccessException("Administrator authorization required"); } return true; } /** * Gets user option values for application * * @param array $params array([option => option_name]) * @param int $n Standard pagination param * @param CRestServer $server Standard Server object link * * @return array|mixed|null|string * * @throws AccessException */ public static function userOptionGet($params, $n, \CRestServer $server) { global $USER; if(!$server->getClientId()) { throw new AccessException("Application context required"); } if(!$USER->IsAuthorized()) { throw new AccessException("User authorization required"); } $userOptions = \CUserOptions::GetOption("app_options", "options_".$server->getClientId(), array()); if(isset($params['option'])) { return isset($userOptions[$params['option']]) ? $userOptions[$params['option']] : null; } else { return $userOptions; } } /** * Sets user options values for application * * @param array $params array(option_name => option_value) || array(options => array(option_name => option_value,....)) * @param int $n Standard pagination param. * @param CRestServer $server Standard Server object link * * @return bool * * @throws AccessException * @throws ArgumentNullException */ public static function userOptionSet($params, $n, \CRestServer $server) { global $USER; if(!$server->getClientId()) { throw new AccessException("Application context required"); } if(!$USER->IsAuthorized()) { throw new AccessException("User authorization required"); } if(!isset($params["options"])) { $params['options'] = $params; } if(count($params['options']) <= 0) { throw new ArgumentNullException('options'); } $userOptions = \CUserOptions::GetOption("app_options", "options_".$server->getClientId(), array()); foreach($params['options'] as $key => $value) { $userOptions[$key] = $value; } \CUserOptions::SetOption("app_options", "options_".$server->getClientId(), $userOptions); return true; } public static function getServerTime($params) { return date('c', time()); } public static function OnAppEvent($arParams, $arHandler) { $arEventFields = $arParams[0]; if($arEventFields['APP_ID'] == $arHandler['APP_ID'] || $arEventFields['APP_ID'] == $arHandler['APP_CODE']) { $arEventFields["LANGUAGE_ID"] = \CRestUtil::getLanguage(); unset($arEventFields['APP_ID']); return $arEventFields; } else { throw new Exception('Wrong app!'); } } public static function OnAppPayment($arParams, $arHandler) { if($arParams[0] == $arHandler['APP_ID']) { $app = \Bitrix\Rest\AppTable::getByClientId($arHandler['APP_ID']); if($app) { $info = \Bitrix\Rest\AppTable::getAppStatusInfo($app, ''); return array( 'CODE' => $app['CODE'], 'VERSION' => intval($app['VERSION']), 'STATUS' => $info['STATUS'], 'PAYMENT_EXPIRED' => $info['PAYMENT_EXPIRED'], 'DAYS' => $info['DAYS_LEFT'] ); } } throw new Exception('Wrong app!'); } protected static function getApp(\CRestServer $server) { if(self::$arApp == null) { if(CModule::IncludeModule('oauth')) { $client = OAuth\Base::instance($server->getClientId()); if($client) { self::$arApp = $client->getClient(); if(is_array(self::$arApp) && is_array(self::$arApp['SCOPE'])) { self::$arApp['SCOPE'] = implode(',', self::$arApp['SCOPE']); } } } elseif($server->getClientId()) { self::$arApp = \Bitrix\Rest\AppTable::getByClientId($server->getClientId()); } else { throw new AccessException("Application context required"); } } return self::$arApp; } protected static function getScope(\CRestServer $server) { return $server->getAuthScope(); } } ?>