Initial xentral_oss_20.3.c9ffacf
This commit is contained in:
@@ -0,0 +1,982 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
use Xentral\Components\Database\Database;
|
||||
use Xentral\Components\Http\Request;
|
||||
use Xentral\Components\Http\Session\Session;
|
||||
use Xentral\Components\Http\Session\SessionHandler;
|
||||
use Xentral\Modules\GoogleApi\Data\GoogleCredentialsData;
|
||||
use Xentral\Modules\GoogleApi\Exception\CsrfViolationException;
|
||||
use Xentral\Modules\GoogleApi\Exception\GoogleAccountNotFoundException;
|
||||
use Xentral\Modules\GoogleApi\Exception\UserConsentException;
|
||||
use Xentral\Modules\GoogleApi\GoogleScope;
|
||||
use Xentral\Modules\GoogleApi\Service\GoogleAccountGateway;
|
||||
use Xentral\Modules\GoogleApi\Service\GoogleAccountService;
|
||||
use Xentral\Modules\GoogleApi\Service\GoogleAuthorizationService;
|
||||
use Xentral\Modules\GoogleApi\Service\GoogleCredentialsService;
|
||||
use Xentral\Modules\GoogleCalendar\Client\GoogleCalendarClientFactory;
|
||||
use Xentral\Modules\GoogleCalendar\Service\GoogleCalendarSynchronizer;
|
||||
|
||||
class GoogleApi
|
||||
{
|
||||
/** @var string MODULE_NAME */
|
||||
public const MODULE_NAME = 'GoogleApi';
|
||||
|
||||
/** @var string GOOGLE_API_TESTURL_PRINT */
|
||||
//private const TESTURL_PRINT = 'https://www.google.com/cloudprint/search';
|
||||
|
||||
/** @var string GOOGLE_API_TESTURL_CALENDAR */
|
||||
//private const TESTURL_CALENDAR = 'https://www.googleapis.com/calendar/v3/users/me/calendarList';
|
||||
|
||||
/** @var erpooSystem $app */
|
||||
private $app;
|
||||
|
||||
/** @var GoogleAccountGateway $gateway */
|
||||
private $gateway;
|
||||
|
||||
/** @var GoogleAccountService $service */
|
||||
private $service;
|
||||
|
||||
/** @var GoogleCredentialsService $credentialsService */
|
||||
private $credentialsService;
|
||||
|
||||
/** @var GoogleAuthorizationService $auh */
|
||||
private $auth;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param erpooSystem $app
|
||||
* @param bool $intern
|
||||
*/
|
||||
public function __construct($app, $intern = false)
|
||||
{
|
||||
$this->app = $app;
|
||||
if ($intern) {
|
||||
return;
|
||||
}
|
||||
$this->gateway = $this->app->Container->get('GoogleAccountGateway');
|
||||
$this->service = $this->app->Container->get('GoogleAccountService');
|
||||
$this->credentialsService = $this->app->Container->get('GoogleCredentialsService');
|
||||
$this->auth = $this->app->Container->get('GoogleAuthorizationService');
|
||||
|
||||
$this->app->ActionHandlerInit($this);
|
||||
|
||||
// ab hier alle Action Handler definieren die das Modul hat
|
||||
$this->app->ActionHandler('list', 'GoogleApiEdit');
|
||||
$this->app->ActionHandler('edit', 'GoogleApiEdit');
|
||||
$this->app->ActionHandler('print', 'GoogleApiPrint');
|
||||
$this->app->ActionHandler('redirect', 'GoogleApiRedirect');
|
||||
$this->app->ActionHandler('ajaxprinters', 'GoogleApiAjaxPrinters');
|
||||
|
||||
$this->app->ActionHandlerListen($app);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param erpooSystem $app
|
||||
* @param string $name
|
||||
* @param array $erlaubtevars
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function TableSearch(&$app, $name, $erlaubtevars)
|
||||
{
|
||||
// in dieses switch alle lokalen Tabellen (diese Live Tabellen mit Suche etc.) für dieses Modul
|
||||
switch ($name) {
|
||||
case 'googleapi_list':
|
||||
$allowed['googleapi'] = ['list'];
|
||||
|
||||
$heading = [
|
||||
'Name (intern)',
|
||||
'Beschreibung',
|
||||
'Art',
|
||||
'Aktiv',
|
||||
'Client ID',
|
||||
'Client Schlüssel',
|
||||
'letzte Registrierung',
|
||||
'Menü',
|
||||
];
|
||||
$width = ['10%', '10%', '10%', '5%', '20%', '10%', '10%', '1%'];
|
||||
$findcols = [
|
||||
'g.id_name',
|
||||
'g.description',
|
||||
'g.type',
|
||||
'g.active',
|
||||
'g.user',
|
||||
'g.password',
|
||||
'g.last_auth',
|
||||
'g.id',
|
||||
];
|
||||
$searchsql = [
|
||||
'g.id_name',
|
||||
'g.description',
|
||||
'g.type',
|
||||
'g.active',
|
||||
'g.user',
|
||||
'g.password',
|
||||
'g.last_auth',
|
||||
];
|
||||
$defaultorder = 1;
|
||||
$defaultorderdesc = 0;
|
||||
|
||||
$menu = '<table cellpadding=0 cellspacing=0>';
|
||||
$menu .= '<tr>';
|
||||
$menu .= '<td nowrap>';
|
||||
$menu .= '<a href="?module=googleapi&action=edit&id=%value%" class="googleapi-edit" data-googleapi-id="%value%">';
|
||||
$menu .= "<img src=\"themes/{$app->Conf->WFconf['defaulttheme']}/images/edit.svg\" border=\"0\">";
|
||||
$menu .= '</a> ';
|
||||
$menu .= '<a href="javascript:;" class="googleapi-delete" data-googleapi-id="%value%">';
|
||||
$menu .= "<img src=\"themes/{$app->Conf->WFconf['defaulttheme']}/images/delete.svg\" border=\"0\">";
|
||||
$menu .= '</a>';
|
||||
$menu .= '</td>';
|
||||
$menu .= '</tr>';
|
||||
$menu .= '</table>';
|
||||
|
||||
$where = ' g.id > 0';
|
||||
|
||||
$sql = "SELECT SQL_CALC_FOUND_ROWS g.id, g.id_name, g.description,
|
||||
(CASE g.type
|
||||
WHEN 'print' THEN 'Google Cloud Print'
|
||||
WHEN 'mail' THEN 'Google Mail'
|
||||
WHEN 'calendar' THEN 'Google Calendar'
|
||||
ELSE ''
|
||||
END) AS `type`,
|
||||
IF(g.active = 0, 'nein', 'ja'),
|
||||
g.user, g.password, g.last_auth, g.id
|
||||
FROM googleapi AS g";
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$erg = false;
|
||||
|
||||
foreach ($erlaubtevars as $k => $v) {
|
||||
if (isset($$v)) {
|
||||
$erg[$v] = $$v;
|
||||
}
|
||||
}
|
||||
|
||||
return $erg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function Install()
|
||||
{
|
||||
//$this->app->erp->CheckTable('googleapi');
|
||||
//$this->app->erp->CheckColumn('id', 'int(11)', 'googleapi', 'NOT NULL AUTO_INCREMENT');
|
||||
//$this->app->erp->CheckColumn('id_name', 'varchar(255)', 'googleapi', "NOT NULL DEFAULT ''");
|
||||
//$this->app->erp->CheckColumn('description', 'varchar(255)', 'googleapi', 'NULL');
|
||||
//$this->app->erp->CheckColumn('type', 'varchar(255)', 'googleapi', 'NULL');
|
||||
//$this->app->erp->CheckColumn('active', 'tinyint', 'googleapi', 'NOT NULL DEFAULT 0');
|
||||
//$this->app->erp->CheckColumn('user', 'varchar(255)', 'googleapi', 'NULL');
|
||||
//$this->app->erp->CheckColumn('password', 'varchar(255)', 'googleapi', 'NULL');
|
||||
//$this->app->erp->CheckColumn('redirect_uri', 'varchar(255)', 'googleapi', 'NULL');
|
||||
//$this->app->erp->CheckColumn('token', 'varchar(255)', 'googleapi', 'NULL');
|
||||
//$this->app->erp->CheckColumn('token_expires', 'datetime', 'googleapi', 'NULL');
|
||||
//$this->app->erp->CheckColumn('refresh_token', 'varchar(255)', 'googleapi', 'NULL');
|
||||
//$this->app->erp->CheckColumn('last_auth', 'datetime', 'googleapi', 'NULL');
|
||||
|
||||
//$this->app->erp->CheckTable('googleapi_user');
|
||||
//$this->app->erp->CheckColumn('id', 'int(11)', 'googleapi_user', 'NOT NULL AUTO_INCREMENT');
|
||||
//$this->app->erp->CheckColumn('user_id', 'int(11)', 'googleapi_user', 'NOT NULL DEFAULT 0');
|
||||
//$this->app->erp->CheckColumn('googleapi_id_name', 'varchar(255)', 'googleapi_user', "NOT NULL DEFAULT ''");
|
||||
//$this->app->erp->CheckColumn('active', 'tinyint', 'googleapi_user', 'NOT NULL DEFAULT 0');
|
||||
//$this->app->erp->CheckColumn('auto_sync', 'tinyint', 'googleapi_user', 'NOT NULL DEFAULT 0');
|
||||
//$this->app->erp->CheckColumn('identifier', 'varchar(255)', 'googleapi_user', 'NULL');
|
||||
//$this->app->erp->CheckColumn('refresh_token', 'varchar(255)', 'googleapi_user', 'NULL');
|
||||
//$this->app->erp->CheckColumn('access_token', 'varchar(255)', 'googleapi_user', 'NULL');
|
||||
//$this->app->erp->CheckColumn('token_expires', 'datetime', 'googleapi_user', 'NULL');
|
||||
//$this->app->erp->CheckIndex('googleapi_user', 'user_id');
|
||||
|
||||
$this->app->erp->CheckTable('google_account');
|
||||
$this->app->erp->CheckColumn('id', 'int(11)', 'google_account', 'UNSIGNED NOT NULL AUTO_INCREMENT');
|
||||
$this->app->erp->CheckColumn('user_id', 'int(11)', 'google_account', 'UNSIGNED NOT NULL DEFAULT 0');
|
||||
$this->app->erp->CheckColumn('refresh_token', 'varchar(255)', 'google_account');
|
||||
$this->app->erp->CheckColumn('identifier', 'varchar(255)', 'google_account');
|
||||
$this->app->erp->CheckIndex('google_account', 'user_id');
|
||||
|
||||
$this->app->erp->CheckTable('google_account_scope');
|
||||
$this->app->erp->CheckColumn('id', 'int(11)', 'google_account_scope', 'UNSIGNED NOT NULL AUTO_INCREMENT');
|
||||
$this->app->erp->CheckColumn('google_account_id', 'int(11)', 'google_account_scope', 'UNSIGNED NOT NULL DEFAULT 0');
|
||||
$this->app->erp->CheckColumn('scope', 'varchar(255)', 'google_account_scope');
|
||||
$this->app->erp->CheckIndex('google_account_scope', 'google_account_id');
|
||||
|
||||
$this->app->erp->CheckTable('google_account_property');
|
||||
$this->app->erp->CheckColumn('id', 'int(11)', 'google_account_property', 'UNSIGNED NOT NULL AUTO_INCREMENT');
|
||||
$this->app->erp->CheckColumn('google_account_id', 'int(11)', 'google_account_property', 'UNSIGNED NOT NULL DEFAULT 0');
|
||||
$this->app->erp->CheckColumn('varname', 'varchar(64)', 'google_account_property');
|
||||
$this->app->erp->CheckColumn('value', 'varchar(255)', 'google_account_property');
|
||||
$this->app->erp->CheckIndex('google_account_data', 'google_account_id');
|
||||
|
||||
$this->app->erp->CheckTable('google_access_token');
|
||||
$this->app->erp->CheckColumn('id', 'int(11)', 'google_access_token', 'UNSIGNED NOT NULL AUTO_INCREMENT');
|
||||
$this->app->erp->CheckColumn('google_account_id', 'int(11)', 'google_access_token', 'UNSIGNED NOT NULL DEFAULT 0');
|
||||
$this->app->erp->CheckColumn('token', 'varchar(255)', 'google_access_token');
|
||||
$this->app->erp->CheckColumn('expires', 'datetime', 'google_access_token');
|
||||
$this->app->erp->CheckIndex('google_access_token', 'google_account_id');
|
||||
|
||||
$this->app->erp->CheckTable('googleapi_calendar_sync');
|
||||
$this->app->erp->CheckColumn('id', 'int(11)', 'googleapi_calendar_sync', 'NOT NULL AUTO_INCREMENT');
|
||||
$this->app->erp->CheckColumn('event_id', 'int(11)', 'googleapi_calendar_sync', 'NOT NULL DEFAULT 0');
|
||||
$this->app->erp->CheckColumn('foreign_id', 'varchar(255)', 'googleapi_calendar_sync', "NOT NULL DEFAULT ''");
|
||||
$this->app->erp->CheckColumn('owner', 'int(11)', 'googleapi_calendar_sync', 'NOT NULL DEFAULT 0');
|
||||
$this->app->erp->CheckColumn('from_google', 'tinyint', 'googleapi_calendar_sync', 'NOT NULL DEFAULT 0');
|
||||
$this->app->erp->CheckColumn('event_date', 'datetime', 'googleapi_calendar_sync', 'NULL');
|
||||
$this->app->erp->CheckColumn('html_link', 'varchar(255)', 'googleapi_calendar_sync', 'NULL');
|
||||
$this->app->erp->CheckIndex('googleapi_calendar_sync', 'event_id');
|
||||
|
||||
$this->app->erp->RegisterHook('kalender_event_hook','googleapi', 'EventHook');
|
||||
$this->app->erp->CheckProzessstarter('Google Kalender Import', 'uhrzeit', '', '2017-01-01 00:00:00', 'cronjob', 'google_calendar_import', 1);
|
||||
|
||||
$this->migrate();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $eventId
|
||||
* @param string $actionType
|
||||
*/
|
||||
public function EventHook($eventId, $actionType)
|
||||
{
|
||||
try {
|
||||
/** @var GoogleAccountGateway $gateway */
|
||||
$gateway = $this->app->Container->get('GoogleAccountGateway');
|
||||
$userId = (int)$this->app->User->GetID();
|
||||
/** @var GoogleCalendarClientFactory $factory */
|
||||
$factory = $this->app->Container->get('GoogleCalendarClientFactory');
|
||||
$client = $factory->createClient($userId);
|
||||
/** @var GoogleCalendarSynchronizer $synchronizer */
|
||||
$synchronizer = $this->app->Container->get('GoogleCalendarSynchronizer');
|
||||
$synchronizer->calendarEventHook($client, $eventId, $actionType);
|
||||
} catch (Exception $e) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function GoogleApiList(): void
|
||||
{
|
||||
$this->createMenu();
|
||||
$this->app->erp->Headlines('Google APIs');
|
||||
$this->existTables();
|
||||
|
||||
$this->app->YUI->TableSearch(
|
||||
'TAB1',
|
||||
'googleapi_list',
|
||||
'show',
|
||||
'',
|
||||
'',
|
||||
basename(__FILE__),
|
||||
__CLASS__
|
||||
);
|
||||
$this->app->Tpl->Parse('PAGE', 'googleapi_list.tpl');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function GoogleApiEdit(): void
|
||||
{
|
||||
$this->existTables();
|
||||
|
||||
/** @var Request $request */
|
||||
$request = $this->app->Container->get('Request');
|
||||
if ($request->post->has('save')) {
|
||||
$this->saveCredentials($request);
|
||||
$this->app->Tpl->Add(
|
||||
'MESSAGE',
|
||||
'<div class="info">Einstellungen wurden gespeichert.</div>'
|
||||
);
|
||||
}
|
||||
|
||||
if ($request->post->has('authorize_mail')) {
|
||||
$this->authorize(GoogleScope::MAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($request->post->has('authorize_cal')) {
|
||||
$this->authorize(GoogleScope::CALENDAR);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($request->post->has('unauthorize')) {
|
||||
$this->unauthorize();
|
||||
}
|
||||
|
||||
$credentials = $this->credentialsService->getCredentials();
|
||||
$redirectUri = $credentials->getRedirectUri();
|
||||
if (empty($redirectUri)) {
|
||||
$redirectUri = $this->auth->getDefaultRedirectUri();
|
||||
}
|
||||
$this->app->Tpl->Set('CLIENT_ID',$credentials->getClientId());
|
||||
$this->app->Tpl->Set('SECRET', $credentials->getClientSecret());
|
||||
$this->app->Tpl->Set('REDIRECT_URI', $redirectUri);
|
||||
|
||||
$this->app->erp->Headlines('Google Zugangsdaten');
|
||||
$this->createMenu();
|
||||
$this->app->Tpl->Parse('PAGE', 'googleapi_edit.tpl');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function GoogleApiPrint(): void
|
||||
{
|
||||
/** @var Request $request */
|
||||
$request = $this->app->Container->get('Request');
|
||||
if ($request->post->has('authorize_cloudprint')) {
|
||||
/** @var Session $session */
|
||||
$session = $this->app->Container->get('Session');
|
||||
$redirect = $this->auth->requestScopeAuthorization(
|
||||
$session,
|
||||
[GoogleScope::CLOUDPRINT],
|
||||
'index.php?module=googleapi&action=print'
|
||||
);
|
||||
SessionHandler::commitSession($session);
|
||||
$redirect->send();
|
||||
$this->app->ExitXentral();
|
||||
}
|
||||
|
||||
if ($request->post->has('unauthorize')) {
|
||||
$this->unauthorize();
|
||||
}
|
||||
|
||||
$this->app->Tpl->Add(
|
||||
'MESSAGE',
|
||||
'<div class="warning">
|
||||
Hinweis: Google wird den Cloud Print Dienst am 31.12.2020 abschalten.</div>'
|
||||
);
|
||||
|
||||
$this->app->erp->Headlines('Google Cloud Print');
|
||||
$this->createMenu();
|
||||
$this->app->Tpl->Parse('PAGE', 'googleapi_print.tpl');
|
||||
}
|
||||
|
||||
/**
|
||||
* After user confirmed access to Google API manually, Google API
|
||||
* redirects user to this action sending authentication code and API scope
|
||||
* as GET parameters.
|
||||
*/
|
||||
public function GoogleApiRedirect()
|
||||
{
|
||||
/** @var Session $session */
|
||||
$session = $this->app->Container->get('Session');
|
||||
/** @var Request $request */
|
||||
$request = $this->app->Container->get('Request');
|
||||
$userId = (int)$this->app->User->GetID();
|
||||
|
||||
try {
|
||||
return $this->auth->authorizationCallback($session, $request, $userId);
|
||||
} catch (CsrfViolationException $e) {
|
||||
$message = '<div class="error">CSRF Token ungültig. Bitte versuchen Sie es erneut.</div>';
|
||||
} catch (UserConsentException $e) {
|
||||
$message = '<div class="warning">Authorisierung für Google durch den Benutzer abgebrochen.</div>';
|
||||
} catch (Exception $e) {
|
||||
$message = sprintf('<div class="error">Fehler:<br>%s</div>', $e->getMessage());
|
||||
}
|
||||
|
||||
$this->app->Tpl->Set('MESSAGE', $message);
|
||||
$this->app->Tpl->Parse('PAGE', 'googleapi_redirect.tpl');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Action for the printer setup gui to get printer options from api connection
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function GoogleApiAjaxPrinters()
|
||||
{
|
||||
$data = [];
|
||||
$apiName = $this->app->DB->real_escape_string(trim($this->app->Secure->GetPOST('api_name')));
|
||||
if(!empty($apiName)) {
|
||||
$id = $this->getGoogleApiByName($apiName);
|
||||
$token = $this->getAccessToken($id);
|
||||
$authHeader = sprintf('Authorization: Bearer %s', $token);
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [$authHeader]);
|
||||
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION,true);
|
||||
curl_setopt( $ch, CURLOPT_HEADER,false);
|
||||
curl_setopt( $ch, CURLOPT_RETURNTRANSFER,true);
|
||||
curl_setopt( $ch, CURLOPT_HTTPAUTH,CURLAUTH_ANY);
|
||||
curl_setopt( $ch, CURLOPT_URL, 'https://www.google.com/cloudprint/search');
|
||||
curl_setopt( $ch, CURLOPT_POST, true );
|
||||
curl_setopt ( $ch, CURLOPT_POSTFIELDS, ['printerid' => $id]);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$result = json_decode($response, true);
|
||||
|
||||
$printers = $result['printers'];
|
||||
if(!empty($printers)) {
|
||||
foreach ($printers as $item) {
|
||||
$data[$item['id']] = sprintf('%s:%s', $item['displayName'], $item['connectionStatus']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$responseData = json_encode($data);
|
||||
header('Content-Type: application/json');
|
||||
echo $responseData;
|
||||
$this->app->ExitXentral();
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically calls getAccessTokenByRederect if needed.
|
||||
*
|
||||
* @param int $id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAccessToken($id)
|
||||
{
|
||||
$id = (int)$id;
|
||||
$sql = sprintf(
|
||||
'SELECT g.id, g.token, TIMESTAMPDIFF(SECOND, NOW(), g.token_expires) AS expires_in
|
||||
FROM googleapi AS g
|
||||
WHERE g.id = %s;',
|
||||
$id
|
||||
);
|
||||
|
||||
$data = $this->app->DB->SelectRow($sql);
|
||||
if (empty($data) || $data['token'] === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ((int)$data['expires_in'] < 1) {
|
||||
return $this->getAccessTokenByRefresh($id);
|
||||
}
|
||||
|
||||
return $data['token'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Always requests new access token
|
||||
* consider using getAccessToken instead
|
||||
*
|
||||
* @param int $id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAccessTokenByRefresh($id)
|
||||
{
|
||||
$id = (int)$id;
|
||||
$sql = sprintf(
|
||||
'SELECT g.id, g.refresh_token, g.user, g.password FROM googleapi AS g WHERE g.id = %s',
|
||||
$id
|
||||
);
|
||||
$data = $this->app->DB->SelectRow($sql);
|
||||
if (empty($data) || (int)$data['id'] !== $id || $data['refresh_token'] === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$postData = [
|
||||
'refresh_token' => $data['refresh_token'],
|
||||
'client_id' => $data['user'],
|
||||
'client_secret' => $data['password'],
|
||||
'grant_type' => 'refresh_token',
|
||||
];
|
||||
$response = $this->sendGoogleCurl(self::GOOGLE_API_URL_TOKEN_REFRESH, $postData);
|
||||
if (isset($response['error'])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$token = $response['access_token'];
|
||||
$expires = (int)$response['expires_in'] -5;
|
||||
|
||||
if(empty($token) || $expires < 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$updateSql = sprintf(
|
||||
"UPDATE googleapi
|
||||
SET token = '%s', token_expires = DATE_ADD(NOW(),INTERVAL %s SECOND)
|
||||
WHERE id = %s",
|
||||
$token,
|
||||
$expires,
|
||||
$id
|
||||
);
|
||||
$this->app->DB->Update($updateSql);
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getGoogleApiByName($name)
|
||||
{
|
||||
$sql = sprintf(
|
||||
"SELECT g.id
|
||||
FROM googleapi AS g
|
||||
WHERE g.id_name = '%s' AND g.active = 1",
|
||||
$name
|
||||
);
|
||||
$id = (int)$this->app->DB->Select($sql);
|
||||
if ($id < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|string $id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getGoogleApiById($id)
|
||||
{
|
||||
$id = (int)$id;
|
||||
if ($id < 1) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$sql = sprintf(
|
||||
'SELECT g.id, g.id_name, g.description, g.type, g.active, g.user, g.password, g.redirect_uri, g.refresh_token, g.last_auth,
|
||||
g.token, g.token_expires, TIMESTAMPDIFF(SECOND, NOW(), g.token_expires) as expires_in
|
||||
FROM googleapi AS g WHERE g.id = %s ORDER BY g.active DESC LIMIT 1',
|
||||
$id
|
||||
);
|
||||
$result = $this->app->DB->SelectRow($sql);
|
||||
if(empty($result)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|string $id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getGoogleMailApiById($id)
|
||||
{
|
||||
$id = (int)$id;
|
||||
if ($id < 1) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$sql = sprintf(
|
||||
'SELECT g.id, g.id_name, g.description, g.type, g.active, g.user, g.password, g.redirect_uri,
|
||||
gu.refresh_token, g.last_auth,
|
||||
gu.access_token, gu.token_expires, TIMESTAMPDIFF(SECOND, NOW(), gu.token_expires) as expires_in
|
||||
FROM googleapi AS g
|
||||
JOIN googleapi_user AS gu ON gu.googleapi_id_name = g.id_name
|
||||
WHERE g.id = %s ORDER BY g.active DESC LIMIT 1',
|
||||
$id
|
||||
);
|
||||
$result = $this->app->DB->SelectRow($sql);
|
||||
if(empty($result)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param string $messageTarget
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function saveCredentials(Request $request, $messageTarget = 'MESSAGE'): void
|
||||
{
|
||||
$client = $request->post->get('client_id', null);
|
||||
$secret = $request->post->get('secret', null);
|
||||
$redirectUri = $request->post->get('redirect_uri', null);
|
||||
|
||||
$credentials = new GoogleCredentialsData($client, $secret, $redirectUri);
|
||||
$this->credentialsService->saveCredentials($credentials);
|
||||
}
|
||||
|
||||
protected function existTables()
|
||||
{
|
||||
/** @var Database $db */
|
||||
$db = $this->app->Container->get('Database');
|
||||
try {
|
||||
$result = $db->fetchRow('SELECT `id` FROM `google_account` LIMIT 1');
|
||||
$result = $db->fetchRow('SELECT `id` FROM `google_account_property` LIMIT 1');
|
||||
$result = $db->fetchRow('SELECT `id` FROM `google_account_scope` LIMIT 1');
|
||||
$result = $db->fetchRow('SELECT `id` FROM `google_access_token` LIMIT 1');
|
||||
$result = $db->fetchRow('SELECT `id` FROM `googleapi_calendar_sync` LIMIT 1');
|
||||
} catch (Exception $e) {
|
||||
$this->Install();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If data in the old Googleapi structure exists, migrate to new structure and cancel all
|
||||
* client connections
|
||||
*/
|
||||
protected function migrate()
|
||||
{
|
||||
/** @var Database $db */
|
||||
$db = $this->app->Container->get('Database');
|
||||
|
||||
// Try to find api account and take the first active one and save it in the new Structure
|
||||
try {
|
||||
$credentials = $db->fetchRow(
|
||||
'SELECT g.user, g.password, g.redirect_uri FROM `googleapi` AS `g` WHERE g.active = 1 LIMIT 1'
|
||||
);
|
||||
/** @var GoogleCredentialsService $credentialsService */
|
||||
$credentialsService = $this->app->Container->get('GoogleCredentialsService');
|
||||
if (!empty($credentials) && !$credentialsService->existCredentials()) {
|
||||
$credentialsService->saveCredentials(
|
||||
new GoogleCredentialsData(
|
||||
$credentials['user'],
|
||||
$credentials['password'],
|
||||
$credentials['redirect_uri']
|
||||
)
|
||||
);
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
}
|
||||
|
||||
//Find googleapi_user entries
|
||||
try {
|
||||
$rows = $db->fetchAll("SELECT u.id, u.refresh_token
|
||||
FROM `googleapi_user` AS `u`
|
||||
WHERE u.refresh_token != ''");
|
||||
$db->perform("UPDATE `googleapi_user` SET refresh_token = '' WHERE 1");
|
||||
} catch (Throwable $e) {
|
||||
$rows = [];
|
||||
}
|
||||
|
||||
//quit the connections
|
||||
/** @var GoogleAuthorizationService $authService */
|
||||
$authService = $this->app->Container->get('GoogleAuthorizationService');
|
||||
foreach ($rows as $row) {
|
||||
try {
|
||||
if (!empty($row['refresh_token'])) {
|
||||
$authService->revokeToken($row['refresh_token']);
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends initial authentification request to Google.
|
||||
*
|
||||
* Request is GET method and redirects the xentral user to Google to
|
||||
* manually allow access to Google API.
|
||||
* When user allowed access Google will redirect to xentral (see GoogleApiRedirect)
|
||||
*
|
||||
* @param string $clientId
|
||||
* @param string $type
|
||||
* @param string $redirectUri
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function requestGoogleAuthCode($clientId, $type, $redirectUri = '')
|
||||
{
|
||||
if (empty($redirectUri)) {
|
||||
$redirectUri = $this->getDefaultRedirectUri();
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case 'print':
|
||||
$scope = self::GOOGLE_API_SCOPE_PRINT;
|
||||
|
||||
break;
|
||||
|
||||
case 'mail':
|
||||
$scope = self::GOOGLE_API_SCOPE_MAIL;
|
||||
|
||||
break;
|
||||
|
||||
case 'calendar':
|
||||
$scope = self::GOOGLE_API_SCOPE_CALENDAR;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
$scope = '';
|
||||
}
|
||||
|
||||
$params = [
|
||||
'client_id' => $clientId,
|
||||
'redirect_uri' => $redirectUri,
|
||||
'response_type' => 'code',
|
||||
'scope' => $scope,
|
||||
'access_type' => 'offline',
|
||||
];
|
||||
|
||||
$redirect = sprintf('location: %s?%s', self::GOOGLE_API_URL_AUTH, http_build_query($params));
|
||||
header($redirect);
|
||||
$this->app->ExitXentral();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function closeApiConnection($id)
|
||||
{
|
||||
$data = $this->getGoogleApiById($id);
|
||||
if (empty($data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($data['type'] === 'mail') {
|
||||
$users = $this->gateway->getApiUsersByAccount($data['id_name']);
|
||||
if (count($users) > 0) {
|
||||
$this->auth->removeUserToken($users[0]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!empty($data['token'])) {
|
||||
$this->revokeToken($data['token']);
|
||||
$updateSql = sprintf(
|
||||
'UPDATE googleapi
|
||||
SET token = NULL, token_expires = NULL
|
||||
WHERE id = %s',
|
||||
$id
|
||||
);
|
||||
$this->app->DB->Update($updateSql);
|
||||
}
|
||||
|
||||
if (!empty($data['refresh_token'])) {
|
||||
$this->revokeToken($data['refresh_token']);
|
||||
$updateSql = sprintf(
|
||||
'UPDATE googleapi
|
||||
SET token = NULL, token_expires = NULL, refresh_token = NULL
|
||||
WHERE id = %s',
|
||||
$id
|
||||
);
|
||||
$this->app->DB->Update($updateSql);
|
||||
}
|
||||
|
||||
if(!empty($data['token']) || !empty($data['refresh_token'])) {
|
||||
$redirect = sprintf('location: ?module=googleapi&action=edit&id=%s', $id);
|
||||
header($redirect);
|
||||
$this->app->ExitXentral();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function authorize(string $scope): void
|
||||
{
|
||||
/** @var Session $session */
|
||||
$session = $this->app->Container->get('Session');
|
||||
$redirect = $this->auth->requestScopeAuthorization(
|
||||
$session,
|
||||
[$scope],
|
||||
'index.php?module=googleapi&action=edit'
|
||||
);
|
||||
SessionHandler::commitSession($session);
|
||||
$redirect->send();
|
||||
$this->app->ExitXentral();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function unauthorize(): void
|
||||
{
|
||||
try {
|
||||
$account = $this->gateway->getAccountByUser((int)$this->app->User->GetID());
|
||||
} catch (GoogleAccountNotFoundException $e) {
|
||||
$this->app->Tpl->Add('MESSAGE', '<div class="info">Keine Verbindung vorhanden.</div>');
|
||||
return;
|
||||
}
|
||||
$this->auth->revokeAuthorization($account);
|
||||
$this->app->Tpl->Add('MESSAGE', '<div class="info">Verbindung zu Google beendet.</div>');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $token
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function revokeToken($token)
|
||||
{
|
||||
if (empty($token)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$url = sprintf('%s?token=%s', self::GOOGLE_API_URL_TOKEN_REVOKE, $token);
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
$response = curl_exec($ch);
|
||||
$info = curl_getinfo($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if ((int)$info['http_code'] === 200) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param string $messageTarget
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function testApiConnection($id, $messageTarget = '')
|
||||
{
|
||||
$id = (int)$id;
|
||||
$api = $this->gateway->getApiAccount();
|
||||
|
||||
if ($api !== null && $api->getType() === 'mail') {
|
||||
$users = $this->gateway->getApiUsersByAccount($api->getIdName());
|
||||
$token = '';
|
||||
if (count($users) > 0) {
|
||||
$token = $users[0]->getAccessToken();
|
||||
}
|
||||
} else {
|
||||
$token = $this->getAccessToken($id);
|
||||
}
|
||||
|
||||
if ($token === '') {
|
||||
$this->app->Tpl->Add(
|
||||
$messageTarget,
|
||||
'<div class="error">Kein gültiges Access Token vorhanden</div>'
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$type = $this->app->DB->Select(sprintf("SELECT g.type FROM googleapi AS g WHERE g.id = '%s';", $id));
|
||||
switch ($type) {
|
||||
case 'print':
|
||||
$testurl = self::GOOGLE_API_TESTURL_PRINT;
|
||||
break;
|
||||
|
||||
case 'mail':
|
||||
$this->app->Tpl->Add(
|
||||
$messageTarget,
|
||||
'<div class="info">Die Verbindung zu Google Mail kann hier nicht getestet werden. Versenden Sie stattdessen eine Test-Email.</div>'
|
||||
);
|
||||
return true;
|
||||
break;
|
||||
|
||||
case 'calendar':
|
||||
$testurl = self::GOOGLE_API_TESTURL_CALENDAR;
|
||||
break;
|
||||
|
||||
default:
|
||||
$testurl = '';
|
||||
}
|
||||
|
||||
$authHeader = sprintf('Authorization: Bearer %s', $token);
|
||||
$ch = curl_init($testurl);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [$authHeader]);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
$response = curl_exec($ch);
|
||||
$info = curl_getinfo($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if ((int)$info['http_code'] !== 200) {
|
||||
$error = sprintf('Test fehlgeschlagen: ERROR %s %s', $info['http_code'], $response['error']);
|
||||
$this->app->Tpl->Add(
|
||||
$messageTarget,
|
||||
sprintf('<div class="error">%s</div>', $error)
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($type === 'print' &&
|
||||
(!isset($info['content_type']) || explode(';', $info['content_type'])[0] !== 'text/plain')
|
||||
) {
|
||||
$error = 'Test fehlgeschlagen: Fehlerhafte Antwort vom Server';
|
||||
$this->app->Tpl->Add(
|
||||
$messageTarget,
|
||||
sprintf('<div class="error">%s</div>', $error)
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($type === 'mail' &&
|
||||
(!isset($info['content_type']) || explode(';', $info['content_type'])[0] !== 'text/plain')
|
||||
) {
|
||||
$error = 'Test fehlgeschlagen: Fehlerhafte Antwort vom Server';
|
||||
$this->app->Tpl->Add(
|
||||
$messageTarget,
|
||||
sprintf('<div class="error">%s</div>', $error)
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($type === 'calendar' &&
|
||||
(!isset($info['content_type']) || explode(';', $info['content_type'])[0] !== 'application/json')
|
||||
) {
|
||||
$error = 'Test fehlgeschlagen: Fehlerhafte Antwort vom Server';
|
||||
$this->app->Tpl->Add(
|
||||
$messageTarget,
|
||||
sprintf('<div class="error">%s</div>', $error)
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->app->Tpl->Add(
|
||||
$messageTarget,
|
||||
'<div class="info">Test der Verbindung war erfolgreich.</div>'
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param array $postData
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function sendGoogleCurl($url, $postData = [])
|
||||
{
|
||||
$ch = curl_init();
|
||||
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION,true);
|
||||
curl_setopt( $ch, CURLOPT_HEADER,false);
|
||||
curl_setopt( $ch, CURLOPT_RETURNTRANSFER,true);
|
||||
//curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt( $ch, CURLOPT_HTTPAUTH,CURLAUTH_ANY);
|
||||
curl_setopt( $ch, CURLOPT_URL, $url);
|
||||
curl_setopt( $ch, CURLOPT_POST, true );
|
||||
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $postData);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$info = curl_getinfo($ch);
|
||||
$result = json_decode($response, true);
|
||||
if ($response === false) {
|
||||
$result = ['error' => 'error in curl request'];
|
||||
}
|
||||
|
||||
if((int)$info['http_code'] !== 200){
|
||||
$result['http_code'] = $info['http_code'];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function createMenu()
|
||||
{
|
||||
$this->app->erp->MenuEintrag('index.php?module=googleapi&action=list',
|
||||
'Zurück zur Übersicht');
|
||||
$this->app->erp->MenuEintrag('index.php?module=googleapi&action=list', 'Übersicht');
|
||||
$this->app->erp->MenuEintrag('index.php?module=googleapi&action=print', 'Google Cloud Print');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user