-
Notifications
You must be signed in to change notification settings - Fork 263
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: per account imap and smtp debugging #10301
base: main
Are you sure you want to change the base?
Changes from 12 commits
421a8dc
f832baa
3f64efd
29e8e0b
97a09c0
7aa605d
34aa301
7cc73f6
21c5495
378fa95
6f37da9
2c0f6fe
131fcea
565737f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
<?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'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about Sieve? ;) It's using the SieveClientFactory There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I looked at the SieveClientFactory, it will need to be refactored first, so I thought it would be best to add sieve in a separate PR. |
||
|
||
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 = []; | ||
|
||
try { | ||
$account = $this->accountService->findById($accountId)->getMailAccount(); | ||
} catch (DoesNotExistException $e) { | ||
$output->writeln("<error>Account $accountId does not exist</error>"); | ||
return 1; | ||
} | ||
|
||
if ($imapDefault) { | ||
$debug[] = 'imap'; | ||
} elseif ($imapFull) { | ||
$debug[] = 'imap-full'; | ||
} | ||
|
||
if ($smtpDefault) { | ||
$debug[] = 'smtp'; | ||
} | ||
|
||
$account->setDebug(implode('|', $debug)); | ||
$this->accountService->save($account); | ||
|
||
return 0; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -117,8 +117,16 @@ | |
'backend' => $this->hordeCacheFactory->newCache($account), | ||
]; | ||
} | ||
if ($this->config->getSystemValue('debug', false)) { | ||
$params['debug'] = $this->config->getSystemValue('datadirectory') . '/horde_imap.log'; | ||
$debug = array_merge( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we decide to keep the protocol option, then this code should go into a small service or into the account object. classDiagram
class DebugHelper
DebugHelper : +debugImap(account) bool
DebugHelper : +debugSmtp(account) bool
DebugHelper : +debugSieve(account) bool
DebugHelper : +fileNameImap(account) string
DebugHelper : +fileNameSmtp(account) string
DebugHelper : +fileNameSieve(account) string
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, that can be done. Let see what the rest think. |
||
explode('|', $this->config->getSystemValueString('MAIL_DEBUG')), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm aware that getSystemValueString is used here as a workaround for reading environment variables, but I have some concerns:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I was referring to the symfony mailer configuration in Nextcloud using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
In a previous version, you were using $_ENV / getenv, why did you withdraw this approach? I think that would be cleaner than hijacking SystemConfig 🏴☠️ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Ah, Okay, yeah we can still change it to mail_app_debug or anything else.
I agree it was cleaner but abandoned the approach, ironically because I thought it would get flagged during the review process, for one of two reasons,
|
||
explode('|', $account->getDebug()) | ||
); | ||
if (in_array('imap', $debug) || in_array('imap-full', $debug)) { | ||
$fn = 'mail-' . $account->getUserId() . '-' . $account->getId() . '-imap.log'; | ||
$params['debug'] = $this->config->getSystemValue('datadirectory') . '/' . $fn; | ||
if (in_array('imap-full', $debug)) { | ||
$params['debug_literal'] = true; | ||
} | ||
} | ||
|
||
$client = new HordeImapClient($params); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<?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::STRING, [ | ||
'length' => 32, | ||
'notnull' => false, | ||
'default' => '', | ||
]); | ||
} | ||
return $schema; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,6 +47,7 @@ public function createTestAccount(?string $userId = null) { | |
$mailAccount->setOutboundUser('[email protected]'); | ||
$mailAccount->setOutboundPassword(OC::$server->getCrypto()->encrypt('mypassword')); | ||
$mailAccount->setOutboundSslMode('none'); | ||
$mailAccount->setDebug('imap'); | ||
$acc = $accountService->save($mailAccount); | ||
|
||
/** @var MailboxSync $mbSync */ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To also print smtp and sieve like before?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would kind of defeat the purpose of per account logging, as all account smtp transmissions would end up in the same file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NVM. I miss understood this, sure I can change this.