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"