Skip to content

Commit

Permalink
feat: per account imap and smtp debugging
Browse files Browse the repository at this point in the history
Signed-off-by: SebastianKrupinski <krupinskis05@gmail.com>
  • Loading branch information
SebastianKrupinski committed Oct 28, 2024
1 parent a137752 commit 7a4dbb7
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 4 deletions.
1 change: 1 addition & 0 deletions appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ Learn more about the Nextcloud Ethical AI Rating [in our blog](https://nextcloud
<command>OCA\Mail\Command\CleanUp</command>
<command>OCA\Mail\Command\CreateAccount</command>
<command>OCA\Mail\Command\CreateTagMigrationJobEntry</command>
<command>OCA\Mail\Command\DebugAccount</command>
<command>OCA\Mail\Command\DeleteAccount</command>
<command>OCA\Mail\Command\DiagnoseAccount</command>
<command>OCA\Mail\Command\ExportAccount</command>
Expand Down
7 changes: 7 additions & 0 deletions lib/Account.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ public function getUserId() {
return $this->account->getUserId();
}

/**
* @return string

Check failure on line 65 in lib/Account.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

InvalidReturnType

lib/Account.php:65:13: InvalidReturnType: The declared return type 'string' for OCA\Mail\Account::getDebug is incorrect, got 'int' (see https://psalm.dev/011)
*/
public function getDebug() {
return $this->account->getDebug();

Check failure on line 68 in lib/Account.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

InvalidReturnStatement

lib/Account.php:68:10: InvalidReturnStatement: The inferred type 'int' does not match the declared return type 'string' for OCA\Mail\Account::getDebug (see https://psalm.dev/128)
}

/**
* Set the quota percentage
* @param Quota $quota
Expand Down
78 changes: 78 additions & 0 deletions lib/Command/DebugAccount.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Mail\Command;

use OCA\Mail\Service\AccountService;
use OCP\AppFramework\Db\DoesNotExistException;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class DebugAccount extends Command {
protected const ARGUMENT_ACCOUNT_ID = 'account-id';
protected const OPTION_IMAP_DEFAULT = 'imap';
protected const OPTION_IMAP_FULL = 'imap-full';
protected const OPTION_SMTP_DEFAULT = 'smtp';

public function __construct(
private AccountService $accountService,
private LoggerInterface $logger,
) {
parent::__construct();
}

/**
* @return void
*/
protected function configure() {
$this->setName('mail:account:debug');
$this->setDescription('Enable or Disable IMAP/SMTP debugging on a account');
$this->addArgument(self::ARGUMENT_ACCOUNT_ID, InputArgument::REQUIRED);
$this->addOption(self::OPTION_IMAP_DEFAULT, null, InputOption::VALUE_NONE);
$this->addOption(self::OPTION_IMAP_FULL, null, InputOption::VALUE_NONE);
$this->addOption(self::OPTION_SMTP_DEFAULT, null, InputOption::VALUE_NONE);
}

protected function execute(InputInterface $input, OutputInterface $output): int {
$accountId = (int)$input->getArgument(self::ARGUMENT_ACCOUNT_ID);
$imapDefault = $input->getOption(self::OPTION_IMAP_DEFAULT);
$imapFull = $input->getOption(self::OPTION_IMAP_FULL);
$smtpDefault = $input->getOption(self::OPTION_SMTP_DEFAULT);
$debug = 0;
$debugImapDefault = 1 << 0; // 1 (0000 0001)
$debugImapFull = 1 << 1; // 2 (0000 0010)
$debugSmtpDefault = 1 << 4; // 16 (0001 0000)

try {
$account = $this->accountService->findById($accountId)->getMailAccount();
} catch (DoesNotExistException $e) {
$output->writeln("<error>Account $accountId does not exist</error>");
return 1;
}

if ($imapDefault) {
$debug += $debugImapDefault;
} elseif ($imapFull) {
$debug += $debugImapFull;
}

if ($smtpDefault) {
$debug += $debugSmtpDefault;
}

$account->setDebug($debug);
$this->accountService->save($account);

return 0;
}
}
9 changes: 9 additions & 0 deletions lib/Db/MailAccount.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@
* @method void setSearchBody(bool $searchBody)
* @method bool|null getOooFollowsSystem()
* @method void setOooFollowsSystem(bool $oooFollowsSystem)
* @method int getDebug()
* @method void setDebug(int $debug)
*/
class MailAccount extends Entity {
public const SIGNATURE_MODE_PLAIN = 0;
Expand Down Expand Up @@ -183,6 +185,8 @@ class MailAccount extends Entity {
/** @var bool|null */
protected $oooFollowsSystem;

protected int $debug = 0;

/**
* @param array $params
*/
Expand Down Expand Up @@ -240,6 +244,9 @@ public function __construct(array $params = []) {
if (isset($params['outOfOfficeFollowsSystem'])) {
$this->setOutOfOfficeFollowsSystem($params['outOfOfficeFollowsSystem']);
}
if (isset($params['debug'])) {
$this->setDebug($params['debug']);
}

$this->addType('inboundPort', 'integer');
$this->addType('outboundPort', 'integer');
Expand All @@ -263,6 +270,7 @@ public function __construct(array $params = []) {
$this->addType('junkMailboxId', 'integer');
$this->addType('searchBody', 'boolean');
$this->addType('oooFollowsSystem', 'boolean');
$this->addType('debug', 'integer');
}

public function getOutOfOfficeFollowsSystem(): bool {
Expand Down Expand Up @@ -310,6 +318,7 @@ public function toJson() {
'junkMailboxId' => $this->getJunkMailboxId(),
'searchBody' => $this->getSearchBody(),
'outOfOfficeFollowsSystem' => $this->getOutOfOfficeFollowsSystem(),
'debug' => $this->getDebug(),
];

if (!is_null($this->getOutboundHost())) {
Expand Down
12 changes: 10 additions & 2 deletions lib/IMAP/IMAPClientFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ class IMAPClientFactory {
private ITimeFactory $timeFactory;
private HordeCacheFactory $hordeCacheFactory;

private int $debugDefault = 1 << 0; // 1 (0000 0001)
private int $debugFull = 1 << 1; // 2 (0000 0010)

public function __construct(ICrypto $crypto,
IConfig $config,
ICacheFactory $cacheFactory,
Expand Down Expand Up @@ -117,8 +120,13 @@ public function getClient(Account $account, bool $useCache = true): Horde_Imap_C
'backend' => $this->hordeCacheFactory->newCache($account),
];
}
if ($this->config->getSystemValue('debug', false)) {
$params['debug'] = $this->config->getSystemValue('datadirectory') . '/horde_imap.log';
$debug = $account->getDebug();
if ($debug & $this->debugDefault || $debug & $this->debugFull) {

Check failure on line 124 in lib/IMAP/IMAPClientFactory.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

InvalidOperand

lib/IMAP/IMAPClientFactory.php:124:7: InvalidOperand: Cannot perform a numeric operation with a non-numeric type string (see https://psalm.dev/058)

Check failure on line 124 in lib/IMAP/IMAPClientFactory.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

InvalidOperand

lib/IMAP/IMAPClientFactory.php:124:39: InvalidOperand: Cannot perform a numeric operation with a non-numeric type string (see https://psalm.dev/058)
$fn = 'mail-' . $account->getUserId() . '-' . $account->getId() . '-imap.log';
$params['debug'] = $this->config->getSystemValue('datadirectory') . '/' . $fn;
if ($debug & $this->debugFull) {

Check failure on line 127 in lib/IMAP/IMAPClientFactory.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

InvalidOperand

lib/IMAP/IMAPClientFactory.php:127:8: InvalidOperand: Cannot perform a numeric operation with a non-numeric type string (see https://psalm.dev/058)
$params['debug_literal'] = true;
}
}

$client = new HordeImapClient($params);
Expand Down
38 changes: 38 additions & 0 deletions lib/Migration/Version4100Date20241028000000.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Mail\Migration;

use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;

class Version4100Date20241028000000 extends SimpleMigrationStep {

/**
* @param IOutput $output
* @param Closure(): ISchemaWrapper $schemaClosure
* @param array $options
* @return null|ISchemaWrapper
*/
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
$schema = $schemaClosure();

$accountsTable = $schema->getTable('mail_accounts');
if (!$accountsTable->hasColumn('debug')) {
$accountsTable->addColumn('debug', Types::SMALLINT, [
'notnull' => false,
'default' => 0,
]);
}
return $schema;
}
}
7 changes: 5 additions & 2 deletions lib/SMTP/SmtpClientFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class SmtpClientFactory {
/** @var HostNameFactory */
private $hostNameFactory;

private int $debugDefault = 1 << 4; // 16 (0001 0000)

public function __construct(IConfig $config,
ICrypto $crypto,
HostNameFactory $hostNameFactory) {
Expand Down Expand Up @@ -77,8 +79,9 @@ public function create(Account $account): Horde_Mail_Transport {
$decryptedAccessToken,
);
}
if ($this->config->getSystemValue('debug', false)) {
$params['debug'] = $this->config->getSystemValue('datadirectory') . '/horde_smtp.log';
if ($account->getDebug() & $this->debugDefault) {

Check failure on line 82 in lib/SMTP/SmtpClientFactory.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

InvalidOperand

lib/SMTP/SmtpClientFactory.php:82:7: InvalidOperand: Cannot perform a numeric operation with a non-numeric type string (see https://psalm.dev/058)
$fn = 'mail-' . $account->getUserId() . '-' . $account->getId() . '-smtp.log';
$params['debug'] = $this->config->getSystemValue('datadirectory') . '/' . $fn;
}
return new Horde_Mail_Transport_Smtphorde($params);
}
Expand Down

0 comments on commit 7a4dbb7

Please sign in to comment.