MailTransport
9 #include "transport_p.h"
10 #include "transportmanager.h"
11 #include "transporttype_p.h"
13 #include "mailtransport_debug.h"
14 #include <KConfigGroup>
15 #include <KLocalizedString>
16 #include <KMessageBox>
17 #include <KStringHandler>
20 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
21 #include <qt5keychain/keychain.h>
23 #include <qt6keychain/keychain.h>
25 using namespace QKeychain;
26 using namespace MailTransport;
28 Transport::Transport(
const QString &cfgGroup)
29 : TransportBase(cfgGroup)
30 , d(new TransportPrivate)
32 qCDebug(MAILTRANSPORT_LOG) << cfgGroup;
33 d->passwordLoaded =
false;
34 d->passwordDirty =
false;
35 d->storePasswordInFile =
false;
36 d->needsWalletMigration =
false;
45 return (
id() > 0) && !
host().isEmpty() && port() <= 65536;
48 void Transport::loadPassword()
50 if (!d->passwordLoaded && requiresAuthentication() && storePassword() && d->password.isEmpty()) {
55 QString Transport::password()
const
62 d->passwordLoaded =
true;
63 if (d->password == passwd) {
66 d->passwordDirty =
true;
76 if (t->id() !=
id()) {
77 existingNames << t->name();
82 while (existingNames.
contains(name())) {
84 i18nc(
"%1: name; %2: number appended to it to make "
85 "it unique among a list of names",
96 if (original ==
this) {
97 qCWarning(MAILTRANSPORT_LOG) <<
"Tried to update password state of non-cloned transport.";
101 d->password = original->d->password;
102 d->passwordLoaded = original->d->passwordLoaded;
103 d->passwordDirty = original->d->passwordDirty;
106 qCWarning(MAILTRANSPORT_LOG) <<
"Transport with this ID not managed by transport manager.";
112 return !requiresAuthentication() || !storePassword() || d->passwordLoaded;
123 case EnumAuthenticationType::LOGIN:
124 return QStringLiteral(
"LOGIN");
125 case EnumAuthenticationType::PLAIN:
126 return QStringLiteral(
"PLAIN");
127 case EnumAuthenticationType::CRAM_MD5:
128 return QStringLiteral(
"CRAM-MD5");
129 case EnumAuthenticationType::DIGEST_MD5:
130 return QStringLiteral(
"DIGEST-MD5");
131 case EnumAuthenticationType::NTLM:
132 return QStringLiteral(
"NTLM");
133 case EnumAuthenticationType::GSSAPI:
134 return QStringLiteral(
"GSSAPI");
135 case EnumAuthenticationType::CLEAR:
136 return i18nc(
"Authentication method",
"Clear text");
137 case EnumAuthenticationType::APOP:
138 return QStringLiteral(
"APOP");
139 case EnumAuthenticationType::ANONYMOUS:
140 return i18nc(
"Authentication method",
"Anonymous");
141 case EnumAuthenticationType::XOAUTH2:
142 return QStringLiteral(
"XOAUTH2");
148 void Transport::usrRead()
150 TransportBase::usrRead();
154 if (d->oldName.isEmpty()) {
161 d->transportType.d->mIdentifier = identifier();
166 int index = types.
indexOf(d->transportType);
168 d->transportType = types[index];
170 qCWarning(MAILTRANSPORT_LOG) <<
"Type unknown to manager.";
171 d->transportType.d->mName =
i18nc(
"An unknown transport type",
"Unknown");
177 if (!storePassword()) {
181 if (d->passwordLoaded) {
187 if (group.hasKey(
"password")) {
191 if (!d->password.isEmpty()) {
192 d->passwordLoaded =
true;
197 d->needsWalletMigration =
true;
199 d->storePasswordInFile =
true;
204 bool Transport::usrSave()
206 if (requiresAuthentication() && storePassword() && d->passwordDirty) {
207 const QString storePassword = d->password;
208 auto writeJob =
new WritePasswordJob(WALLET_FOLDER,
this);
209 connect(writeJob, &Job::finished,
this, [=] {
210 if (writeJob->error()) {
211 qWarning(MAILTRANSPORT_LOG()) <<
"WritePasswordJob failed with: " << writeJob->errorString();
213 if (d->storePasswordInFile
214 || KMessageBox::warningTwoActions(nullptr,
215 i18n(
"QKeychain not found a backend for storing your password. "
216 "It is strongly recommended to use strong backend for managing your passwords.\n"
217 "However, the password can be stored in the configuration "
218 "file instead. The password is stored in an obfuscated format, "
219 "but should not be considered secure from decryption efforts "
220 "if access to the configuration file is obtained.\n"
221 "Do you want to store the password for server '%1' in the "
222 "configuration file?",
224 i18n(
"KWallet Not Available"),
225 KGuiItem(i18n(
"Store Password")),
226 KGuiItem(i18n(
"Do Not Store Password")))
227 == KMessageBox::ButtonCode::PrimaryAction) {
229 KConfigGroup group(config(), currentGroup());
230 group.writeEntry(
"password", KStringHandler::obscure(storePassword));
231 d->storePasswordInFile = true;
237 writeJob->setTextData(storePassword);
242 d->passwordDirty =
false;
245 if (!TransportBase::usrSave()) {
249 if (
name() != d->oldName) {
257 void Transport::readPassword()
260 if (!requiresAuthentication()) {
263 d->passwordLoaded =
true;
265 auto readJob =
new ReadPasswordJob(WALLET_FOLDER,
this);
266 connect(readJob, &Job::finished,
this, &Transport::readTransportPasswordFinished);
271 void Transport::readTransportPasswordFinished(QKeychain::Job *baseJob)
273 auto job = qobject_cast<ReadPasswordJob *>(baseJob);
277 d->passwordLoaded =
false;
278 qWarning() <<
"We have an error during reading password " << job->errorString();
288 return d->needsWalletMigration;
293 qCDebug(MAILTRANSPORT_LOG) <<
"migrating" << id() <<
"to wallet";
294 d->needsWalletMigration =
false;
297 d->passwordDirty =
true;
298 d->storePasswordInFile =
false;
310 if (!d->transportType.isValid()) {
311 qCWarning(MAILTRANSPORT_LOG) <<
"Invalid transport type.";
313 return d->transportType;
Transport * transportById(int id, bool def=true) const
Returns the Transport object with the given id.
QString number(int n, int base)
void deleteEntry(const char *key, WriteConfigFlags pFlags=Normal)
Transport * clone() const
Returns a deep copy of this Transport object which will no longer be automatically updated.
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
QList< Transport * > transports() const
Returns a list of all available transports.
KCOREADDONS_EXPORT QString obscure(const QString &str)
int exec(QEventLoop::ProcessEventsFlags flags)
void setHost(ScriptableExtension *host)
bool isComplete() const
Returns true if all settings have been loaded.
void setPassword(const QString &passwd)
Sets the password of this transport.
A representation of a transport type.
Transport(const QString &cfgGroup)
Creates a Transport object.
static TransportManager * self()
Returns the TransportManager instance.
KSharedConfigPtr config()
int indexOf(QStringView str, int from) const const
void passwordChanged()
Emitted when the password is changed.
Represents the settings of a specific mail transport.
ScriptableExtension * host() const
void migrateToWallet()
Try to migrate the password from the config file to the wallet.
~Transport() override
Destructor.
void passwordLoaded()
Emitted when passwords have been loaded from QKeyChain.
QString authenticationTypeString() const
Returns a string representation of the authentication type.
const char * name(StandardAction id)
bool needsWalletMigration() const
Returns true if the password was not stored in the wallet.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
void forceUniqueName()
Makes sure the transport has a unique name.
void updatePasswordState()
This function synchronizes the password of this transport with the password of the transport with the...
Q_INVOKABLE bool isValid() const
Returns true if this transport is valid, ie.
QString mid(int position, int n) const const
void transportRenamed(int id, const QString &oldName, const QString &newName)
Emitted when a transport has been renamed.
void transportTypeChanged()
Emitted when the transport type is changed.
TransportType::List types() const
Returns a list of all available transport types.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Thu Mar 23 2023 04:19:12 by
doxygen 1.8.17 written
by
Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.