%PDF- %PDF-
Direktori : /proc/11976/task/11976/root/home/bitrix/www/local/php_interface/include/ |
Current File : //proc/11976/task/11976/root/home/bitrix/www/local/php_interface/include/phoneauth.php |
<?php use Firebase\Auth\Token\Exception\InvalidToken; use Kreait\Firebase\Factory; use Kreait\Firebase\ServiceAccount; define('SLACK2LOG_URL', 'https://hooks.slack.com/services/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'); class PhoneUserLoginExternal { const UF_FIREBASE = 'UF_FIREBASE'; public static function getUserByFirebaseUid($uid) { $dbUser = \CUser::GetList( ($by = 'XML_ID'), ($order = 'asc'), ['XML_ID' => $uid], [SELECT => ['ID', static::UF_FIREBASE]] ); if ($arUser = $dbUser->Fetch()) { return $arUser; } return false; } /** * Авторизует пользователя по токену в хидере. */ public static function OnBeforeProlog() { global $USER; if ($USER->IsAuthorized() || empty($_SERVER['REMOTE_USER'])) { return; } // static::log2slack('OnBeforeProlog', $_SERVER); $arToken = explode(' ', $_SERVER['REMOTE_USER']); if ('Bearer' !== $arToken[0]) { return; } $dbUser = \CUser::GetList( ($by = 'ID'), ($order = 'asc'), [static::UF_FIREBASE => $arToken['1']] ); if ($arUser = $dbUser->Fetch()) { $USER->Authorize($arUser['ID'], false); } } /** * Код взят из компонента p4:user.registration. * Профилю будет присвоено временное имя "ID_соль" (например, 13456_cdjkncfkdvb). * И e-mail 'no-reply@port4lio.pro', письмо о регистрации уйдет в на no-reply@port4lio.pro. * * @param string $uid Идентифкатор пользователя в Firebase * @param string $customTokem Внутренний токен авторизации в P4 * * @return array|null user data */ public static function registerUser($uid, $customToken) { $CUser = new \CUser(); $passwd = uniqid(); $result = $CUser->Register( "FIREBASE_{$uid}", "FIREBASE_{$uid}".uniqid().'_fake', '', $passwd, $passwd, "FIREBASE_{$uid}-no-reply@port4lio.pro" ); if ('OK' == $result['TYPE']) { $userID = $result['ID']; $CUser->Update($userID, [ 'ACTIVE' => 'Y', 'XML_ID' => $uid, static::UF_FIREBASE => $customToken, ]); $dbUser = \CUser::GetByID($userID); $arUser = $dbUser->Fetch(); $section = 'models'; if (!($profileID = P4UserRegisterHelper::createProfile($arUser, $el, $section))) { static::log('registerUser: '.$el->LAST_ERROR, 'ERROR'); return false; } return $arUser; } } /** * Авторизация пользователя по токену из Firabase Auth. * * @param array $arParams * * @return bool|int */ public static function OnFirebaseAuth(&$arParams) { if (!empty($_REQUEST['LOGIN_BY_FIREBASE']) && 'Y' == $_REQUEST['LOGIN_BY_FIREBASE']) { $idTokenString = $_REQUEST['LOGIN']; $serviceAccount = ServiceAccount::fromJsonFile( __DIR__. '/keys/port4lio-8fb93-firebase-adminsdk-tcdmn-cbee5bad88.json' ); $firebase = (new Factory()) ->withServiceAccount($serviceAccount) ->create(); try { $verifiedIdToken = $firebase->getAuth()->verifyIdToken($idTokenString); } catch (InvalidToken $e) { static::log('OnFirebaseAuth#InvalidToken: '.$e->getMessage(), 'ERROR'); return false; } $uid = $verifiedIdToken->getClaim('sub'); $arUser = static::getUserByFirebaseUid($uid); if (is_array($arUser) && !empty($arUser)) { if (!empty($arUser[static::UF_FIREBASE])) { $customToken = $firebase->getAuth()->createCustomToken($uid); $CUser = new \CUser(); $arUserFields = [static::UF_FIREBASE => $customToken]; if (!$CUser->Update($arUser['ID'], $arUserFields)) { static::log('UpdateCustomToken: '.$CUser->LAST_ERROR, 'ERROR'); } } return $arUser['ID']; } else { $customToken = $firebase->getAuth()->createCustomToken($uid); $arFbUser = $firebase->getAuth()->getUser($uid); if (!empty($arFbUser->phoneNumber)) { $phoneNumber = str_replace('+', '', $arFbUser->phoneNumber); $by = 'id'; $order = 'desc'; $dbUsers = CUser::GetList($by, $order, array( 'UF_USER_PHONE' => $phoneNumber, 'ACTIVE' => 'Y', )); if ($arUser = $dbUsers->Fetch()) { $CUser = new \CUser(); $arUserFields = [static::UF_FIREBASE => $customToken]; if (!$CUser->Update($arUser['ID'], $arUserFields)) { static::log('UpdateCustomToken: '.$CUser->LAST_ERROR, 'ERROR'); } return $arUser['ID']; } } $arUser = static::registerUser($uid, $customToken); if (is_array($arUser) && !empty($arUser)) { return $arUser['ID']; } } } } /** * Авторизация пользователя по номеру телефона. * * @param [type] $arParams */ public static function OnUserLoginExternal(&$arParams) { if (isset($_REQUEST['LOGIN_BY_PHONE']) && 'Y' == $_REQUEST['LOGIN_BY_PHONE']) { $by = 'id'; $order = 'desc'; $dbUsers = CUser::GetList($by, $order, array( 'UF_USER_PHONE' => $arParams['LOGIN'], 'ACTIVE' => 'Y', )); if ($arUser = $dbUsers->Fetch()) { $arParams['PASSWORD']; if (strlen($arUser['PASSWORD']) > 32) { $salt = substr($arUser['PASSWORD'], 0, strlen($arUser['PASSWORD']) - 32); $db_password = substr($arUser['PASSWORD'], -32); } else { $salt = ''; $db_password = $arUser['PASSWORD']; } if ('Y' == $arParams['PASSWORD_ORIGINAL']) { $user_password = md5($salt.$arParams['PASSWORD']); } else { if (strlen($arParams['PASSWORD']) > 32) { $user_password = substr($arParams['PASSWORD'], -32); } else { $user_password = $arParams['PASSWORD']; } } if ($db_password === $user_password) { return $arUser['ID']; } } } } public static function log2slack($message, $context = null) { if (\defined('SLACK2LOG_URL') && function_exists(curl_init)) { $server = empty($_SERVER['SERVER_NAME']) ? $_SERVER['DOCUMENT_ROOT'] : $_SERVER['SERVER_NAME']; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, SLACK2LOG_URL); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type:application/json']); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([ text => $server.': '.$message. (null === $context ? '' : "\n\n".print_r($context, true)), ])); $result = curl_exec($ch); curl_close($ch); } else { \CEventLog::Log( 'INFO', 'INFO', 'external.auth', 'external.auth', null === $context ? $message : $message.'. '.print_r($context, true)); } } public static function init() { AddEventHandler('main', 'OnUserLoginExternal', [__CLASS__, 'OnUserLoginExternal']); AddEventHandler('main', 'OnUserLoginExternal', [__CLASS__, 'OnFirebaseAuth']); AddEventHandler('main', 'OnBeforeProlog', [__CLASS__, 'OnBeforeProlog']); } private static function log($message, $severity = 'INFO', $context = null) { \CEventLog::Log( $severity, $severity, 'external.auth', 'external.auth', $message.(null != $context ? (': '.print_r($context, true)) : '') ); } }