1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
googleproxy.php
См. документацию.
1<?php
2
7use Bitrix\SocialServices\UserTable;
9
10
12{
13 public const PROXY_CONST = 'BITRIX';
17 private $user;
18
23 public static function isProxyAuth(): bool
24 {
25 return !\Bitrix\Main\Loader::includeModule('bitrix24')
26 && (\Bitrix\Main\Config\Option::get('socialservices', 'google_sync_proxy', 'N') === 'Y');
27 }
28
29 public function Authorize()
30 {
31 global $APPLICATION;
32 $APPLICATION->RestartBuffer();
33
34 $bSuccess = false;
35 $addParams = false;
36
37 $authError = SOCSERV_AUTHORISATION_ERROR;
38
39 $state = $this->parseState($_REQUEST['state']);
40
41 if(!empty($_REQUEST["code"]) && $this->checkUserToken($state['user_token']))
42 {
43 $this->getEntityOAuth()->setCode($_REQUEST["code"]);
44
45 unset($_REQUEST["state"]);
46
47 if($this->getEntityOAuth()->GetAccessToken() !== false)
48 {
49 $arGoogleUser = $this->getEntityOAuth()->GetCurrentUser();
50
51 if(is_array($arGoogleUser) && !isset($arGoogleUser["error"]))
52 {
53 $arFields = $this->prepareUser($arGoogleUser);
54 $arFields['USER_ID'] = $this->user->getId();
55 $authError = $this->AuthorizeUser($arFields);
56 }
57 }
58 }
59
60 $aRemove = ["logout", "auth_service_error", "auth_service_id", "code", "error_reason", "error", "error_description", "check_key", "current_fieldset"];
61 $mode = null;
62
63 if($this->user && ($authError === true))
64 {
65 $bSuccess = true;
67
68 $url = ($APPLICATION->GetCurDir() === "/login/") ? "" : $APPLICATION->GetCurDir();
69 $mode = 'opener';
70 $addParams = true;
71 if(isset($state) && is_array($state))
72 {
73 if(isset($state['backurl']) || isset($state['redirect_url']))
74 {
75 $url = !empty($state['redirect_url']) ? $state['redirect_url'] : $state['backurl'];
76 if(!str_starts_with($url, "#"))
77 {
78 $parseUrl = parse_url($url);
79
80 $urlPath = $parseUrl["path"];
81 $arUrlQuery = explode('&', $parseUrl["query"]);
82
83 foreach($arUrlQuery as $key => $value)
84 {
85 foreach($aRemove as $param)
86 {
87 if(str_starts_with($value, $param . "="))
88 {
89 unset($arUrlQuery[$key]);
90 break;
91 }
92 }
93 }
94
95 $url = (!empty($arUrlQuery)) ? $urlPath . '?' . implode("&", $arUrlQuery) : $urlPath;
96 }
97 else
98 {
99 $addParams = false;
100 }
101 }
102
103 if(isset($state['mode']))
104 {
105 $mode = $state['mode'];
106 }
107 }
108 }
109
110 if($authError === SOCSERV_REGISTRATION_DENY)
111 {
112 $url = (preg_match("/\?/", $url)) ? $url.'&' : $url.'?';
113 $url .= 'auth_service_id='.static::ID.'&auth_service_error='.SOCSERV_REGISTRATION_DENY;
114 }
115 elseif($bSuccess !== true)
116 {
117 $url = (isset($urlPath)) ? $urlPath.'?auth_service_id='.static::ID.'&auth_service_error='.$authError : $APPLICATION->GetCurPageParam(('auth_service_id='.static::ID.'&auth_service_error='.$authError), $aRemove);
118 }
119
120 if($addParams && CModule::IncludeModule("socialnetwork") && !str_contains($url, "current_fieldset="))
121 {
122 $url = (preg_match("/\?/", $url)) ? $url."&current_fieldset=SOCSERV" : $url."?current_fieldset=SOCSERV";
123 }
124
125 $url = CUtil::JSEscape($url);
126
127 if ($bSuccess && $mode === self::MOBILE_MODE)
128 {
129 $this->onAfterMobileAuth();
130 }
131 else
132 {
133 $this->onAfterWebAuth($addParams, $mode, $url);
134 }
135
136 CMain::FinalActions();
137 }
138
139 public function getUrl($location = 'opener', $addScope = null, $arParams = array())
140 {
141 if(IsModuleInstalled('bitrix24') && defined('BX24_HOST_NAME'))
142 {
143 return '';
144 }
145
146 $this->entityOAuth = $this->getEntityOAuth();
147
148 if($this->userId === null)
149 {
150 $this->entityOAuth->setRefreshToken("skip");
151 }
152
153 if($addScope !== null)
154 {
155 $this->entityOAuth->addScope($addScope);
156 }
157
158 $state = 'provider='.static::ID
159 . '&site_id=' . SITE_ID
160 . '&backurl=' . urlencode(
161 $GLOBALS["APPLICATION"]
162 ->GetCurPageParam(
163 'check_key=' . \CSocServAuthManager::getUniqueKey(),
164 ["logout", "auth_service_error", "auth_service_id", "backurl", 'serviceName', 'hitHash']
165 )
166 )
167 . '&mode=' . $location
168 . (isset($arParams['BACKURL'])
169 ? '&redirect_url=' . urlencode($arParams['BACKURL'])
170 : '')
171 . '&user_token=' . urlencode($this->generateUserToken())
172 . '&hostUrl=' . urlencode(\Bitrix\Main\Engine\UrlManager::getInstance()->getHostUrl())
173 ;
174
175 $redirect_uri = $this->getEntityOAuth()->getRedirectUri();
176
177 return $this->entityOAuth->GetAuthUrl($redirect_uri, $state, $arParams['APIKEY']);
178 }
179
184 public function getEntityOAuth($code = false)
185 {
186 if(!($this->entityOAuth instanceof CGoogleProxyOAuthInterface))
187 {
188 $this->entityOAuth = new CGoogleProxyOAuthInterface();
189 }
190
191 if($code !== false)
192 {
193 $this->entityOAuth->setCode($code);
194 }
195
196 return $this->entityOAuth;
197 }
198
204 private function generateUserToken(): string
205 {
206 $configuration = Configuration::getInstance();
207 $cipherKey = $configuration->get('crypto')['crypto_key'] ?? null;
208 if (!$cipherKey)
209 {
210 throw new SystemException('There is no crypto[crypto_key] in .settings.php. Generate it.');
211 }
212
213 $cipher = new Cipher();
214
215 return base64_encode($cipher->encrypt(time() . '_'. $this->userId .'_' . self::PROXY_CONST, $cipherKey));
216 }
217
224 private function checkUserToken(string $userToken = null): bool
225 {
226 if (!$userToken)
227 {
228 return false;
229 }
230
231 $configuration = Configuration::getInstance();
232 $cipherKey = $configuration->get('crypto')['crypto_key'] ?? null;
233 if (!$cipherKey)
234 {
235 throw new SystemException('There is no crypto[crypto_key] in .settings.php. Generate it.');
236 }
237
238 $cipher = new Cipher();
239 $data = explode('_', $cipher->decrypt(base64_decode($userToken), $cipherKey));
240 if (
241 empty($data[1])
242 || (($data[0] + 3600) < time())
243 || $data[2] !== self::PROXY_CONST
244 )
245 {
246 return false;
247 }
248
249 $user = \Bitrix\Main\UserTable::query()
250 ->where('ID', (int)$data[1])
251 ->setSelect(['*'])
252 ->exec()
253 ->fetchObject()
254 ;
255
256 if (!$user)
257 {
258 return false;
259 }
260
261 $this->user = $user;
262 $this->userId = $data[1];
263
264 return true;
265 }
266
267 private function parseState(string $requestState = null): ?array
268 {
269 if (!$requestState)
270 {
271 return null;
272 }
273
274 $state = [];
275 parse_str($requestState, $state);
276
277 if (!$state)
278 {
279 return null;
280 }
281
282 return $state;
283 }
284
285 public function AuthorizeUser($socservUserFields, $bSave = false)
286 {
287 if(!isset($socservUserFields['XML_ID']) || $socservUserFields['XML_ID'] == '')
288 {
289 return false;
290 }
291
292 if(!isset($socservUserFields['EXTERNAL_AUTH_ID']) || $socservUserFields['EXTERNAL_AUTH_ID'] == '')
293 {
294 return false;
295 }
296
297 if (!empty($socservUserFields['USER_ID']))
298 {
299 $this->deleteOldTokens($socservUserFields['USER_ID'], $socservUserFields['EXTERNAL_AUTH_ID']);
300
301 $dbSocUser = UserTable::getList(
302 [
303 'filter' => [
304 '=XML_ID' => $socservUserFields['XML_ID'],
305 '=EXTERNAL_AUTH_ID' => $socservUserFields['EXTERNAL_AUTH_ID']
306 ],
307 'select' => ['ID'],
308 ]
309 );
310
311 $storedUser = $dbSocUser->fetch();
312
313 if (!$storedUser)
314 {
315 $result = UserTable::add(UserTable::filterFields($socservUserFields));
316 }
317 else
318 {
319 $result = UserTable::update($storedUser['ID'], UserTable::filterFields($socservUserFields));
320 }
321 }
322 else
323 {
324 return false;
325 }
326
327 return $result->isSuccess();
328 }
329
334 private function deleteOldTokens($userId, $externalAuthId): void
335 {
336 $dbTokens = \Bitrix\Socialservices\UserTable::getList(
337 [
338 'filter' => [
339 '=USER_ID' => $userId,
340 '=EXTERNAL_AUTH_ID' => $externalAuthId
341 ],
342 'select' => ['ID']
343 ]);
344
345 while ($accessToken = $dbTokens->fetch())
346 {
347 UserTable::delete($accessToken['ID']);
348 }
349 }
350}
351
353{
354 public const TOKEN_URL = "https://calendar-proxy-ru-01.bitrix24.com";
355
356 public function __construct($appID = false, $appSecret = false, $code = false)
357 {
358 parent::__construct($this->getAppId(), null, $code);
359 }
360
361 public function GetAccessToken($redirect_uri = false)
362 {
363 $tokens = $this->getStorageTokens();
364
365 if(is_array($tokens))
366 {
367 $this->access_token = $tokens["OATOKEN"];
368 $this->accessTokenExpires = $tokens["OATOKEN_EXPIRES"];
369
370 if(!$this->code)
371 {
372 if ($this->checkAccessToken())
373 {
374 return true;
375 }
376
377 if(
378 isset($tokens["REFRESH_TOKEN"])
379 && $this->getNewAccessToken(
380 $tokens["REFRESH_TOKEN"],
381 $this->userId,
382 true
383 )
384 )
385 {
386 return true;
387 }
388 }
389
390 $this->deleteStorageTokens();
391 }
392
393 if($this->code === false)
394 {
395 return false;
396 }
397
398 $http = new HttpClient([
399 "socketTimeout" => $this->httpTimeout
400 ]);
401
402 $params = array_merge(
403 $this->getLicenseParams(),
404 [
405 "client_id" => $this->appID,
406 "code" => $this->code,
407 "redirect_uri" => $this->getRedirectUri(),
408 "grant_type" => "authorization_code",
409 ]
410 );
411
412 try
413 {
414 $result = \Bitrix\Main\Web\Json::decode($http->post(static::TOKEN_URL, $params));
415 if (isset($result['APP_ID'], $result['API_KEY']))
416 {
417 $params['client_id'] = $result['APP_ID'];
418 $this->appID = $result['APP_ID'];
419 CSocServGoogleOAuth::SetOption("google_proxy_appid", trim($result['APP_ID']));
420 CSocServGoogleOAuth::SetOption("google_proxy_api_key", trim($result['API_KEY']));
421
422 $result = \Bitrix\Main\Web\Json::decode($http->post(static::TOKEN_URL, $params));
423 }
424
425 $this->arResult = $result;
426 }
427 catch(\Bitrix\Main\ArgumentException $e)
428 {
429 $this->arResult = [];
430 }
431
432 if(isset($this->arResult["access_token"]) && $this->arResult["access_token"] <> '')
433 {
434 if(isset($this->arResult["refresh_token"]) && $this->arResult["refresh_token"] <> '')
435 {
436 $this->refresh_token = $this->arResult["refresh_token"];
437 }
438 $this->access_token = $this->arResult["access_token"];
439 $this->accessTokenExpires = $this->arResult["expires_in"] + time();
440
441 $_SESSION["OAUTH_DATA"] = [
442 "OATOKEN" => $this->access_token,
443 "OATOKEN_EXPIRES" => $this->accessTokenExpires,
444 "REFRESH_TOKEN" => $this->refresh_token,
445 ];
446
447 return true;
448 }
449
450 return false;
451 }
452
453 public function getNewAccessToken($refreshToken = false, $userId = 0, $save = false)
454 {
455 if($this->appID === false)
456 {
457 return false;
458 }
459
460 if($refreshToken === false)
461 {
462 $refreshToken = $this->refresh_token;
463 }
464
465
466 $params = array_merge(
467 $this->getLicenseParams(),
468 [
469 "client_id" => $this->appID,
470 "refresh_token"=>$refreshToken,
471 "grant_type"=>"refresh_token",
472 ]
473 );
474
475 $http = new HttpClient(
476 array("socketTimeout" => $this->httpTimeout)
477 );
478
479 $result = $http->post(static::TOKEN_URL, $params);
480
481 try
482 {
483 $this->arResult = \Bitrix\Main\Web\Json::decode($result);
484 }
485 catch(\Bitrix\Main\ArgumentException $e)
486 {
487 $this->arResult = [];
488 }
489
490 if (isset($this->arResult["access_token"]) && $this->arResult["access_token"] <> '')
491 {
492 $this->access_token = $this->arResult["access_token"];
493 $this->accessTokenExpires = $this->arResult["expires_in"] + time();
494 if ($save && intval($userId) > 0)
495 {
496 $dbSocservUser = \Bitrix\Socialservices\UserTable::getList([
497 'filter' => [
498 '=EXTERNAL_AUTH_ID' => static::SERVICE_ID,
499 '=USER_ID' => $userId,
500 ],
501 'select' => ["ID"]
502 ]);
503 if($arOauth = $dbSocservUser->Fetch())
504 {
505 \Bitrix\Socialservices\UserTable::update($arOauth["ID"], [
506 "OATOKEN" => $this->access_token,
507 "OATOKEN_EXPIRES" => $this->accessTokenExpires
508 ]
509 );
510 }
511 }
512
513 return true;
514 }
515
516 return false;
517 }
518
522 public function getAppId(): string
523 {
524 if ($appId = trim(CSocServGoogleOAuth::GetOption("google_proxy_appid")))
525 {
526 return $appId;
527 }
528
529 $http = new HttpClient(["socketTimeout" => $this->httpTimeout]);
530
531 $result = $http->post(static::TOKEN_URL, $this->getLicenseParams());
532
533 try
534 {
536 CSocServGoogleOAuth::SetOption("google_proxy_appid", trim($proxyData['APP_ID']));
537 CSocServGoogleOAuth::SetOption("google_proxy_api_key", trim($proxyData['API_KEY']));
538
539 return $proxyData['APP_ID'];
540 }
541 catch(\Bitrix\Main\ArgumentException $e)
542 {
543 }
544
545 return '';
546 }
547
551 public function getRedirectUri(): string
552 {
553 return static::TOKEN_URL;
554 }
555
559 public function getLicenseParams(): array
560 {
561 $params["BX_TYPE"] = Client::getPortalType();
562 $params["BX_LICENCE"] = Client::getLicenseCode();
563 $params["SERVER_NAME"] = Client::getServerName();
564 $params["license_key"] = Client::signRequest($params);
565
566 return $params;
567 }
568}
$arParams
Определения access_dialog.php:21
global $APPLICATION
Определения include.php:80
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
Определения check_mail.php:18
static get($moduleId, $name, $default="", $siteId=false)
Определения option.php:30
static includeModule($moduleName)
Определения loader.php:67
static decode($data)
Определения json.php:50
__construct($appID=false, $appSecret=false, $code=false)
Определения googleproxy.php:356
getNewAccessToken($refreshToken=false, $userId=0, $save=false)
Определения googleproxy.php:453
const TOKEN_URL
Определения googleproxy.php:354
GetAccessToken($redirect_uri=false)
Определения googleproxy.php:361
onAfterWebAuth($addParams, $mode, $url)
Определения authmanager.php:1707
onAfterMobileAuth()
Определения authmanager.php:1696
Определения google.php:11
prepareUser($arGoogleUser, $short=false)
Определения google.php:164
AuthorizeUser($socservUserFields, $bSave=false)
Определения googleproxy.php:285
static isProxyAuth()
Определения googleproxy.php:23
getEntityOAuth($code=false)
Определения googleproxy.php:184
const PROXY_CONST
Определения googleproxy.php:13
getUrl($location='opener', $addScope=null, $arParams=array())
Определения googleproxy.php:139
getStorageTokens()
Определения oauthtransport.php:116
deleteStorageTokens()
Определения oauthtransport.php:134
$accessTokenExpires
Определения oauthtransport.php:10
checkAccessToken()
Определения oauthtransport.php:153
static checkOAuthProxyParams()
Определения authmanager.php:1795
$arFields
Определения dblapprove.php:5
$data['IS_AVAILABLE']
Определения .description.php:13
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$_REQUEST["admin_mnu_menu_id"]
Определения get_menu.php:8
$result
Определения get_property_values.php:14
$save
Определения iblock_catalog_edit.php:365
if(!is_null($config))($config as $configItem)(! $configItem->isVisible()) $code
Определения options.php:195
IsModuleInstalled($module_id)
Определения tools.php:5301
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
if(empty($signedUserToken)) $key
Определения quickway.php:257
if(! $storage) $userToken
Определения quickway.php:276
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']
Определения template.php:799
$location
Определения options.php:2729
const SOCSERV_REGISTRATION_DENY
Определения include.php:4
const SOCSERV_AUTHORISATION_ERROR
Определения include.php:3
const SITE_ID
Определения sonet_set_content_view.php:12
$GLOBALS['_____370096793']
Определения update_client.php:1
$url
Определения iframe.php:7