晋太元中,武陵人捕鱼为业。缘溪行,忘路之远近。忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤纷。渔人甚异之,复前行,欲穷其林。 林尽水源,便得一山,山有小口,仿佛若有光。便舍船,从口入。初极狭,才通人。复行数十步,豁然开朗。土地平旷,屋舍俨然,有良田、美池、桑竹之属。阡陌交通,鸡犬相闻。其中往来种作,男女衣着,悉如外人。黄发垂髫,并怡然自乐。 见渔人,乃大惊,问所从来。具答之。便要还家,设酒杀鸡作食。村中闻有此人,咸来问讯。自云先世避秦时乱,率妻子邑人来此绝境,不复出焉,遂与外人间隔。问今是何世,乃不知有汉,无论魏晋。此人一一为具言所闻,皆叹惋。余人各复延至其家,皆出酒食。停数日,辞去。此中人语云:“不足为外人道也。”(间隔 一作:隔绝) 既出,得其船,便扶向路,处处志之。及郡下,诣太守,说如此。太守即遣人随其往,寻向所志,遂迷,不复得路。 南阳刘子骥,高尚士也,闻之,欣然规往。未果,寻病终。后遂无问津者。
|
Server : Apache System : Linux srv.rainic.com 4.18.0-553.47.1.el8_10.x86_64 #1 SMP Wed Apr 2 05:45:37 EDT 2025 x86_64 User : rainic ( 1014) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /proc/thread-self/root/home/akaindir/public_html/crm/modules/Google/connectors/ |
Upload File : |
<?php
/*+***********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
*************************************************************************************/
require_once 'vtlib/Vtiger/Net/Client.php';
class Google_Oauth2_Connector {
protected $service_provider = 'Google';
protected $source_module;
protected $user_id;
protected $db;
protected $table_name = 'vtiger_google_oauth2';
protected $service_name;
protected $client_id;
protected $client_secret;
protected $redirect_uri;
protected $scope;
protected $state;
protected $response_type = 'code';
protected $access_type = 'offline';
protected $approval_prompt = 'force';
protected $scopes = array(
'Contacts' => 'https://www.google.com/m8/feeds',
'Calendar' => 'https://www.googleapis.com/auth/calendar',
);
public $token;
const OAUTH2_AUTH_URL = 'https://accounts.google.com/o/oauth2/auth';
const OAUTH2_TOKEN_URI = 'https://accounts.google.com/o/oauth2/token';
const OAUTH2_REVOKE_URI = 'https://accounts.google.com/o/oauth2/revoke';
public function __construct($module,$userId=false) {
global $site_URL;
$this->source_module = $module;
if($userId) $this->user_id = $userId;
$this->service_name = $this->service_provider . $module;
$this->client_id = Google_Config_Connector::$clientId;
$this->client_secret = Google_Config_Connector::$clientSecret;
$this->redirect_uri = Google_Config_Connector::getRedirectUrl();
$this->scope = implode(' ', array_values($this->scopes));
}
public function getClientId() {
return $this->client_id;
}
public function getClientSecret() {
return $this->client_secret;
}
public function getRedirectUri() {
return $this->redirect_uri;
}
public function getScope() {
return $this->scope;
}
public function getAccessType() {
return $this->access_type;
}
public function getApprovalPrompt() {
return $this->approval_prompt;
}
public function getAccessToken() {
return json_encode($this->token['access_token']);
}
protected function getAuthUrl() {
$params = array(
'response_type='. urlencode($this->response_type),
'redirect_uri=' . urlencode($this->redirect_uri),
'client_id=' . urlencode($this->client_id),
'scope=' . urlencode($this->scope),
'access_type=' . urlencode($this->access_type),
'approval_prompt=' . urlencode($this->approval_prompt),
);
$queryString = implode('&', $params);
return self::OAUTH2_AUTH_URL . "?$queryString";
}
public function hasStoredToken() {
if(!isset($this->user_id)) $this->user_id = Users_Record_Model::getCurrentUserModel()->getId();
if(!isset($this->db)) $this->db = PearDatabase::getInstance();
$sql = 'SELECT 1 FROM ' . $this->table_name . ' WHERE userid = ? AND service = ?';
$params = array($this->user_id, $this->service_name);
$res = $this->db->pquery($sql,$params);
$hasStoredToken = ($this->db->num_rows($res) > 0) ? true : false;
return $hasStoredToken;
}
public function getState($source) {
global $site_URL;
$callbackUri = rtrim($site_URL, '/') . '/index.php?module=Google&view=List&operation=sync&sourcemodule='.$this->source_module . '&service=' . $source;
$stateDetails['url'] = $callbackUri;
$parse = parse_url($site_URL);
$ipAddr = getHostByName($parse['host']);
// to prevent domain name forgery
$stateDetails['dnf'] = md5($ipAddr);
$state = json_encode($stateDetails,JSON_FORCE_OBJECT);
return $state;
}
protected function setState() {
$this->state = $this->getState($this->service_name);
}
protected function showConsentScreen() {
header('Location: ' . $this->getAuthUrl());
}
protected function fireRequest($url,$headers,$params=array(),$method='POST') {
$httpClient = new Vtiger_Net_Client($url);
if(count($headers)) $httpClient->setHeaders($headers);
switch ($method) {
case 'POST':
$response = $httpClient->doPost($params);
break;
case 'GET':
$response = $httpClient->doGet($params);
break;
}
return $response;
}
protected function exchangeCodeForToken($code) {
$params = array(
'grant_type' => 'authorization_code',
'code' => $code,
'client_id' => $this->client_id,
'client_secret' => $this->client_secret,
'redirect_uri' => $this->redirect_uri
);
$response = $this->fireRequest(self::OAUTH2_TOKEN_URI,array(),$params);
return $response;
}
protected function storeToken($token) {
if(!isset($this->user_id)) $this->user_id = Users_Record_Model::getCurrentUserModel()->getId();
if(!isset($this->db)) $this->db = PearDatabase::getInstance();
$decodedToken = json_decode($token,true);
$refresh_token = $decodedToken['refresh_token'];
unset($decodedToken['refresh_token']);
$decodedToken['created'] = time();
$accessToken = json_encode($decodedToken);
$modulesSupported = array('Contacts', 'Calendar');
foreach($modulesSupported as $moduleName) {
$params = array($this->service_provider.$moduleName,$accessToken,$refresh_token,$this->user_id);
$sql = 'INSERT INTO ' . $this->table_name . ' VALUES (' . generateQuestionMarks($params) . ')';
$this->db->pquery($sql,$params);
}
}
protected function retreiveToken() {
if(!$this->user_id) $this->user_id = Users_Record_Model::getCurrentUserModel()->getId();
$query = 'SELECT access_token,refresh_token FROM ' . $this->table_name . ' WHERE userid=? AND service =?';
$params = array($this->user_id, $this->service_name);
$result = $this->db->pquery($query, $params);
$data = $this->db->fetch_array($result);
$decodedAccessToken = json_decode(decode_html($data['access_token']),true);
$refreshToken = decode_html($data['refresh_token']);
return array(
'access_token' => $decodedAccessToken,
'refresh_token' => $refreshToken
);
}
protected function setToken($token) {
$this->token = $token;
}
public function isTokenExpired() {
if (null == $this->token || null == $this->token['access_token']) return true;
// If the token is set to expire in the next 30 seconds.
$expired = ($this->token['access_token']['created']
+ ($this->token['access_token']['expires_in'] - 30)) < time();
return $expired;
}
protected function updateAccessToken($accesstoken,$refreshtoken) {
if(!isset($this->db)) $this->db = PearDatabase::getInstance();
$sql = 'UPDATE ' . $this->table_name . ' SET access_token = ? WHERE refresh_token = ? AND service = ?';
$params = array($accesstoken,$refreshtoken,$this->service_name);
$this->db->pquery($sql,$params);
}
public function refreshToken() {
if($this->token['refresh_token'] == null) throw new AppException('refresh token is null');
$params = array(
'grant_type' => 'refresh_token',
'refresh_token' => $this->token['refresh_token'],
'client_id' => $this->client_id,
'client_secret' => $this->client_secret
);
$encodedToken = $this->fireRequest(self::OAUTH2_TOKEN_URI,array(),$params);
$decodedToken = json_decode($encodedToken,true);
if(!isset($decodedToken['error'])) {
$decodedToken['created'] = time();
$token['access_token'] = $decodedToken;
$token['refresh_token'] = $this->token['refresh_token'];
$this->updateAccessToken(json_encode($decodedToken),$token['refresh_token']);
$this->setToken($token);
}
}
public function authorize() {
if($this->hasStoredToken()) {
$token = $this->retreiveToken();
$this->setToken($token);
if($this->isTokenExpired()) $this->refreshToken();
return $this;
} else {
if($_REQUEST['service'] && $_REQUEST['code']) {
$authCode = $_REQUEST['code'];
$token = $this->exchangeCodeForToken($authCode);
$this->storeToken($token);
echo '<script>window.opener.sync();window.close();</script>'; exit;
} else if($_REQUEST['service']) {
echo '<script>window.close();</script>'; exit;
} else {
$this->setState(); $this->showConsentScreen();
}
}
}
}
?>