Add Google OAuth token refresh

Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
This commit is contained in:
Christoph Wurst 2022-10-18 09:31:18 +02:00
Родитель da07d90d76
Коммит b63dfd6056
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: CC42AC2A7F0E56D8
5 изменённых файлов: 125 добавлений и 2 удалений

Просмотреть файл

@ -34,6 +34,7 @@ use OCA\Mail\Contracts\ITrustedSenderService;
use OCA\Mail\Contracts\IUserPreferences;
use OCA\Mail\Dashboard\ImportantMailWidget;
use OCA\Mail\Dashboard\UnreadMailWidget;
use OCA\Mail\Events\BeforeImapClientCreated;
use OCA\Mail\Events\BeforeMessageSentEvent;
use OCA\Mail\Events\DraftMessageCreatedEvent;
use OCA\Mail\Events\DraftSavedEvent;
@ -50,6 +51,7 @@ use OCA\Mail\Http\Middleware\ProvisioningMiddleware;
use OCA\Mail\Listener\AddressCollectionListener;
use OCA\Mail\Listener\AntiAbuseListener;
use OCA\Mail\Listener\HamReportListener;
use OCA\Mail\Listener\OauthTokenRefreshListener;
use OCA\Mail\Listener\SpamReportListener;
use OCA\Mail\Listener\DeleteDraftListener;
use OCA\Mail\Listener\FlagRepliedMessageListener;
@ -104,6 +106,7 @@ class Application extends App implements IBootstrap {
$context->registerServiceAlias(ITrustedSenderService::class, TrustedSenderService::class);
$context->registerServiceAlias(IUserPreferences::class, UserPreferenceService::class);
$context->registerEventListener(BeforeImapClientCreated::class, OauthTokenRefreshListener::class);
$context->registerEventListener(BeforeMessageSentEvent::class, AntiAbuseListener::class);
$context->registerEventListener(DraftSavedEvent::class, DeleteDraftListener::class);
$context->registerEventListener(DraftMessageCreatedEvent::class, DeleteDraftListener::class);

Просмотреть файл

@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
/*
* @copyright 2022 Christoph Wurst <christoph@winzerhof-wurst.at>
*
* @author 2022 Christoph Wurst <christoph@winzerhof-wurst.at>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace OCA\Mail\Events;
use OCA\Mail\Account;
use OCP\EventDispatcher\Event;
class BeforeImapClientCreated extends Event {
/** @var Account */
private $account;
public function __construct(Account $account) {
parent::__construct();
$this->account = $account;
}
/**
* @return Account
*/
public function getAccount(): Account {
return $this->account;
}
}

Просмотреть файл

@ -28,6 +28,8 @@ use Horde_Imap_Client_Password_Xoauth2;
use Horde_Imap_Client_Socket;
use OCA\Mail\Account;
use OCA\Mail\Cache\Cache;
use OCA\Mail\Events\BeforeImapClientCreated;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\ICacheFactory;
use OCP\IConfig;
use OCP\Security\ICrypto;
@ -42,15 +44,22 @@ class IMAPClientFactory {
/** @var ICacheFactory */
private $cacheFactory;
/** @var IEventDispatcher */
private $eventDispatcher;
/**
* @param ICrypto $crypto
* @param IConfig $config
* @param ICacheFactory $cacheFactory
*/
public function __construct(ICrypto $crypto, IConfig $config, ICacheFactory $cacheFactory) {
public function __construct(ICrypto $crypto,
IConfig $config,
ICacheFactory $cacheFactory,
IEventDispatcher $eventDispatcher) {
$this->crypto = $crypto;
$this->config = $config;
$this->cacheFactory = $cacheFactory;
$this->eventDispatcher = $eventDispatcher;
}
/**
@ -65,6 +74,9 @@ class IMAPClientFactory {
* @return Horde_Imap_Client_Socket
*/
public function getClient(Account $account, bool $useCache = true): Horde_Imap_Client_Socket {
$this->eventDispatcher->dispatchTyped(
new BeforeImapClientCreated($account)
);
$host = $account->getMailAccount()->getInboundHost();
$user = $account->getMailAccount()->getInboundUser();
$decryptedPassword = $this->crypto->decrypt($account->getMailAccount()->getInboundPassword());

Просмотреть файл

@ -0,0 +1,55 @@
<?php
declare(strict_types=1);
/*
* @copyright 2022 Christoph Wurst <christoph@winzerhof-wurst.at>
*
* @author 2022 Christoph Wurst <christoph@winzerhof-wurst.at>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace OCA\Mail\Listener;
use OCA\Mail\Events\BeforeImapClientCreated;
use OCA\Mail\Integration\GoogleIntegration;
use OCA\Mail\Service\AccountService;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
class OauthTokenRefreshListener implements IEventListener {
private GoogleIntegration $googleIntegration;
private AccountService $accountService;
public function __construct(GoogleIntegration $googleIntegration,
AccountService $accountService) {
$this->googleIntegration = $googleIntegration;
$this->accountService = $accountService;
}
public function handle(Event $event): void {
if (!($event instanceof BeforeImapClientCreated)) {
return;
}
if (!$this->googleIntegration->isGoogleOauthAccount($event->getAccount())) {
return;
}
$updated = $this->googleIntegration->refresh($event->getAccount());
$this->accountService->update($updated->getMailAccount());
}
}

Просмотреть файл

@ -29,6 +29,7 @@ use OCA\Mail\Account;
use OCA\Mail\Db\MailAccount;
use OCA\Mail\IMAP\IMAPClientFactory;
use ChristophWurst\Nextcloud\Testing\TestCase;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\ICacheFactory;
use OCP\IConfig;
use OCP\Security\ICrypto;
@ -53,8 +54,14 @@ class IMAPClientFactoryTest extends TestCase {
$this->crypto = $this->createMock(ICrypto::class);
$this->config = $this->createMock(IConfig::class);
$this->cacheFactory = $this->createMock(ICacheFactory::class);
$this->eventDispatcher = $this->createMock(IEventDispatcher::class);
$this->factory = new IMAPClientFactory($this->crypto, $this->config, $this->cacheFactory);
$this->factory = new IMAPClientFactory(
$this->crypto,
$this->config,
$this->cacheFactory,
$this->eventDispatcher,
);
}
/**