Skip to content

Commit 02653f1

Browse files
authored
Merge pull request #11026 from nextcloud/bug/noid/enabeling-sieve-broken
fix enabeling sieve
2 parents 6bf0776 + 3a9385e commit 02653f1

File tree

3 files changed

+63
-49
lines changed

3 files changed

+63
-49
lines changed

lib/Controller/SieveController.php

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
namespace OCA\Mail\Controller;
1111

1212
use Horde\ManageSieve\Exception as ManagesieveException;
13-
use OCA\Mail\Account;
1413
use OCA\Mail\AppInfo\Application;
1514
use OCA\Mail\Db\MailAccountMapper;
1615
use OCA\Mail\Exception\ClientException;
@@ -142,36 +141,40 @@ public function updateAccount(int $id,
142141
$mailAccount->setSieveEnabled(false);
143142
$mailAccount->setSieveHost(null);
144143
$mailAccount->setSievePort(null);
144+
$mailAccount->setSieveSslMode(null);
145145
$mailAccount->setSieveUser(null);
146146
$mailAccount->setSievePassword(null);
147-
$mailAccount->setSieveSslMode(null);
148147

149148
$this->mailAccountMapper->save($mailAccount);
150149
return new JSONResponse(['sieveEnabled' => $mailAccount->isSieveEnabled()]);
151150
}
152151

