1 /*
2 SPDX-FileCopyrightText: 2013-2021 Laurent Montel <montel@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include "sieveeditorutil.h"
8 #include "sieveeditor_debug.h"
9 #include "sieveeditorsavepasswordjob.h"
10 #include "sieveserversettings.h"
11
12 #include <KConfig>
13
14 #include <KConfigGroup>
15
16 #include <KSharedConfig>
17 #include <QRegularExpression>
18 #include <QUrlQuery>
19
20 #include <qt5keychain/keychain.h>
21 using namespace QKeychain;
22
url() const23 QUrl SieveEditorUtil::SieveServerConfig::url() const
24 {
25 QUrl u;
26 u.setHost(sieveSettings.serverName);
27 u.setUserName(sieveSettings.userName);
28 u.setPassword(sieveSettings.password);
29 u.setPort(sieveSettings.port);
30
31 QString authStr;
32 switch (sieveSettings.authenticationType) {
33 case MailTransport::Transport::EnumAuthenticationType::CLEAR:
34 case MailTransport::Transport::EnumAuthenticationType::PLAIN:
35 authStr = QStringLiteral("PLAIN");
36 break;
37 case MailTransport::Transport::EnumAuthenticationType::LOGIN:
38 authStr = QStringLiteral("LOGIN");
39 break;
40 case MailTransport::Transport::EnumAuthenticationType::CRAM_MD5:
41 authStr = QStringLiteral("CRAM-MD5");
42 break;
43 case MailTransport::Transport::EnumAuthenticationType::DIGEST_MD5:
44 authStr = QStringLiteral("DIGEST-MD5");
45 break;
46 case MailTransport::Transport::EnumAuthenticationType::GSSAPI:
47 authStr = QStringLiteral("GSSAPI");
48 break;
49 case MailTransport::Transport::EnumAuthenticationType::ANONYMOUS:
50 authStr = QStringLiteral("ANONYMOUS");
51 break;
52 default:
53 authStr = QStringLiteral("PLAIN");
54 break;
55 }
56 QUrlQuery query;
57 query.addQueryItem(QStringLiteral("x-mech"), authStr);
58 u.setQuery(query);
59 return u;
60 }
61
operator ==(const SieveEditorUtil::SieveServerConfig & other) const62 bool SieveEditorUtil::SieveServerConfig::operator==(const SieveEditorUtil::SieveServerConfig &other) const
63 {
64 const bool result = (enabled == other.enabled) && (useImapCustomServer == other.useImapCustomServer) && (sieveSettings == other.sieveSettings)
65 && (sieveImapAccountSettings == other.sieveImapAccountSettings);
66 if (!result) {
67 qCDebug(SIEVEEDITOR_LOG) << "enabled " << enabled << " other.enabled " << other.enabled;
68 qCDebug(SIEVEEDITOR_LOG) << "useImapCustomServer " << useImapCustomServer << " other.useImapCustomServer " << other.useImapCustomServer;
69 qCDebug(SIEVEEDITOR_LOG) << "sieveSettings " << sieveSettings << " other.sieveSettings " << other.sieveSettings;
70 qCDebug(SIEVEEDITOR_LOG) << "sieveImapAccountSettings " << sieveImapAccountSettings << " other.sieveImapAccountSettings "
71 << other.sieveImapAccountSettings;
72 }
73 return result;
74 }
75
writeServerSieveConfig(const QVector<SieveServerConfig> & lstConfig)76 void SieveEditorUtil::writeServerSieveConfig(const QVector<SieveServerConfig> &lstConfig)
77 {
78 KSharedConfigPtr cfg = KSharedConfig::openConfig();
79 const QRegularExpression re(QStringLiteral("^ServerSieve (.+)$"));
80 // Delete Old Group
81 const QStringList groups = cfg->groupList().filter(re);
82 for (const QString &conf : groups) {
83 KConfigGroup group = cfg->group(conf);
84 group.deleteGroup();
85 }
86
87 int i = 0;
88 for (const SieveEditorUtil::SieveServerConfig &conf : lstConfig) {
89 writeSieveSettings(cfg, conf, i);
90 ++i;
91 }
92 cfg->sync();
93 cfg->reparseConfiguration();
94 }
95
sievePasswordIdentifier(const QString & userName,const QString & serverName)96 QString SieveEditorUtil::sievePasswordIdentifier(const QString &userName, const QString &serverName)
97 {
98 return userName + QLatin1Char('@') + serverName;
99 }
100
imapPasswordIdentifier(const QString & userName,const QString & serverName)101 QString SieveEditorUtil::imapPasswordIdentifier(const QString &userName, const QString &serverName)
102 {
103 return QLatin1String("Imap") + userName + QLatin1Char('@') + serverName;
104 }
105
writeSieveSettings(const KSharedConfigPtr & cfg,const SieveEditorUtil::SieveServerConfig & conf,int index)106 void SieveEditorUtil::writeSieveSettings(const KSharedConfigPtr &cfg, const SieveEditorUtil::SieveServerConfig &conf, int index)
107 {
108 KConfigGroup group = cfg->group(QStringLiteral("ServerSieve %1").arg(index));
109 group.writeEntry(QStringLiteral("Port"), conf.sieveSettings.port);
110 group.writeEntry(QStringLiteral("ServerName"), conf.sieveSettings.serverName);
111 group.writeEntry(QStringLiteral("UserName"), conf.sieveSettings.userName);
112 group.writeEntry(QStringLiteral("Enabled"), conf.enabled);
113
114 const QString walletEntry = SieveEditorUtil::sievePasswordIdentifier(conf.sieveSettings.userName, conf.sieveSettings.serverName);
115 auto writeJob = new SieveEditorSavePasswordJob;
116 writeJob->setName(SieveEditorUtil::walletFolderName());
117 writeJob->setPassword(conf.sieveSettings.password);
118 writeJob->setKey(walletEntry);
119
120 writeJob->start();
121
122 group.writeEntry(QStringLiteral("Authentication"), static_cast<int>(conf.sieveSettings.authenticationType));
123
124 // Imap Account Settings
125 group.writeEntry(QStringLiteral("ImapPort"), conf.sieveImapAccountSettings.port());
126 group.writeEntry(QStringLiteral("ImapAuthentication"), static_cast<int>(conf.sieveImapAccountSettings.authenticationType()));
127 group.writeEntry(QStringLiteral("ImapEncrypt"), static_cast<int>(conf.sieveImapAccountSettings.encryptionMode()));
128
129 if ((conf.sieveImapAccountSettings.serverName() != conf.sieveSettings.serverName)
130 && (conf.sieveImapAccountSettings.userName() != conf.sieveSettings.userName) && !conf.sieveImapAccountSettings.serverName().isEmpty()
131 && !conf.sieveImapAccountSettings.userName().isEmpty()) {
132 group.writeEntry(QStringLiteral("useImapCustomServer"), true);
133 group.writeEntry(QStringLiteral("ImapServerName"), conf.sieveImapAccountSettings.serverName());
134 group.writeEntry(QStringLiteral("ImapUserName"), conf.sieveImapAccountSettings.userName());
135 const QString imapWalletEntry = imapPasswordIdentifier(conf.sieveImapAccountSettings.userName(), conf.sieveImapAccountSettings.serverName());
136
137 auto writeImapSettingJob = new SieveEditorSavePasswordJob;
138 writeImapSettingJob->setName(SieveEditorUtil::walletFolderName());
139 writeImapSettingJob->setPassword(conf.sieveImapAccountSettings.password());
140 writeImapSettingJob->setKey(imapWalletEntry);
141 writeImapSettingJob->start();
142 }
143 }
144
walletFolderName()145 QString SieveEditorUtil::walletFolderName()
146 {
147 return QStringLiteral("sieveeditor");
148 }
149
addServerSieveConfig(const SieveEditorUtil::SieveServerConfig & conf)150 void SieveEditorUtil::addServerSieveConfig(const SieveEditorUtil::SieveServerConfig &conf)
151 {
152 KSharedConfigPtr cfg = KSharedConfig::openConfig();
153 const QRegularExpression re(QStringLiteral("^ServerSieve (.+)$"));
154 const QStringList groups = cfg->groupList().filter(re);
155
156 writeSieveSettings(cfg, conf, groups.count());
157 cfg->sync();
158 }
159
operator <<(QDebug d,const SieveEditorUtil::SieveServerConfig & settings)160 QDebug operator<<(QDebug d, const SieveEditorUtil::SieveServerConfig &settings)
161 {
162 d << "sieveSettings " << settings.sieveSettings;
163 d << "sieveImapAccountSettings " << settings.sieveImapAccountSettings;
164 d << "url " << settings.url();
165 d << "enabled " << settings.enabled;
166 d << "useImapCustomServer " << settings.useImapCustomServer;
167 return d;
168 }
169
operator <<(QDebug d,const SieveEditorUtil::SieveAccountSettings & settings)170 QDebug operator<<(QDebug d, const SieveEditorUtil::SieveAccountSettings &settings)
171 {
172 d << "serverName " << settings.serverName;
173 d << "userName " << settings.userName;
174 d << "password " << settings.password;
175 d << "authenticationType " << settings.authenticationType;
176 d << "port " << settings.port;
177 return d;
178 }
179
operator ==(const SieveEditorUtil::SieveAccountSettings & other) const180 bool SieveEditorUtil::SieveAccountSettings::operator==(const SieveEditorUtil::SieveAccountSettings &other) const
181 {
182 bool result = (serverName == other.serverName) && (userName == other.userName) && (password == other.password)
183 && (authenticationType == other.authenticationType) && (port == other.port);
184 if (!result) {
185 qCDebug(SIEVEEDITOR_LOG) << "serverName " << serverName << " other.serverName " << other.serverName;
186 qCDebug(SIEVEEDITOR_LOG) << "userName " << userName << " other.userName " << other.userName;
187 qCDebug(SIEVEEDITOR_LOG) << "password " << password << " other.password " << other.password;
188 qCDebug(SIEVEEDITOR_LOG) << "authenticationType " << authenticationType << " other.authenticationType " << other.authenticationType;
189 qCDebug(SIEVEEDITOR_LOG) << "port " << port << " other.port " << other.port;
190 }
191 return result;
192 }
193
isValid() const194 bool SieveEditorUtil::SieveAccountSettings::isValid() const
195 {
196 return !serverName.isEmpty() && !userName.isEmpty() && (port != -1);
197 }
198
isValid() const199 bool SieveEditorUtil::SieveServerConfig::isValid() const
200 {
201 return sieveSettings.isValid();
202 }
203