File indexing completed on 2024-11-24 03:41:06

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2021 Slava Aseev <nullptrnine@basealt.ru>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 #include "kwalletfreedesktopprompt.h"
0008 
0009 #include "kwalletd.h"
0010 #include "kwalletfreedesktopcollection.h"
0011 #include "kwalletfreedesktoppromptadaptor.h"
0012 
0013 KWalletFreedesktopPrompt::KWalletFreedesktopPrompt(KWalletFreedesktopService *service, QDBusObjectPath objectPath, PromptType type, QString responseBusName)
0014     : QObject(nullptr)
0015     , m_service(service)
0016     , m_objectPath(std::move(objectPath))
0017     , m_type(type)
0018     , m_responseBusName(std::move(responseBusName))
0019 {
0020     (void)new KWalletFreedesktopPromptAdaptor(this);
0021 }
0022 
0023 KWalletFreedesktopService *KWalletFreedesktopPrompt::fdoService() const
0024 {
0025     return m_service;
0026 }
0027 
0028 KWalletD *KWalletFreedesktopPrompt::backend() const
0029 {
0030     return fdoService()->backend();
0031 }
0032 
0033 QDBusObjectPath KWalletFreedesktopPrompt::fdoObjectPath() const
0034 {
0035     return m_objectPath;
0036 }
0037 
0038 void KWalletFreedesktopPrompt::Dismiss()
0039 {
0040     auto msg = QDBusMessage::createTargetedSignal(m_responseBusName,
0041                                                   fdoObjectPath().path(),
0042                                                   QStringLiteral("org.freedesktop.Secret.Prompt"),
0043                                                   QStringLiteral("Completed"));
0044     QVariantList args;
0045     args << true << QVariant::fromValue(QDBusVariant(QVariant::fromValue(QList<QDBusObjectPath>())));
0046     msg.setArguments(args);
0047     QDBusConnection::sessionBus().send(msg);
0048     QDBusConnection::sessionBus().unregisterObject(fdoObjectPath().path());
0049 }
0050 
0051 void KWalletFreedesktopPrompt::Prompt(const QString &window_id)
0052 {
0053     if (m_type != PromptType::Open && m_type != PromptType::Create) {
0054         return;
0055     }
0056 
0057     const int wId = window_id.toInt();
0058     for (auto properties : std::as_const(m_propertiesList)) {
0059         /* When type is "PromptType::Open" the properties.label actually stores
0060          * the wallet name
0061          */
0062         QString walletName = properties.collectionLabel;
0063 
0064         if (m_type == PromptType::Create) {
0065             walletName = fdoService()->makeUniqueWalletName(properties.collectionLabel);
0066             properties.collectionLabel = walletName;
0067         }
0068 
0069         if (!properties.alias.isEmpty()) {
0070             fdoService()->createCollectionAlias(properties.alias, walletName);
0071         }
0072 
0073         const int tId = backend()->openAsync(walletName, wId, FDO_APPID, false, connection(), message());
0074         m_transactionIds.insert(tId);
0075         m_transactionIdToCollectionProperties.emplace(tId, std::move(properties));
0076     }
0077 }
0078 
0079 void KWalletFreedesktopPrompt::walletAsyncOpened(int transactionId, int walletHandle)
0080 {
0081     const auto found = m_transactionIds.find(transactionId);
0082 
0083     if (found != m_transactionIds.end()) {
0084         const auto propertiesPos = m_transactionIdToCollectionProperties.find(transactionId);
0085         if (walletHandle < 0 || propertiesPos == m_transactionIdToCollectionProperties.end()) {
0086             Dismiss();
0087             fdoService()->deletePrompt(fdoObjectPath().path());
0088             return;
0089         }
0090         m_transactionIds.remove(transactionId);
0091 
0092         const QString &walletName = propertiesPos->second.collectionLabel;
0093         const auto collectionPath = fdoService()->promptUnlockCollection(walletName, walletHandle);
0094         m_result.push_back(propertiesPos->second.objectPath.path() == QStringLiteral("/") ? collectionPath : propertiesPos->second.objectPath);
0095     }
0096 
0097     if (m_transactionIds.empty()) {
0098         /* At this point there is no remaining transactions, so we able to complete prompt */
0099 
0100         auto msg = QDBusMessage::createTargetedSignal(m_responseBusName,
0101                                                       fdoObjectPath().path(),
0102                                                       QStringLiteral("org.freedesktop.Secret.Prompt"),
0103                                                       QStringLiteral("Completed"));
0104         QVariantList args;
0105         args << false;
0106 
0107         if (m_type == PromptType::Create && m_result.size() < 2) {
0108             /* Single object in dbus variant */
0109             args << QVariant::fromValue(QDBusVariant(QVariant::fromValue(m_result.empty() ? QDBusObjectPath("/") : m_result.front())));
0110         } else {
0111             /* Object array in dbus variant */
0112             args << QVariant::fromValue(QDBusVariant(QVariant::fromValue(m_result)));
0113         }
0114 
0115         msg.setArguments(args);
0116         QDBusConnection::sessionBus().send(msg);
0117 
0118         fdoService()->deletePrompt(fdoObjectPath().path());
0119     }
0120 }
0121 
0122 void KWalletFreedesktopPrompt::subscribeForWalletAsyncOpened()
0123 {
0124     connect(backend(), &KWalletD::walletAsyncOpened, this, &KWalletFreedesktopPrompt::walletAsyncOpened);
0125     QDBusConnection::sessionBus().registerObject(fdoObjectPath().path(), this);
0126 }
0127 
0128 void KWalletFreedesktopPrompt::appendProperties(const QString &label, const QDBusObjectPath &objectPath, const QString &alias)
0129 {
0130     m_propertiesList.push_back(CollectionProperties{label, objectPath, alias});
0131 }
0132 
0133 #include "moc_kwalletfreedesktopprompt.cpp"