%PDF- %PDF-
| Direktori : /proc/self/root/home/bitrix/www/local/php_interface/include/ |
| Current File : //proc/self/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)) : '')
);
}
}