%PDF- %PDF-
| Direktori : /home/bitrix/www/bitrix/modules/mail/lib/helper/ |
| Current File : /home/bitrix/www/bitrix/modules/mail/lib/helper/oauth.php |
<?php
namespace Bitrix\Mail\Helper;
use Bitrix\Main;
use Bitrix\Mail;
abstract class OAuth
{
protected $oauthEntity;
protected $service, $storedUid;
public static function getKnownServices()
{
static $knownServices;
if (is_null($knownServices))
{
$knownServices = array(
OAuth\Google::getServiceName(),
OAuth\LiveId::getServiceName(),
OAuth\Yandex::getServiceName(),
//OAuth\Mailru::getServiceName(),
);
}
return $knownServices;
}
public static function getInstance($service = null)
{
if (get_called_class() != get_class())
{
$className = get_called_class();
$service = $className::getServiceName();
}
else
{
if (!in_array($service, self::getKnownServices()))
{
return false;
}
$className = sprintf('%s\OAuth\%s', __NAMESPACE__, $service);
}
if (!Main\Loader::includeModule('socialservices'))
{
return false;
}
$instance = new $className;
$instance->service = $service;
$instance->storedUid = sprintf('%x%x', time(), rand(0, 0xffffffff));
if (!$instance->check())
{
return false;
}
return $instance;
}
public static function getInstanceByMeta($meta)
{
if ($meta = static::parseMeta($meta))
{
if ($instance = self::getInstance($meta['service']))
{
if ('oauthb' == $meta['type'])
{
$instance->storedUid = $meta['key'];
}
return $instance;
}
}
}
public function buildMeta()
{
return sprintf(
"\x00oauthb\x00%s\x00%s",
$this->getServiceName(),
$this->getStoredUid()
);
}
public static function parseMeta($meta)
{
$regex = sprintf(
'/^\x00(oauthb)\x00(%s)\x00([a-f0-9]+)$/',
join(
'|',
array_map(
function ($item)
{
return preg_quote($item, '/');
},
self::getKnownServices()
)
)
);
if (!preg_match($regex, $meta, $matches))
{
if (!preg_match('/^\x00(oauth)\x00(google|liveid)\x00(\d+)$/', $meta, $matches))
{
return null;
}
}
return array(
'type' => $matches[1],
'service' => $matches[2],
'key' => $matches[3],
);
}
private static function getSocservToken($service, $key)
{
if (Main\Loader::includeModule('socialservices'))
{
switch ($service)
{
case 'google':
$oauthClient = new \CSocServGoogleOAuth($key);
$oauthClient->getUrl('modal', array('https://mail.google.com/'));
break;
case 'liveid':
$oauthClient = new \CSocServLiveIDOAuth($key);
$oauthClient->getUrl('modal', array('wl.imap', 'wl.offline_access'));
break;
}
if (!empty($oauthClient))
{
return $oauthClient->getStorageToken() ?: false;
}
}
return null;
}
public static function getTokenByMeta($meta)
{
if ($meta = static::parseMeta($meta))
{
if ('oauthb' == $meta['type'])
{
if ($oauthHelper = self::getInstance($meta['service']))
{
return $oauthHelper->getStoredToken($meta['key']) ?: false;
}
}
else if ('oauth' == $meta['type'])
{
return self::getSocservToken($meta['service'], $meta['key']);
}
}
}
public static function getUserDataByMeta($meta, $secure = true)
{
if ($meta = static::parseMeta($meta))
{
if ($oauthHelper = self::getInstance($meta['service']))
{
if ('oauthb' == $meta['type'])
{
$oauthHelper->getStoredToken($meta['key']);
}
else if ('oauth' == $meta['type'])
{
if ($token = self::getSocservToken($meta['service'], $meta['key']))
{
$oauthHelper->getOAuthEntity()->setToken($token);
}
}
return $oauthHelper->getUserData($secure);
}
}
return null;
}
public function getOAuthEntity()
{
return $this->oauthEntity;
}
public function getStoredUid()
{
return $this->storedUid;
}
public function getRedirect($final = true)
{
return isModuleInstalled('bitrix24') && !$final
? $this->getControllerUrl() . '/redirect.php'
: \CHttp::urn2uri('/bitrix/tools/mail_oauth.php');
}
public function getUrl()
{
global $APPLICATION;
\CSocServAuthManager::setUniqueKey();
if (isModuleInstalled('bitrix24'))
{
$state = sprintf(
'%s?%s',
$this->getRedirect(),
http_build_query(array(
'check_key' => $_SESSION['UNIQUE_KEY'],
'dummy' => 'https://dummy.bitrix24.com/',
'state' => rawurlencode(http_build_query(array(
'service' => $this->service,
'uid' => $this->storedUid,
))),
))
);
}
else
{
$state = http_build_query(array(
'check_key' => $_SESSION['UNIQUE_KEY'],
'service' => $this->service,
'uid' => $this->storedUid,
));
}
return $this->oauthEntity->getAuthUrl($this->getRedirect(false), $state);
}
public function getStoredToken($uid = null)
{
$token = null;
if (!empty($uid))
{
$this->storedUid = $uid;
}
$item = Mail\Internals\OAuthTable::getList(array(
'filter' => array(
'=UID' => $this->storedUid,
),
'order' => array(
'ID' => 'DESC',
),
))->fetch();
if (!empty($item))
{
$this->oauthEntity->setToken($token = $item['TOKEN']);
if (empty($token) || $item['TOKEN_EXPIRES'] > 0 && $item['TOKEN_EXPIRES'] < time())
{
$this->oauthEntity->setToken(null);
if (!empty($item['REFRESH_TOKEN']))
{
$this->oauthEntity->getNewAccessToken($item['REFRESH_TOKEN']);
}
$token = $this->oauthEntity->getToken();
}
}
return $token;
}
public function getAccessToken($code = null)
{
if ($code)
{
$this->oauthEntity->setCode($code);
}
$oauthData = $_SESSION['OAUTH_DATA'];
$result = $this->oauthEntity->getAccessToken($this->getRedirect(false));
$_SESSION['OAUTH_DATA'] = $oauthData;
return $result;
}
public function getUserData($secure = true)
{
try
{
$userData = $this->oauthEntity->getCurrentUser();
}
catch (Main\SystemException $e)
{
}
if (!empty($userData))
{
return array_merge(
$this->mapUserData($userData),
$secure ? array() : array('__data' => $userData)
);
}
}
abstract protected function mapUserData(array $userData);
public static function getServiceName()
{
throw new Main\ObjectException('abstract');
}
public function handleResponse($state)
{
$this->storedUid = $state['uid'];
if (!empty($_REQUEST['code']) && \CSocServAuthManager::checkUniqueKey())
{
$this->getAccessToken($_REQUEST['code']);
if ($userData = $this->getUserData(false))
{
Mail\Internals\OAuthTable::add(array(
'UID' => $this->getStoredUid(),
'TOKEN' => $userData['__data']['access_token'],
'REFRESH_TOKEN' => $userData['__data']['refresh_token'],
'TOKEN_EXPIRES' => $userData['__data']['expires_in'],
));
unset($userData['__data']);
?>
<script type="text/javascript">
targetWindow = window.opener ? window.opener : window;
targetWindow.BX.onCustomEvent(
'OnMailOAuthBCompleted',
[
'<?=\CUtil::jsEscape($this->getStoredUid()) ?>',
'<?=\CUtil::jsEscape($this->getUrl()) ?>',
<?=Main\Web\Json::encode($userData) ?>
],
true
);
if (targetWindow !== window)
{
window.close();
}
</script>
<?
}
}
}
}