File indexing completed on 2024-11-24 04:53:09
0001 /* Copyright (C) 2006 - 2014 Jan Kundrát <jkt@flaska.net> 0002 0003 This file is part of the Trojita Qt IMAP e-mail client, 0004 http://trojita.flaska.net/ 0005 0006 This program is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU General Public License as 0008 published by the Free Software Foundation; either version 2 of 0009 the License or (at your option) version 3 or any later version 0010 accepted by the membership of KDE e.V. (or its successor approved 0011 by the membership of KDE e.V.), which shall act as a proxy 0012 defined in Section 14 of version 3 of the license. 0013 0014 This program is distributed in the hope that it will be useful, 0015 but WITHOUT ANY WARRANTY; without even the implied warranty of 0016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0017 GNU General Public License for more details. 0018 0019 You should have received a copy of the GNU General Public License 0020 along with this program. If not, see <http://www.gnu.org/licenses/>. 0021 */ 0022 0023 #include "ImapAccess.h" 0024 #include <QDir> 0025 #include <QFileInfo> 0026 #include <QSslKey> 0027 #include <QSettings> 0028 #include "Common/MetaTypes.h" 0029 #include "Common/Paths.h" 0030 #include "Common/PortNumbers.h" 0031 #include "Common/SettingsNames.h" 0032 #include "Imap/Model/CombinedCache.h" 0033 #include "Imap/Model/DummyNetworkWatcher.h" 0034 #include "Imap/Model/MailboxModel.h" 0035 #include "Imap/Model/MemoryCache.h" 0036 #include "Imap/Model/Model.h" 0037 #include "Imap/Model/MsgListModel.h" 0038 #include "Imap/Model/NetworkWatcher.h" 0039 #include "Imap/Model/OneMessageModel.h" 0040 #include "Imap/Model/SubtreeModel.h" 0041 #include "Imap/Model/SystemNetworkWatcher.h" 0042 #include "Imap/Model/ThreadingMsgListModel.h" 0043 #include "Imap/Model/Utils.h" 0044 #include "Imap/Model/VisibleTasksModel.h" 0045 #include "Imap/Network/MsgPartNetAccessManager.h" 0046 #include "Streams/SocketFactory.h" 0047 #include "UiUtils/PasswordWatcher.h" 0048 0049 namespace Imap { 0050 0051 ImapAccess::ImapAccess(QObject *parent, QSettings *settings, Plugins::PluginManager *pluginManager, const QString &accountName) : 0052 QObject(parent), m_settings(settings), m_imapModel(0), m_mailboxModel(0), m_mailboxSubtreeModel(0), m_msgListModel(0), 0053 m_threadingMsgListModel(0), m_visibleTasksModel(0), m_oneMessageModel(0), m_netWatcher(0), m_msgQNAM(0), 0054 m_pluginManager(pluginManager), m_passwordWatcher(0), m_port(0), 0055 m_connectionMethod(Common::ConnectionMethod::Invalid), 0056 m_sslInfoIcon(UiUtils::Formatting::IconType::NoIcon), 0057 m_accountName(accountName) 0058 { 0059 Imap::migrateSettings(m_settings); 0060 reloadConfiguration(); 0061 m_cacheDir = Common::writablePath(Common::LOCATION_CACHE) + m_accountName + QLatin1Char('/');; 0062 m_passwordWatcher = new UiUtils::PasswordWatcher(this, m_pluginManager, 0063 // FIXME: this can be removed when support for multiple accounts is implemented 0064 accountName.isEmpty() ? QStringLiteral("account-0") : accountName, 0065 QStringLiteral("imap")); 0066 } 0067 0068 void ImapAccess::reloadConfiguration() 0069 { 0070 m_server = m_settings->value(Common::SettingsNames::imapHostKey).toString(); 0071 m_username = m_settings->value(Common::SettingsNames::imapUserKey).toString(); 0072 if (m_settings->value(Common::SettingsNames::imapMethodKey).toString() == Common::SettingsNames::methodSSL) { 0073 m_connectionMethod = Common::ConnectionMethod::NetDedicatedTls; 0074 } else if (m_settings->value(Common::SettingsNames::imapMethodKey).toString() == Common::SettingsNames::methodTCP) { 0075 m_connectionMethod = m_settings->value(Common::SettingsNames::imapStartTlsKey).toBool() ? 0076 Common::ConnectionMethod::NetStartTls : Common::ConnectionMethod::NetCleartext; 0077 } else if (m_settings->value(Common::SettingsNames::imapMethodKey).toString() == Common::SettingsNames::methodProcess) { 0078 m_connectionMethod = Common::ConnectionMethod::Process; 0079 } 0080 m_port = m_settings->value(Common::SettingsNames::imapPortKey, QVariant(0)).toInt(); 0081 if (!m_port) { 0082 switch (m_connectionMethod) { 0083 case Common::ConnectionMethod::NetCleartext: 0084 case Common::ConnectionMethod::NetStartTls: 0085 m_port = Common::PORT_IMAP; 0086 break; 0087 case Common::ConnectionMethod::NetDedicatedTls: 0088 m_port = Common::PORT_IMAPS; 0089 break; 0090 case Common::ConnectionMethod::Process: 0091 case Common::ConnectionMethod::Invalid: 0092 // do nothing 0093 break; 0094 } 0095 } 0096 } 0097 0098 void ImapAccess::alertReceived(const QString &message) 0099 { 0100 qDebug() << "alertReceived" << message; 0101 } 0102 0103 void ImapAccess::imapError(const QString &message) 0104 { 0105 qDebug() << "imapError" << message; 0106 } 0107 0108 void ImapAccess::networkError(const QString &message) 0109 { 0110 qDebug() << "networkError" << message; 0111 } 0112 0113 void ImapAccess::slotLogged(uint parserId, const Common::LogMessage &message) 0114 { 0115 if (message.kind != Common::LOG_IO_READ) { 0116 qDebug() << "LOG" << parserId << message.timestamp << message.kind << message.source << message.message; 0117 } 0118 } 0119 0120 QString ImapAccess::server() const 0121 { 0122 return m_server; 0123 } 0124 0125 void ImapAccess::setServer(const QString &server) 0126 { 0127 m_server = server; 0128 m_settings->setValue(Common::SettingsNames::imapHostKey, m_server); 0129 emit serverChanged(); 0130 } 0131 0132 QString ImapAccess::username() const 0133 { 0134 return m_username; 0135 } 0136 0137 void ImapAccess::setUsername(const QString &username) 0138 { 0139 m_username = username; 0140 m_settings->setValue(Common::SettingsNames::imapUserKey, m_username); 0141 emit usernameChanged();; 0142 } 0143 0144 QString ImapAccess::password() const 0145 { 0146 return m_password; 0147 } 0148 0149 void ImapAccess::setPassword(const QString &password) 0150 { 0151 m_password = password; 0152 } 0153 0154 int ImapAccess::port() const 0155 { 0156 return m_port; 0157 } 0158 0159 void ImapAccess::setPort(const int port) 0160 { 0161 m_port = port; 0162 m_settings->setValue(Common::SettingsNames::imapPortKey, m_port); 0163 emit portChanged(); 0164 } 0165 0166 QString ImapAccess::sslMode() const 0167 { 0168 switch (m_connectionMethod) { 0169 case Common::ConnectionMethod::NetCleartext: 0170 return QStringLiteral("No"); 0171 case Common::ConnectionMethod::NetStartTls: 0172 return QStringLiteral("StartTLS"); 0173 case Common::ConnectionMethod::NetDedicatedTls: 0174 return QStringLiteral("SSL"); 0175 case Common::ConnectionMethod::Invalid: 0176 case Common::ConnectionMethod::Process: 0177 return QString(); 0178 } 0179 0180 Q_ASSERT(false); 0181 return QString(); 0182 } 0183 0184 void ImapAccess::setSslMode(const QString &sslMode) 0185 { 0186 if (sslMode == QLatin1String("No")) { 0187 setConnectionMethod(Common::ConnectionMethod::NetCleartext); 0188 } else if (sslMode == QLatin1String("SSL")) { 0189 setConnectionMethod(Common::ConnectionMethod::NetDedicatedTls); 0190 } else if (sslMode == QLatin1String("StartTLS")) { 0191 setConnectionMethod(Common::ConnectionMethod::NetStartTls); 0192 } else { 0193 Q_ASSERT(false); 0194 } 0195 } 0196 0197 Common::ConnectionMethod ImapAccess::connectionMethod() const 0198 { 0199 return m_connectionMethod; 0200 } 0201 0202 void ImapAccess::setConnectionMethod(const Common::ConnectionMethod mode) 0203 { 0204 m_connectionMethod = mode; 0205 switch (m_connectionMethod) { 0206 case Common::ConnectionMethod::Invalid: 0207 break; 0208 case Common::ConnectionMethod::NetCleartext: 0209 case Common::ConnectionMethod::NetStartTls: 0210 m_settings->setValue(Common::SettingsNames::imapMethodKey, Common::SettingsNames::methodTCP); 0211 m_settings->setValue(Common::SettingsNames::imapStartTlsKey, m_connectionMethod == Common::ConnectionMethod::NetStartTls); 0212 break; 0213 case Common::ConnectionMethod::NetDedicatedTls: 0214 m_settings->setValue(Common::SettingsNames::imapMethodKey, Common::SettingsNames::methodSSL); 0215 // Trying to communicate the fact that this is going to be an encrypted connection, even though 0216 // that settings bit is not actually used 0217 m_settings->setValue(Common::SettingsNames::imapStartTlsKey, true); 0218 break; 0219 case Common::ConnectionMethod::Process: 0220 m_settings->setValue(Common::SettingsNames::imapMethodKey, Common::SettingsNames::methodProcess); 0221 break; 0222 } 0223 emit connMethodChanged(); 0224 } 0225 0226 Imap::Mailbox::NetworkPolicy ImapAccess::preferredNetworkPolicy() const 0227 { 0228 auto val = m_settings->value(Common::SettingsNames::imapStartMode).toString(); 0229 if (val == Common::SettingsNames::netOffline) { 0230 return Imap::Mailbox::NETWORK_OFFLINE; 0231 } else if (val == Common::SettingsNames::netExpensive) { 0232 return Imap::Mailbox::NETWORK_EXPENSIVE; 0233 } else { 0234 return Imap::Mailbox::NETWORK_ONLINE; 0235 } 0236 } 0237 0238 QString ImapAccess::accountIconName() const 0239 { 0240 return m_settings->value(Common::SettingsNames::imapAccountIcon).toString(); 0241 } 0242 0243 void ImapAccess::setAccountIconName(const QString &iconName) 0244 { 0245 m_settings->setValue(Common::SettingsNames::imapAccountIcon, iconName); 0246 } 0247 0248 void ImapAccess::doConnect() 0249 { 0250 if (m_netWatcher) { 0251 // We're temporarily "disabling" this connection. Otherwise this "offline preference" 0252 // would get saved into the config file, which would be bad. 0253 disconnect(m_netWatcher, &Mailbox::NetworkWatcher::desiredNetworkPolicyChanged, this, &ImapAccess::desiredNetworkPolicyChanged); 0254 } 0255 0256 if (m_imapModel) { 0257 // Disconnect from network, nuke the models 0258 Q_ASSERT(m_netWatcher); 0259 m_netWatcher->setNetworkOffline(); 0260 delete m_threadingMsgListModel; 0261 m_threadingMsgListModel = 0; 0262 delete m_msgQNAM; 0263 m_msgQNAM = 0; 0264 delete m_oneMessageModel; 0265 m_oneMessageModel = 0; 0266 delete m_visibleTasksModel; 0267 m_visibleTasksModel = 0; 0268 delete m_msgListModel; 0269 m_msgListModel = 0; 0270 delete m_mailboxSubtreeModel; 0271 m_mailboxSubtreeModel = 0; 0272 delete m_mailboxModel; 0273 m_mailboxModel = 0; 0274 delete m_netWatcher; 0275 m_netWatcher = 0; 0276 delete m_imapModel; 0277 m_imapModel = 0; 0278 } 0279 0280 Q_ASSERT(!m_imapModel); 0281 0282 Imap::Mailbox::SocketFactoryPtr factory; 0283 Imap::Mailbox::TaskFactoryPtr taskFactory(new Imap::Mailbox::TaskFactory()); 0284 0285 Streams::ProxySettings proxySettings = m_settings->value(Common::SettingsNames::imapUseSystemProxy, true).toBool() ? 0286 Streams::ProxySettings::RespectSystemProxy : Streams::ProxySettings::DirectConnect; 0287 0288 switch (m_connectionMethod) { 0289 case Common::ConnectionMethod::Invalid: 0290 factory.reset(new Streams::FakeSocketFactory(Imap::CONN_STATE_LOGOUT)); 0291 break; 0292 case Common::ConnectionMethod::NetCleartext: 0293 case Common::ConnectionMethod::NetStartTls: 0294 factory.reset(new Streams::TlsAbleSocketFactory(server(), port())); 0295 factory->setStartTlsRequired(m_connectionMethod == Common::ConnectionMethod::NetStartTls); 0296 factory->setProxySettings(proxySettings, QStringLiteral("imap")); 0297 break; 0298 case Common::ConnectionMethod::NetDedicatedTls: 0299 factory.reset(new Streams::SslSocketFactory(server(), port())); 0300 factory->setProxySettings(proxySettings, QStringLiteral("imap")); 0301 break; 0302 case Common::ConnectionMethod::Process: 0303 QStringList args = m_settings->value(Common::SettingsNames::imapProcessKey).toString().split(QLatin1Char(' ')); 0304 if (args.isEmpty()) { 0305 // it's going to fail anyway 0306 args << QLatin1String(""); 0307 } 0308 QString appName = args.takeFirst(); 0309 factory.reset(new Streams::ProcessSocketFactory(appName, args)); 0310 break; 0311 } 0312 0313 bool shouldUsePersistentCache = 0314 m_settings->value(Common::SettingsNames::cacheOfflineKey).toString() != Common::SettingsNames::cacheOfflineNone; 0315 0316 if (shouldUsePersistentCache && !QDir().mkpath(m_cacheDir)) { 0317 onCacheError(tr("Failed to create directory %1").arg(m_cacheDir)); 0318 shouldUsePersistentCache = false; 0319 } 0320 0321 if (shouldUsePersistentCache) { 0322 QFile::Permissions expectedPerms = QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner; 0323 if (QFileInfo(m_cacheDir).permissions() != expectedPerms) { 0324 if (!QFile::setPermissions(m_cacheDir, expectedPerms)) { 0325 #ifndef Q_OS_WIN32 0326 onCacheError(tr("Failed to set safe permissions on cache directory %1").arg(m_cacheDir)); 0327 shouldUsePersistentCache = false; 0328 #endif 0329 } 0330 } 0331 } 0332 0333 std::shared_ptr<Imap::Mailbox::AbstractCache> cache; 0334 0335 if (!shouldUsePersistentCache) { 0336 cache.reset(new Imap::Mailbox::MemoryCache()); 0337 } else { 0338 cache.reset(new Imap::Mailbox::CombinedCache(QStringLiteral("trojita-imap-cache"), m_cacheDir)); 0339 cache->setErrorHandler([this](const QString &e) { this->onCacheError(e); }); 0340 if (! static_cast<Imap::Mailbox::CombinedCache *>(cache.get())->open()) { 0341 // Error message was already shown by the cacheError() slot 0342 cache.reset(new Imap::Mailbox::MemoryCache()); 0343 } else { 0344 if (m_settings->value(Common::SettingsNames::cacheOfflineKey).toString() == Common::SettingsNames::cacheOfflineAll) { 0345 cache->setRenewalThreshold(0); 0346 } else { 0347 const int defaultCacheLifetime = 30; 0348 bool ok; 0349 int num = m_settings->value(Common::SettingsNames::cacheOfflineNumberDaysKey, defaultCacheLifetime).toInt(&ok); 0350 if (!ok) 0351 num = defaultCacheLifetime; 0352 cache->setRenewalThreshold(num); 0353 } 0354 } 0355 } 0356 0357 m_imapModel = new Imap::Mailbox::Model(this, cache, std::move(factory), std::move(taskFactory)); 0358 m_imapModel->setObjectName(QStringLiteral("imapModel-%1").arg(m_accountName)); 0359 m_imapModel->setCapabilitiesBlacklist(m_settings->value(Common::SettingsNames::imapBlacklistedCapabilities).toStringList()); 0360 m_imapModel->setProperty("trojita-imap-id-no-versions", !m_settings->value(Common::SettingsNames::interopRevealVersions, true).toBool()); 0361 m_imapModel->setProperty("trojita-imap-idle-renewal", m_settings->value(Common::SettingsNames::imapIdleRenewal).toUInt() * 60 * 1000); 0362 m_imapModel->setNumberRefreshInterval(numberRefreshInterval()); 0363 connect(m_imapModel, &Mailbox::Model::alertReceived, this, &ImapAccess::alertReceived); 0364 connect(m_imapModel, &Mailbox::Model::imapError, this, &ImapAccess::imapError); 0365 connect(m_imapModel, &Mailbox::Model::networkError, this, &ImapAccess::networkError); 0366 //connect(m_imapModel, &Mailbox::Model::logged, this, &ImapAccess::slotLogged); 0367 connect(m_imapModel, &Mailbox::Model::needsSslDecision, this, &ImapAccess::slotSslErrors); 0368 connect(m_imapModel, &Mailbox::Model::requireStartTlsInFuture, this, &ImapAccess::onRequireStartTlsInFuture); 0369 0370 if (m_settings->value(Common::SettingsNames::imapNeedsNetwork, true).toBool()) { 0371 m_netWatcher = new Imap::Mailbox::SystemNetworkWatcher(this, m_imapModel); 0372 } else { 0373 m_netWatcher = new Imap::Mailbox::DummyNetworkWatcher(this, m_imapModel); 0374 } 0375 connect(m_netWatcher, &Mailbox::NetworkWatcher::desiredNetworkPolicyChanged, this, &ImapAccess::desiredNetworkPolicyChanged); 0376 switch (preferredNetworkPolicy()) { 0377 case Imap::Mailbox::NETWORK_OFFLINE: 0378 QMetaObject::invokeMethod(m_netWatcher, "setNetworkOffline", Qt::QueuedConnection); 0379 break; 0380 case Imap::Mailbox::NETWORK_EXPENSIVE: 0381 QMetaObject::invokeMethod(m_netWatcher, "setNetworkExpensive", Qt::QueuedConnection); 0382 break; 0383 case Imap::Mailbox::NETWORK_ONLINE: 0384 QMetaObject::invokeMethod(m_netWatcher, "setNetworkOnline", Qt::QueuedConnection); 0385 break; 0386 } 0387 0388 m_imapModel->setImapUser(username()); 0389 if (!m_password.isNull()) { 0390 // Really; the idea is to wait before it has been set for the first time 0391 m_imapModel->setImapPassword(password()); 0392 } 0393 0394 m_mailboxModel = new Imap::Mailbox::MailboxModel(this, m_imapModel); 0395 m_mailboxModel->setObjectName(QStringLiteral("mailboxModel-%1").arg(m_accountName)); 0396 m_mailboxSubtreeModel = new Imap::Mailbox::SubtreeModelOfMailboxModel(this); 0397 m_mailboxSubtreeModel->setObjectName(QStringLiteral("mailboxSubtreeModel-%1").arg(m_accountName)); 0398 m_mailboxSubtreeModel->setSourceModel(m_mailboxModel); 0399 m_mailboxSubtreeModel->setOriginalRoot(); 0400 m_msgListModel = new Imap::Mailbox::MsgListModel(this, m_imapModel); 0401 m_msgListModel->setObjectName(QStringLiteral("msgListModel-%1").arg(m_accountName)); 0402 m_visibleTasksModel = new Imap::Mailbox::VisibleTasksModel(this, m_imapModel->taskModel()); 0403 m_visibleTasksModel->setObjectName(QStringLiteral("visibleTasksModel-%1").arg(m_accountName)); 0404 m_oneMessageModel = new Imap::Mailbox::OneMessageModel(m_imapModel); 0405 m_oneMessageModel->setObjectName(QStringLiteral("oneMessageModel-%1").arg(m_accountName)); 0406 m_msgQNAM = new Imap::Network::MsgPartNetAccessManager(this); 0407 m_msgQNAM->setObjectName(QStringLiteral("m_msgQNAM-%1").arg(m_accountName)); 0408 m_threadingMsgListModel = new Imap::Mailbox::ThreadingMsgListModel(this); 0409 m_threadingMsgListModel->setObjectName(QStringLiteral("threadingMsgListModel-%1").arg(m_accountName)); 0410 m_threadingMsgListModel->setSourceModel(m_msgListModel); 0411 emit modelsChanged(); 0412 } 0413 0414 void ImapAccess::onCacheError(const QString &message) 0415 { 0416 if (m_imapModel) { 0417 m_imapModel->setCache(std::make_shared<Imap::Mailbox::MemoryCache>()); 0418 } 0419 emit cacheError(message); 0420 } 0421 0422 QAbstractItemModel *ImapAccess::imapModel() const 0423 { 0424 return m_imapModel; 0425 } 0426 0427 QAbstractItemModel *ImapAccess::mailboxModel() const 0428 { 0429 return m_mailboxSubtreeModel; 0430 } 0431 0432 QAbstractItemModel *ImapAccess::msgListModel() const 0433 { 0434 return m_msgListModel; 0435 } 0436 0437 QAbstractItemModel *ImapAccess::visibleTasksModel() const 0438 { 0439 return m_visibleTasksModel; 0440 } 0441 0442 QObject *ImapAccess::oneMessageModel() const 0443 { 0444 return m_oneMessageModel; 0445 } 0446 0447 QObject *ImapAccess::networkWatcher() const 0448 { 0449 return m_netWatcher; 0450 } 0451 0452 QObject *ImapAccess::msgQNAM() const 0453 { 0454 return m_msgQNAM; 0455 } 0456 0457 QAbstractItemModel *ImapAccess::threadingMsgListModel() const 0458 { 0459 return m_threadingMsgListModel; 0460 } 0461 0462 UiUtils::PasswordWatcher *ImapAccess::passwordWatcher() const 0463 { 0464 return m_passwordWatcher; 0465 } 0466 0467 void ImapAccess::openMessage(const QString &mailboxName, const uint uid) 0468 { 0469 QModelIndex msgIndex = m_imapModel->messageIndexByUid(mailboxName, uid); 0470 m_oneMessageModel->setMessage(msgIndex); 0471 static_cast<Imap::Network::MsgPartNetAccessManager*>(m_msgQNAM)->setModelMessage(msgIndex); 0472 } 0473 0474 void ImapAccess::slotSslErrors(const QList<QSslCertificate> &sslCertificateChain, const QList<QSslError> &sslErrors) 0475 { 0476 m_sslChain = sslCertificateChain; 0477 m_sslErrors = sslErrors; 0478 0479 QByteArray lastKnownPubKey = m_settings->value(Common::SettingsNames::imapSslPemPubKey).toByteArray(); 0480 if (!m_sslChain.isEmpty() && !lastKnownPubKey.isEmpty() && lastKnownPubKey == m_sslChain[0].publicKey().toPem()) { 0481 // This certificate chain contains the same public keys as the last time; we should accept that 0482 m_imapModel->setSslPolicy(m_sslChain, m_sslErrors, true); 0483 } else { 0484 UiUtils::Formatting::formatSslState( 0485 m_sslChain, lastKnownPubKey, m_sslErrors, &m_sslInfoTitle, &m_sslInfoMessage, &m_sslInfoIcon); 0486 emit checkSslPolicy(); 0487 } 0488 } 0489 0490 /** @short Remember to use STARTTLS during the next connection 0491 0492 Once a first STARTTLS attempt succeeds, change the preferences to require STARTTLS in future. This is needed 0493 to prevent a possible SSL stripping attack by a malicious proxy during subsequent connections. 0494 */ 0495 void ImapAccess::onRequireStartTlsInFuture() 0496 { 0497 // It's possible that we're called after the user has already changed their preferences. 0498 // In order to not change stuff which was not supposed to be changed, let's make sure that we won't undo their changes. 0499 if (connectionMethod() == Common::ConnectionMethod::NetCleartext) { 0500 setConnectionMethod(Common::ConnectionMethod::NetStartTls); 0501 } 0502 } 0503 0504 void ImapAccess::desiredNetworkPolicyChanged(const Mailbox::NetworkPolicy policy) 0505 { 0506 switch (policy) { 0507 case Mailbox::NETWORK_OFFLINE: 0508 m_settings->setValue(Common::SettingsNames::imapStartMode, Common::SettingsNames::netOffline); 0509 break; 0510 case Mailbox::NETWORK_EXPENSIVE: 0511 m_settings->setValue(Common::SettingsNames::imapStartMode, Common::SettingsNames::netExpensive); 0512 break; 0513 case Mailbox::NETWORK_ONLINE: 0514 m_settings->setValue(Common::SettingsNames::imapStartMode, Common::SettingsNames::netOnline); 0515 break; 0516 } 0517 } 0518 0519 void ImapAccess::setSslPolicy(bool accept) 0520 { 0521 if (accept && !m_sslChain.isEmpty()) { 0522 m_settings->setValue(Common::SettingsNames::imapSslPemPubKey, m_sslChain[0].publicKey().toPem()); 0523 } 0524 m_imapModel->setSslPolicy(m_sslChain, m_sslErrors, accept); 0525 } 0526 0527 void ImapAccess::forgetSslCertificate() 0528 { 0529 m_settings->remove(Common::SettingsNames::imapSslPemPubKey); 0530 } 0531 0532 QString ImapAccess::sslInfoTitle() const 0533 { 0534 return m_sslInfoTitle; 0535 } 0536 0537 QString ImapAccess::sslInfoMessage() const 0538 { 0539 return m_sslInfoMessage; 0540 } 0541 0542 UiUtils::Formatting::IconType ImapAccess::sslInfoIcon() const 0543 { 0544 return m_sslInfoIcon; 0545 } 0546 0547 QString ImapAccess::mailboxListMailboxName() const 0548 { 0549 return m_mailboxSubtreeModel->rootIndex().data(Imap::Mailbox::RoleMailboxName).toString(); 0550 } 0551 0552 QString ImapAccess::mailboxListShortMailboxName() const 0553 { 0554 return m_mailboxSubtreeModel->rootIndex().data(Imap::Mailbox::RoleShortMailboxName).toString(); 0555 } 0556 0557 /** @short Persistently remove the local cache of IMAP data 0558 0559 This method should be called by the UI when the user changes its connection details, i.e. when there's a big chance that we are 0560 connecting to a completely different server since the last time. 0561 */ 0562 void ImapAccess::nukeCache() 0563 { 0564 Imap::removeRecursively(m_cacheDir); 0565 } 0566 0567 QModelIndex ImapAccess::deproxifiedIndex(const QModelIndex index) 0568 { 0569 return Imap::deproxifiedIndex(index); 0570 } 0571 0572 void ImapAccess::markMessageDeleted(const QModelIndex &message, bool marked) 0573 { 0574 Q_ASSERT(message.isValid()); 0575 m_imapModel->markMessagesDeleted(QModelIndexList() << message, marked ? Imap::Mailbox::FLAG_ADD : Imap::Mailbox::FLAG_REMOVE); 0576 } 0577 0578 int ImapAccess::numberRefreshInterval() const 0579 { 0580 int interval = m_settings->value(Common::SettingsNames::imapNumberRefreshInterval, QVariant(300)).toInt(); 0581 if (interval < 30) 0582 interval = 30; 0583 else if (interval > 29*60) 0584 interval = 29*60; 0585 return interval; 0586 } 0587 0588 void ImapAccess::setNumberRefreshInterval(const int interval) 0589 { 0590 m_settings->setValue(Common::SettingsNames::imapNumberRefreshInterval, interval); 0591 if (m_imapModel) 0592 m_imapModel->setNumberRefreshInterval(interval); 0593 } 0594 0595 QString ImapAccess::accountName() const 0596 { 0597 return m_accountName; 0598 } 0599 0600 bool ImapAccess::isConfigured() const 0601 { 0602 return m_settings->contains(Common::SettingsNames::imapMethodKey); 0603 } 0604 0605 }