153-
if (empty($sieveUser)) {
152+
if (empty($sieveUser) && empty($sievePassword)) {
153+
$useImapCredentials = true;
154154
$sieveUser = $mailAccount->getInboundUser();
155-
}
156-
157-
if (empty($sievePassword)) {
158-
$sievePassword = $mailAccount->getInboundPassword();
155+
/** @psalm-suppress PossiblyNullArgument */
156+
$sievePassword = $this->crypto->decrypt($mailAccount->getInboundPassword());
159157
} else {
160-
$sievePassword = $this->crypto->encrypt($sievePassword);
158+
$useImapCredentials = false;
161159
}
162160

163161
try {
164-
$this->sieveClientFactory->getClient(new Account($mailAccount));
162+
$this->sieveClientFactory->createClient($sieveHost, $sievePort, $sieveUser, $sievePassword, $sieveSslMode, null);
165163
} catch (ManagesieveException $e) {
166164
throw new CouldNotConnectException($e, 'ManageSieve', $sieveHost, $sievePort);
167165
}
168166

169167
$mailAccount->setSieveEnabled(true);
170168
$mailAccount->setSieveHost($sieveHost);
171169
$mailAccount->setSievePort($sievePort);
172-
$mailAccount->setSieveUser($mailAccount->getInboundUser() === $sieveUser ? null : $sieveUser);
173-
$mailAccount->setSievePassword($mailAccount->getInboundPassword() === $sievePassword ? null : $sievePassword);
174170
$mailAccount->setSieveSslMode($sieveSslMode);
171+
if ($useImapCredentials) {
172+
$mailAccount->setSieveUser(null);
173+
$mailAccount->setSievePassword(null);
174+
} else {
175+
$mailAccount->setSieveUser($sieveUser);
176+
$mailAccount->setSievePassword($this->crypto->encrypt($sievePassword));
177+
}
175178

176179
$this->mailAccountMapper->save($mailAccount);
177180
return new JSONResponse(['sieveEnabled' => $mailAccount->isSieveEnabled()]);

lib/Sieve/SieveClientFactory.php

Lines changed: 48 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,10 @@
1515
use OCP\Security\ICrypto;
1616

1717
class SieveClientFactory {
18-
/** @var ICrypto */
19-
private $crypto;
18+
private ICrypto $crypto;
19+
private IConfig $config;
20+
private array $cache = [];
2021

21-
/** @var IConfig */
22-
private $config;
23-
24-
private $cache = [];
25-
26-
/**
27-
* @param ICrypto $crypto
28-
* @param IConfig $config
29-
*/
3022
public function __construct(ICrypto $crypto, IConfig $config) {
3123
$this->crypto = $crypto;
3224
$this->config = $config;
@@ -41,43 +33,62 @@ public function getClient(Account $account): ManageSieve {
4133
if (empty($user)) {
4234
$user = $account->getMailAccount()->getInboundUser();
4335
}
44-
4536
$password = $account->getMailAccount()->getSievePassword();
4637
if (empty($password)) {
4738
$password = $account->getMailAccount()->getInboundPassword();
4839
}
4940

50-
$sslMode = $account->getMailAccount()->getSieveSslMode();
51-
if (empty($sslMode)) {
52-
$sslMode = true;
53-
} elseif ($sslMode === 'none') {
54-
$sslMode = false;
55-
}
56-
57-
$params = [
58-
'host' => $account->getMailAccount()->getSieveHost(),
59-
'port' => $account->getMailAccount()->getSievePort(),
60-
'user' => $user,
61-
'password' => $this->crypto->decrypt($password),
62-
'secure' => $sslMode,
63-
'timeout' => $this->config->getSystemValueInt('app.mail.sieve.timeout', 5),
64-
'context' => [
65-
'ssl' => [
66-
'verify_peer' => $this->config->getSystemValueBool('app.mail.verify-tls-peer', true),
67-
'verify_peer_name' => $this->config->getSystemValueBool('app.mail.verify-tls-peer', true),
68-
]
69-
],
70-
];
71-
7241
if ($account->getDebug() || $this->config->getSystemValueBool('app.mail.debug')) {
73-
$fn = 'mail-' . $account->getUserId() . '-' . $account->getId() . '-sieve.log';
74-
$params['logger'] = new SieveLogger($this->config->getSystemValue('datadirectory') . '/' . $fn);
42+
$logFile = $this->config->getSystemValue('datadirectory') . '/mail-' . $account->getUserId() . '-' . $account->getId() . '-sieve.log';
43+
} else {
44+
$logFile = null;
7545
}
7646

77-
$this->cache[$account->getId()] = new ManageSieve($params);
47+
$this->cache[$account->getId()] = $this->createClient(
48+
$account->getMailAccount()->getSieveHost(),
49+
$account->getMailAccount()->getSievePort(),
50+
$user,
51+
$this->crypto->decrypt($password),
52+
$account->getMailAccount()->getSieveSslMode(),
53+
$logFile,
54+
);
7855
}
7956

8057
return $this->cache[$account->getId()];
8158
}
8259

60+
/**
61+
* @param string $sslMode possible values: '', 'none', 'ssl' or 'tls'
62+
* @param ?string $logFile absolute path for logFile or null to disable logging
63+
* @throws ManageSieve\Exception
64+
*/
65+
public function createClient(string $host, int $port, string $user, string $password, string $sslMode, ?string $logFile): ManageSieve {
66+
if (empty($sslMode)) {
67+
$sslMode = true;
68+
} elseif ($sslMode === 'none') {
69+
$sslMode = false;
70+
}
71+
72+
$params = [
73+
'host' => $host,
74+
'port' => $port,
75+
'user' => $user,
76+
'password' => $password,
77+
'secure' => $sslMode,
78+
'timeout' => $this->config->getSystemValueInt('app.mail.sieve.timeout', 5),
79+
'context' => [
80+
'ssl' => [
81+
'verify_peer' => $this->config->getSystemValueBool('app.mail.verify-tls-peer', true),
82+
'verify_peer_name' => $this->config->getSystemValueBool('app.mail.verify-tls-peer', true),
83+
84+
]
85+
],
86+
];
87+
88+
if ($logFile !== null) {
89+
$params['logger'] = new SieveLogger($logFile);
90+
}
91+
92+
return new ManageSieve($params);
93+
}
8394
}

tests/Unit/Controller/SieveControllerTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public function testUpdateAccountEnableNoConnection(): void {
107107

108108
$sieveClientFactory = $this->serviceMock->getParameter('sieveClientFactory');
109109
$sieveClientFactory->expects($this->once())
110-
->method('getClient')
110+
->method('createClient')
111111
->willThrowException(new Exception('Computer says no'));
112112

113113
$response = $this->sieveController->updateAccount(2, true, 'localhost', 4190, 'user', 'password', '');

0 commit comments

Comments
 (0)