File indexing completed on 2024-05-12 05:25:41
0001 /* 0002 SPDX-FileCopyrightText: 2013-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "sieveeditorutil.h" 0008 #include "sieveeditor_debug.h" 0009 #include "sieveeditorsavepasswordjob.h" 0010 #include "sieveserversettings.h" 0011 0012 #include <KConfig> 0013 0014 #include <KConfigGroup> 0015 0016 #include <KSharedConfig> 0017 #include <QRegularExpression> 0018 #include <QUrlQuery> 0019 0020 #include <qt6keychain/keychain.h> 0021 using namespace QKeychain; 0022 0023 QUrl SieveEditorUtil::SieveServerConfig::url() const 0024 { 0025 QUrl u; 0026 u.setHost(sieveSettings.serverName); 0027 u.setUserName(sieveSettings.userName); 0028 u.setPassword(sieveSettings.password); 0029 u.setPort(sieveSettings.port); 0030 0031 QString authStr; 0032 switch (sieveSettings.authenticationType) { 0033 case MailTransport::Transport::EnumAuthenticationType::CLEAR: 0034 case MailTransport::Transport::EnumAuthenticationType::PLAIN: 0035 authStr = QStringLiteral("PLAIN"); 0036 break; 0037 case MailTransport::Transport::EnumAuthenticationType::LOGIN: 0038 authStr = QStringLiteral("LOGIN"); 0039 break; 0040 case MailTransport::Transport::EnumAuthenticationType::CRAM_MD5: 0041 authStr = QStringLiteral("CRAM-MD5"); 0042 break; 0043 case MailTransport::Transport::EnumAuthenticationType::DIGEST_MD5: 0044 authStr = QStringLiteral("DIGEST-MD5"); 0045 break; 0046 case MailTransport::Transport::EnumAuthenticationType::GSSAPI: 0047 authStr = QStringLiteral("GSSAPI"); 0048 break; 0049 case MailTransport::Transport::EnumAuthenticationType::ANONYMOUS: 0050 authStr = QStringLiteral("ANONYMOUS"); 0051 break; 0052 default: 0053 authStr = QStringLiteral("PLAIN"); 0054 break; 0055 } 0056 QUrlQuery query; 0057 query.addQueryItem(QStringLiteral("x-mech"), authStr); 0058 u.setQuery(query); 0059 return u; 0060 } 0061 0062 bool SieveEditorUtil::SieveServerConfig::operator==(const SieveEditorUtil::SieveServerConfig &other) const 0063 { 0064 const bool result = (enabled == other.enabled) && (useImapCustomServer == other.useImapCustomServer) && (sieveSettings == other.sieveSettings) 0065 && (sieveImapAccountSettings == other.sieveImapAccountSettings); 0066 if (!result) { 0067 qCDebug(SIEVEEDITOR_LOG) << "enabled " << enabled << " other.enabled " << other.enabled; 0068 qCDebug(SIEVEEDITOR_LOG) << "useImapCustomServer " << useImapCustomServer << " other.useImapCustomServer " << other.useImapCustomServer; 0069 qCDebug(SIEVEEDITOR_LOG) << "sieveSettings " << sieveSettings << " other.sieveSettings " << other.sieveSettings; 0070 qCDebug(SIEVEEDITOR_LOG) << "sieveImapAccountSettings " << sieveImapAccountSettings << " other.sieveImapAccountSettings " 0071 << other.sieveImapAccountSettings; 0072 } 0073 return result; 0074 } 0075 0076 void SieveEditorUtil::writeServerSieveConfig(const QList<SieveServerConfig> &lstConfig) 0077 { 0078 KSharedConfigPtr cfg = KSharedConfig::openConfig(); 0079 const QRegularExpression re(QStringLiteral("^ServerSieve (.+)$")); 0080 // Delete Old Group 0081 const QStringList groups = cfg->groupList().filter(re); 0082 for (const QString &conf : groups) { 0083 KConfigGroup group = cfg->group(conf); 0084 group.deleteGroup(); 0085 } 0086 0087 int i = 0; 0088 for (const SieveEditorUtil::SieveServerConfig &conf : lstConfig) { 0089 writeSieveSettings(cfg, conf, i); 0090 ++i; 0091 } 0092 cfg->sync(); 0093 cfg->reparseConfiguration(); 0094 } 0095 0096 QString SieveEditorUtil::sievePasswordIdentifier(const QString &userName, const QString &serverName) 0097 { 0098 return userName + QLatin1Char('@') + serverName; 0099 } 0100 0101 QString SieveEditorUtil::imapPasswordIdentifier(const QString &userName, const QString &serverName) 0102 { 0103 return QLatin1StringView("Imap") + userName + QLatin1Char('@') + serverName; 0104 } 0105 0106 void SieveEditorUtil::writeSieveSettings(const KSharedConfigPtr &cfg, const SieveEditorUtil::SieveServerConfig &conf, int index) 0107 { 0108 KConfigGroup group = cfg->group(QStringLiteral("ServerSieve %1").arg(index)); 0109 group.writeEntry(QStringLiteral("Port"), conf.sieveSettings.port); 0110 group.writeEntry(QStringLiteral("ServerName"), conf.sieveSettings.serverName); 0111 group.writeEntry(QStringLiteral("UserName"), conf.sieveSettings.userName); 0112 group.writeEntry(QStringLiteral("Enabled"), conf.enabled); 0113 0114 const QString walletEntry = SieveEditorUtil::sievePasswordIdentifier(conf.sieveSettings.userName, conf.sieveSettings.serverName); 0115 auto writeJob = new SieveEditorSavePasswordJob; 0116 writeJob->setName(SieveEditorUtil::walletFolderName()); 0117 writeJob->setPassword(conf.sieveSettings.password); 0118 writeJob->setKey(walletEntry); 0119 0120 writeJob->start(); 0121 0122 group.writeEntry(QStringLiteral("Authentication"), static_cast<int>(conf.sieveSettings.authenticationType)); 0123 0124 // Imap Account Settings 0125 group.writeEntry(QStringLiteral("ImapPort"), conf.sieveImapAccountSettings.port()); 0126 group.writeEntry(QStringLiteral("ImapAuthentication"), static_cast<int>(conf.sieveImapAccountSettings.authenticationType())); 0127 group.writeEntry(QStringLiteral("ImapEncrypt"), static_cast<int>(conf.sieveImapAccountSettings.encryptionMode())); 0128 0129 if ((conf.sieveImapAccountSettings.serverName() != conf.sieveSettings.serverName) 0130 && (conf.sieveImapAccountSettings.userName() != conf.sieveSettings.userName) && !conf.sieveImapAccountSettings.serverName().isEmpty() 0131 && !conf.sieveImapAccountSettings.userName().isEmpty()) { 0132 group.writeEntry(QStringLiteral("useImapCustomServer"), true); 0133 group.writeEntry(QStringLiteral("ImapServerName"), conf.sieveImapAccountSettings.serverName()); 0134 group.writeEntry(QStringLiteral("ImapUserName"), conf.sieveImapAccountSettings.userName()); 0135 const QString imapWalletEntry = imapPasswordIdentifier(conf.sieveImapAccountSettings.userName(), conf.sieveImapAccountSettings.serverName()); 0136 0137 auto writeImapSettingJob = new SieveEditorSavePasswordJob; 0138 writeImapSettingJob->setName(SieveEditorUtil::walletFolderName()); 0139 writeImapSettingJob->setPassword(conf.sieveImapAccountSettings.password()); 0140 writeImapSettingJob->setKey(imapWalletEntry); 0141 writeImapSettingJob->start(); 0142 } 0143 } 0144 0145 QString SieveEditorUtil::walletFolderName() 0146 { 0147 return QStringLiteral("sieveeditor"); 0148 } 0149 0150 void SieveEditorUtil::addServerSieveConfig(const SieveEditorUtil::SieveServerConfig &conf) 0151 { 0152 KSharedConfigPtr cfg = KSharedConfig::openConfig(); 0153 const QRegularExpression re(QStringLiteral("^ServerSieve (.+)$")); 0154 const QStringList groups = cfg->groupList().filter(re); 0155 0156 writeSieveSettings(cfg, conf, groups.count()); 0157 cfg->sync(); 0158 } 0159 0160 QDebug operator<<(QDebug d, const SieveEditorUtil::SieveServerConfig &settings) 0161 { 0162 d << "sieveSettings " << settings.sieveSettings; 0163 d << "sieveImapAccountSettings " << settings.sieveImapAccountSettings; 0164 d << "url " << settings.url(); 0165 d << "enabled " << settings.enabled; 0166 d << "useImapCustomServer " << settings.useImapCustomServer; 0167 return d; 0168 } 0169 0170 QDebug operator<<(QDebug d, const SieveEditorUtil::SieveAccountSettings &settings) 0171 { 0172 d << "serverName " << settings.serverName; 0173 d << "userName " << settings.userName; 0174 d << "password " << settings.password; 0175 d << "authenticationType " << settings.authenticationType; 0176 d << "port " << settings.port; 0177 return d; 0178 } 0179 0180 bool SieveEditorUtil::SieveAccountSettings::operator==(const SieveEditorUtil::SieveAccountSettings &other) const 0181 { 0182 bool result = (serverName == other.serverName) && (userName == other.userName) && (password == other.password) 0183 && (authenticationType == other.authenticationType) && (port == other.port); 0184 if (!result) { 0185 qCDebug(SIEVEEDITOR_LOG) << "serverName " << serverName << " other.serverName " << other.serverName; 0186 qCDebug(SIEVEEDITOR_LOG) << "userName " << userName << " other.userName " << other.userName; 0187 qCDebug(SIEVEEDITOR_LOG) << "password " << password << " other.password " << other.password; 0188 qCDebug(SIEVEEDITOR_LOG) << "authenticationType " << authenticationType << " other.authenticationType " << other.authenticationType; 0189 qCDebug(SIEVEEDITOR_LOG) << "port " << port << " other.port " << other.port; 0190 } 0191 return result; 0192 } 0193 0194 bool SieveEditorUtil::SieveAccountSettings::isValid() const 0195 { 0196 return !serverName.isEmpty() && !userName.isEmpty() && (port != -1); 0197 } 0198 0199 bool SieveEditorUtil::SieveServerConfig::isValid() const 0200 { 0201 return sieveSettings.isValid(); 0202 }