mirror of
https://github.com/OpenXE-org/OpenXE.git
synced 2024-12-26 22:50:29 +01:00
265 lines
8.4 KiB
PHP
265 lines
8.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Xentral\Modules\GoogleApi\Service;
|
|
|
|
use Exception;
|
|
use Xentral\Components\Database\Database;
|
|
use Xentral\Modules\GoogleApi\Data\GoogleAccessTokenData;
|
|
use Xentral\Modules\GoogleApi\Data\GoogleAccountPropertyValue;
|
|
use Xentral\Modules\GoogleApi\Data\GoogleAccountPropertyCollection;
|
|
use Xentral\Modules\GoogleApi\Data\GoogleAccountData;
|
|
use Xentral\Modules\GoogleApi\Exception\GoogleAccountAlreadyExistsException;
|
|
use Xentral\Modules\GoogleApi\Exception\GoogleAccountDeleteException;
|
|
use Xentral\Modules\GoogleApi\Exception\GoogleAccountNotFoundException;
|
|
use Xentral\Modules\GoogleApi\Exception\InvalidArgumentException;
|
|
|
|
final class GoogleAccountService
|
|
{
|
|
/** @var GoogleAccountGateway $gateway */
|
|
private $gateway;
|
|
|
|
/** @var Database $db */
|
|
private $db;
|
|
|
|
/**
|
|
* @param GoogleAccountGateway $gateway
|
|
* @param Database $database
|
|
*/
|
|
public function __construct(GoogleAccountGateway $gateway, Database $database)
|
|
{
|
|
$this->gateway = $gateway;
|
|
$this->db = $database;
|
|
}
|
|
|
|
/**
|
|
* @param int $userId
|
|
* @param string|null $identifier
|
|
* @param string|null $refreshToken
|
|
*
|
|
* @throws InvalidArgumentException
|
|
* @throws GoogleAccountAlreadyExistsException
|
|
* @throws GoogleAccountNotFoundException
|
|
*
|
|
* @return GoogleAccountData
|
|
*/
|
|
public function createAccount(int $userId, ?string $identifier, string $refreshToken = null): GoogleAccountData
|
|
{
|
|
if ($userId < 1) {
|
|
throw new InvalidArgumentException('Cannot create Google Account without User Id.');
|
|
}
|
|
try {
|
|
$this->gateway->getAccountByUser($userId);
|
|
throw new GoogleAccountAlreadyExistsException('A Google account already exists for this user.');
|
|
} catch (GoogleAccountNotFoundException $e) {
|
|
}
|
|
|
|
$account = new GoogleAccountData(null, $userId, $identifier, $refreshToken);
|
|
$id = $this->insertAccount($account);
|
|
|
|
return $this->gateway->getAccount($id);
|
|
}
|
|
|
|
/**
|
|
* @param GoogleAccountData $account
|
|
*
|
|
* @return int
|
|
*/
|
|
public function saveAccount(GoogleAccountData $account): int
|
|
{
|
|
if ($account->getId() === null || !$this->gateway->existsAccount($account->getId())) {
|
|
return $this->insertAccount($account);
|
|
}
|
|
|
|
return $this->updateAccount($account);
|
|
}
|
|
|
|
/**
|
|
* Deletes the google user account entry and all associated tokens, scopes and properties
|
|
*
|
|
* @param int $id
|
|
*
|
|
* @throws GoogleAccountDeleteException
|
|
*
|
|
* @return void
|
|
*/
|
|
public function deleteAccount(int $id): void
|
|
{
|
|
$this->db->beginTransaction();
|
|
try {
|
|
$queries = [
|
|
'DELETE FROM `google_account` WHERE `id` = :id',
|
|
'DELETE FROM `google_access_token` WHERE `google_account_id` = :id',
|
|
'DELETE FROM `google_account_property` WHERE `google_account_id` = :id',
|
|
'DELETE FROM `google_account_scope` WHERE `google_account_id` = :id',
|
|
];
|
|
foreach ($queries as $sql) {
|
|
$this->db->perform($sql, ['id' => $id]);
|
|
}
|
|
} catch (Exception $e) {
|
|
$this->db->rollBack();
|
|
throw new GoogleAccountDeleteException('Could not Delete Google Account', $e->getCode(), $e);
|
|
}
|
|
$this->db->commit();
|
|
}
|
|
|
|
/**
|
|
* @param GoogleAccessTokenData $token
|
|
*
|
|
* @return void
|
|
*/
|
|
public function saveAccessToken(GoogleAccessTokenData $token): void
|
|
{
|
|
$values = $token->toArray();
|
|
$update = 'UPDATE `google_access_token`
|
|
SET `token` = :token, `expires` = :expires
|
|
WHERE `google_account_id` = :google_account_id';
|
|
$affected = $this->db->fetchAffected($update, $values);
|
|
if ($affected > 0) {
|
|
return;
|
|
}
|
|
$insert = 'INSERT INTO `google_access_token` (`google_account_id`, `token`, `expires`)
|
|
VALUES (:google_account_id, :token, :expires)';
|
|
$this->db->perform($insert, $values);
|
|
}
|
|
|
|
/**
|
|
* @param GoogleAccessTokenData $token
|
|
*
|
|
* @return void
|
|
*/
|
|
public function deleteAccessToken(GoogleAccessTokenData $token): void
|
|
{
|
|
$sql = 'DELETE FROM `google_access_token` WHERE `google_account_id` = :google_account_id';
|
|
$this->db->perform($sql, $token->toArray());
|
|
}
|
|
|
|
/**
|
|
* @param int $accountId
|
|
* @param GoogleAccountPropertyCollection $properties
|
|
*
|
|
* @return void
|
|
*/
|
|
public function saveAccountProperties(int $accountId, GoogleAccountPropertyCollection $properties): void
|
|
{
|
|
foreach ($properties->getAll() as $key => $property) {
|
|
if ($property === null) {
|
|
$this->deleteProperty($accountId, $key);
|
|
continue;
|
|
}
|
|
if ($property->getId() === null) {
|
|
$this->insertProperty($accountId, $property);
|
|
continue;
|
|
}
|
|
$this->updateProperty($accountId, $property);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param int $accountId
|
|
* @param string $scope
|
|
*
|
|
* @return void
|
|
*/
|
|
public function saveAccountScope(int $accountId, string $scope): void
|
|
{
|
|
$existingScopes = $this->gateway->getScopes($accountId);
|
|
if (in_array($scope, $existingScopes, true)) {
|
|
return;
|
|
}
|
|
$sql = 'INSERT INTO `google_account_scope` (`google_account_id`, `scope`)
|
|
VALUES (:account_id, :scope)';
|
|
$this->db->perform($sql, ['account_id' => $accountId, 'scope' => $scope]);
|
|
}
|
|
|
|
/**
|
|
* @param int $accountId
|
|
*
|
|
* @return void
|
|
*/
|
|
public function deleteAccountScopes(int $accountId): void
|
|
{
|
|
$sql = 'DELETE FROM `google_account_scope` WHERE `google_account_id` = :account_id';
|
|
$this->db->perform($sql, ['account_id' => $accountId]);
|
|
}
|
|
|
|
/**
|
|
* @param GoogleAccountData $account
|
|
*
|
|
* @return int
|
|
*/
|
|
private function insertAccount(GoogleAccountData $account): int
|
|
{
|
|
$sql = 'INSERT INTO `google_account` (`user_id`, `refresh_token`, `identifier`) VALUES
|
|
(:user_id, :refresh_token, :identifier)';
|
|
$values = $account->toArray();
|
|
$this->db->perform($sql, $values);
|
|
|
|
return $this->db->lastInsertId();
|
|
}
|
|
|
|
/**
|
|
* @param GoogleAccountData $account
|
|
*
|
|
* @return int
|
|
*/
|
|
private function updateAccount(GoogleAccountData $account): int
|
|
{
|
|
$sql = 'UPDATE `google_account` SET
|
|
`user_id` = :user_id,
|
|
`identifier` = :identifier,
|
|
`refresh_token` = :refresh_token
|
|
WHERE `id` = :id';
|
|
$values = $account->toArray();
|
|
$this->db->perform($sql, $values);
|
|
|
|
return $account->getId();
|
|
}
|
|
|
|
/**
|
|
* @param int $accountId
|
|
* @param GoogleAccountPropertyValue $property
|
|
*
|
|
* @return void
|
|
*/
|
|
private function insertProperty(int $accountId, GoogleAccountPropertyValue $property): void
|
|
{
|
|
$sql = 'INSERT INTO `google_account_property` (`google_account_id`, `varname`, `value`)
|
|
VALUES (:account_id, :varname, :value)';
|
|
$values = $property->toArray();
|
|
$values['account_id'] = $accountId;
|
|
$this->db->perform($sql, $values);
|
|
}
|
|
|
|
/**
|
|
* @param int $accountId
|
|
* @param GoogleAccountPropertyValue $property
|
|
*
|
|
* @return void
|
|
*/
|
|
private function updateProperty(int $accountId, GoogleAccountPropertyValue $property): void
|
|
{
|
|
$sql = 'UPDATE `google_account_property`
|
|
SET `google_account_id` = :account_id, `varname` = :varname, `value` = :value
|
|
WHERE `id` = :id';
|
|
$values = $property->toArray();
|
|
$values['account_id'] = $accountId;
|
|
$this->db->perform($sql, $values);
|
|
}
|
|
|
|
/**
|
|
* @param int $accountId
|
|
* @param string $varname
|
|
*
|
|
* @return void
|
|
*/
|
|
private function deleteProperty(int $accountId, string $varname): void
|
|
{
|
|
$sql = 'DELETE FROM `google_account_property`
|
|
WHERE `google_account_id` = :account_id AND `varname` = :varname';
|
|
$values = ['account_id' => $accountId, 'varname' => $varname];
|
|
$this->db->perform($sql, $values);
|
|
}
|
|
}
|