File indexing completed on 2024-11-24 04:53:25

0001 /* Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.com>
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 <QString>
0024 #include <qt5keychain/keychain.h>
0025 #include "QtKeyChainPassword.h"
0026 
0027 namespace Plugins {
0028 
0029 QtKeyChainPasswordJob::QtKeyChainPasswordJob(const QString &accountId, const QString &accountType, const QString &password,
0030     enum Type type, QObject *parent) :
0031     PasswordJob(parent), m_accountId(accountId), m_accountType(accountType), m_password(password), m_type(type), m_job(0)
0032 {
0033 }
0034 
0035 void QtKeyChainPasswordJob::doStart()
0036 {
0037     switch (m_type) {
0038     case Request:
0039         m_job = new QKeychain::ReadPasswordJob(QStringLiteral("Trojita"), this);
0040         static_cast<QKeychain::ReadPasswordJob *>(m_job)->setKey(m_accountId + QLatin1Char('-') + m_accountType);
0041         break;
0042     case Store:
0043         m_job = new QKeychain::WritePasswordJob(QStringLiteral("Trojita"), this);
0044         static_cast<QKeychain::WritePasswordJob *>(m_job)->setKey(m_accountId + QLatin1Char('-') + m_accountType);
0045         static_cast<QKeychain::WritePasswordJob *>(m_job)->setTextData(m_password);
0046         break;
0047     case Delete:
0048         m_job = new QKeychain::DeletePasswordJob(QStringLiteral("Trojita"), this);
0049         static_cast<QKeychain::DeletePasswordJob *>(m_job)->setKey(m_accountId + QLatin1Char('-') + m_accountType);
0050         break;
0051     }
0052     m_job->setAutoDelete(true);
0053     connect(m_job, &QKeychain::Job::finished, this, &QtKeyChainPasswordJob::result);
0054     m_job->start();
0055 }
0056 
0057 void QtKeyChainPasswordJob::result()
0058 {
0059     switch (m_job->error()) {
0060     case QKeychain::NoError:
0061         break;
0062     case QKeychain::EntryNotFound:
0063         emit error(PasswordJob::NoSuchPassword, QString());
0064         return;
0065     default:
0066         emit error(PasswordJob::UnknownError, m_job->errorString());
0067         return;
0068     }
0069 
0070     switch (m_type) {
0071     case Request:
0072         m_password = qobject_cast<QKeychain::ReadPasswordJob *>(m_job)->textData();
0073         emit passwordAvailable(m_password);
0074         return;
0075     case Store:
0076         emit passwordStored();
0077         return;
0078     case Delete:
0079         emit passwordDeleted();
0080         return;
0081     }
0082 }
0083 
0084 void QtKeyChainPasswordJob::doStop()
0085 {
0086     if (m_job) {
0087         disconnect(m_job, nullptr, this, nullptr);
0088         m_job->deleteLater();
0089         m_job = 0;
0090     }
0091     emit error(PasswordJob::Stopped, QString());
0092 }
0093 
0094 QtKeyChainPassword::QtKeyChainPassword(QObject *parent) : PasswordPlugin(parent)
0095 {
0096 }
0097 
0098 PasswordPlugin::Features QtKeyChainPassword::features() const
0099 {
0100     return PasswordPlugin::FeatureEncryptedStorage;
0101 }
0102 
0103 PasswordJob *QtKeyChainPassword::requestPassword(const QString &accountId, const QString &accountType)
0104 {
0105     return new QtKeyChainPasswordJob(accountId, accountType, QString(), QtKeyChainPasswordJob::Request, this);
0106 }
0107 
0108 PasswordJob *QtKeyChainPassword::storePassword(const QString &accountId, const QString &accountType, const QString &password)
0109 {
0110     return new QtKeyChainPasswordJob(accountId, accountType, password, QtKeyChainPasswordJob::Store, this);
0111 }
0112 
0113 PasswordJob *QtKeyChainPassword::deletePassword(const QString &accountId, const QString &accountType)
0114 {
0115     return new QtKeyChainPasswordJob(accountId, accountType, QString(), QtKeyChainPasswordJob::Delete, this);
0116 }
0117 
0118 }
0119 
0120 QString trojita_plugin_QtKeyChainPasswordPlugin::name() const
0121 {
0122     return QStringLiteral("qtkeychainpassword");
0123 }
0124 
0125 QString trojita_plugin_QtKeyChainPasswordPlugin::description() const
0126 {
0127     return tr("Secure storage via QtKeychain");
0128 }
0129 
0130 Plugins::PasswordPlugin *trojita_plugin_QtKeyChainPasswordPlugin::create(QObject *parent, QSettings *)
0131 {
0132     return new Plugins::QtKeyChainPassword(parent);
0133 }
0134 
0135 // vim: set et ts=4 sts=4 sw=4