diff --git a/src/fdosecrets/FdoSecretsPlugin.cpp b/src/fdosecrets/FdoSecretsPlugin.cpp index 96d76e345..e75a77aed 100644 --- a/src/fdosecrets/FdoSecretsPlugin.cpp +++ b/src/fdosecrets/FdoSecretsPlugin.cpp @@ -26,8 +26,6 @@ #include -#include - using FdoSecrets::Service; // TODO: Only used for testing. Need to split service functions away from settings page. @@ -65,12 +63,8 @@ void FdoSecretsPlugin::updateServiceState() { if (FdoSecrets::settings()->isEnabled()) { if (!m_secretService && m_dbTabs) { - m_secretService.reset(new Service(this, m_dbTabs)); - connect(m_secretService.data(), &Service::error, this, [this](const QString& msg) { - emit error(tr("Fdo Secret Service: %1").arg(msg)); - }); - if (!m_secretService->initialize()) { - m_secretService.reset(); + m_secretService = Service::Create(this, m_dbTabs); + if (!m_secretService) { FdoSecrets::settings()->setEnabled(false); return; } @@ -86,7 +80,7 @@ void FdoSecretsPlugin::updateServiceState() Service* FdoSecretsPlugin::serviceInstance() const { - return m_secretService.data(); + return m_secretService.get(); } DatabaseTabWidget* FdoSecretsPlugin::dbTabs() const @@ -107,6 +101,11 @@ void FdoSecretsPlugin::emitRequestShowNotification(const QString& msg, const QSt emit requestShowNotification(msg, title, 10000); } +void FdoSecretsPlugin::emitError(const QString& msg) +{ + emit error(tr("Fdo Secret Service: %1").arg(msg)); +} + QString FdoSecretsPlugin::reportExistingService() const { auto pidStr = tr("Unknown", "Unknown PID"); diff --git a/src/fdosecrets/FdoSecretsPlugin.h b/src/fdosecrets/FdoSecretsPlugin.h index ec57fec82..fdf2aba53 100644 --- a/src/fdosecrets/FdoSecretsPlugin.h +++ b/src/fdosecrets/FdoSecretsPlugin.h @@ -22,7 +22,8 @@ #include "gui/Icons.h" #include -#include + +#include class DatabaseTabWidget; @@ -77,6 +78,12 @@ public slots: void emitRequestSwitchToDatabases(); void emitRequestShowNotification(const QString& msg, const QString& title = {}); + /** + * @brief Show error in the GUI + * @param msg + */ + void emitError(const QString& msg); + signals: void error(const QString& msg); void requestSwitchToDatabases(); @@ -86,7 +93,7 @@ signals: private: QPointer m_dbTabs; - QScopedPointer m_secretService; + std::unique_ptr m_secretService; }; #endif // KEEPASSXC_FDOSECRETSPLUGIN_H diff --git a/src/fdosecrets/objects/Collection.cpp b/src/fdosecrets/objects/Collection.cpp index c0bb8ff34..f03b92090 100644 --- a/src/fdosecrets/objects/Collection.cpp +++ b/src/fdosecrets/objects/Collection.cpp @@ -17,6 +17,7 @@ #include "Collection.h" +#include "fdosecrets/FdoSecretsPlugin.h" #include "fdosecrets/FdoSecretsSettings.h" #include "fdosecrets/objects/Item.h" #include "fdosecrets/objects/Prompt.h" @@ -34,6 +35,18 @@ namespace FdoSecrets { + Collection* Collection::Create(Service* parent, DatabaseWidget* backend) + { + std::unique_ptr coll{new Collection(parent, backend)}; + if (!coll->reloadBackend()) { + return nullptr; + } + if (!coll->backend()) { + // no exposed group on this db + return nullptr; + } + return coll.release(); + } Collection::Collection(Service* parent, DatabaseWidget* backend) : DBusObject(parent) @@ -56,11 +69,9 @@ namespace FdoSecrets } emit doneUnlockCollection(accepted); }); - - reloadBackend(); } - void Collection::reloadBackend() + bool Collection::reloadBackend() { if (m_registered) { // delete all items @@ -83,9 +94,11 @@ namespace FdoSecrets // the database may not have a name (derived from filePath) yet, which may happen if it's newly created. // defer the registration to next time a file path change happens. if (!name().isEmpty()) { - registerWithPath( - QStringLiteral(DBUS_PATH_TEMPLATE_COLLECTION).arg(p()->objectPath().path(), encodePath(name())), - new CollectionAdaptor(this)); + auto path = QStringLiteral(DBUS_PATH_TEMPLATE_COLLECTION).arg(p()->objectPath().path(), encodePath(name())); + if (!registerWithPath(path, new CollectionAdaptor(this))) { + service()->plugin()->emitError(tr("Failed to register database on DBus under the name '%1'").arg(name())); + return false; + } m_registered = true; } @@ -95,6 +108,8 @@ namespace FdoSecrets } else { cleanupConnections(); } + + return true; } DBusReturn Collection::ensureBackend() const @@ -197,7 +212,11 @@ namespace FdoSecrets } // Delete means close database - auto prompt = new DeleteCollectionPrompt(service(), this); + auto dpret = DeleteCollectionPrompt::Create(service(), this); + if (dpret.isError()) { + return dpret; + } + auto prompt = dpret.value(); if (backendLocked()) { // this won't raise a dialog, immediate execute auto pret = prompt->prompt({}); @@ -405,6 +424,8 @@ namespace FdoSecrets if (ok) { m_aliases.insert(alias); emit aliasAdded(alias); + } else { + return DBusReturn<>::Error(QDBusError::InvalidObjectPath); } return {}; @@ -558,7 +579,7 @@ namespace FdoSecrets return; } - auto item = new Item(this, entry); + auto item = Item::Create(this, entry); m_items << item; m_entryToItem[entry] = item; diff --git a/src/fdosecrets/objects/Collection.h b/src/fdosecrets/objects/Collection.h index da6dcb389..5f06cc332 100644 --- a/src/fdosecrets/objects/Collection.h +++ b/src/fdosecrets/objects/Collection.h @@ -39,8 +39,19 @@ namespace FdoSecrets class Collection : public DBusObject { Q_OBJECT - public: + explicit Collection(Service* parent, DatabaseWidget* backend); + public: + /** + * @brief Create a new instance of `Collection` + * @param parent the owning Service + * @param backend the widget containing the database + * @return pointer to created instance, or nullptr when error happens. + * This may be caused by + * - DBus path registration error + * - database has no exposed group + */ + static Collection* Create(Service* parent, DatabaseWidget* backend); DBusReturn> items() const; @@ -101,7 +112,7 @@ namespace FdoSecrets static EntrySearcher::SearchTerm attributeToTerm(const QString& key, const QString& value); public slots: - // expose some methods for Prmopt to use + // expose some methods for Prompt to use bool doLock(); void doUnlock(); // will remove self @@ -114,7 +125,7 @@ namespace FdoSecrets void onDatabaseLockChanged(); void onDatabaseExposedGroupChanged(); // force reload info from backend, potentially delete self - void reloadBackend(); + bool reloadBackend(); private: friend class DeleteCollectionPrompt; diff --git a/src/fdosecrets/objects/DBusObject.cpp b/src/fdosecrets/objects/DBusObject.cpp index 8bf1ae4e5..c53baa72e 100644 --- a/src/fdosecrets/objects/DBusObject.cpp +++ b/src/fdosecrets/objects/DBusObject.cpp @@ -31,17 +31,18 @@ namespace FdoSecrets DBusObject::DBusObject(DBusObject* parent) : QObject(parent) + , m_dbusAdaptor(nullptr) { } - void DBusObject::registerWithPath(const QString& path, QDBusAbstractAdaptor* adaptor) + bool DBusObject::registerWithPath(const QString& path, QDBusAbstractAdaptor* adaptor) { + Q_ASSERT(!m_dbusAdaptor); + m_objectPath.setPath(path); m_dbusAdaptor = adaptor; adaptor->setParent(this); - auto ok = QDBusConnection::sessionBus().registerObject(m_objectPath.path(), this); - Q_UNUSED(ok); - Q_ASSERT(ok); + return QDBusConnection::sessionBus().registerObject(m_objectPath.path(), this); } QString DBusObject::callingPeerName() const diff --git a/src/fdosecrets/objects/DBusObject.h b/src/fdosecrets/objects/DBusObject.h index 4cdaf5ced..eeb505072 100644 --- a/src/fdosecrets/objects/DBusObject.h +++ b/src/fdosecrets/objects/DBusObject.h @@ -57,7 +57,7 @@ namespace FdoSecrets } protected: - void registerWithPath(const QString& path, QDBusAbstractAdaptor* adaptor); + bool registerWithPath(const QString& path, QDBusAbstractAdaptor* adaptor); void unregisterCurrentPath() { diff --git a/src/fdosecrets/objects/DBusTypes.h b/src/fdosecrets/objects/DBusTypes.h index 384a1e6b2..ef1e2276a 100644 --- a/src/fdosecrets/objects/DBusTypes.h +++ b/src/fdosecrets/objects/DBusTypes.h @@ -43,6 +43,7 @@ #define DBUS_PATH_TEMPLATE_SESSION "%1/session/%2" #define DBUS_PATH_TEMPLATE_COLLECTION "%1/collection/%2" #define DBUS_PATH_TEMPLATE_ITEM "%1/%2" +#define DBUS_PATH_TEMPLATE_PROMPT "%1/prompt/%2" namespace FdoSecrets { diff --git a/src/fdosecrets/objects/Item.cpp b/src/fdosecrets/objects/Item.cpp index d58cbcc2c..038b9a922 100644 --- a/src/fdosecrets/objects/Item.cpp +++ b/src/fdosecrets/objects/Item.cpp @@ -48,18 +48,36 @@ namespace FdoSecrets constexpr auto FDO_SECRETS_CONTENT_TYPE = "FDO_SECRETS_CONTENT_TYPE"; } // namespace + Item* Item::Create(Collection* parent, Entry* backend) + { + std::unique_ptr res{new Item(parent, backend)}; + + if (!res->registerSelf()) { + return nullptr; + } + + return res.release(); + } + Item::Item(Collection* parent, Entry* backend) : DBusObject(parent) , m_backend(backend) { Q_ASSERT(!p()->objectPath().path().isEmpty()); - registerWithPath(QStringLiteral(DBUS_PATH_TEMPLATE_ITEM).arg(p()->objectPath().path(), m_backend->uuidToHex()), - new ItemAdaptor(this)); - connect(m_backend.data(), &Entry::entryModified, this, &Item::itemChanged); } + bool Item::registerSelf() + { + auto path = QStringLiteral(DBUS_PATH_TEMPLATE_ITEM).arg(p()->objectPath().path(), m_backend->uuidToHex()); + bool ok = registerWithPath(path, new ItemAdaptor(this)); + if (!ok) { + service()->plugin()->emitError(tr("Failed to register item on DBus at path '%1'").arg(path)); + } + return ok; + } + DBusReturn Item::locked() const { auto ret = ensureBackend(); @@ -206,8 +224,8 @@ namespace FdoSecrets if (ret.isError()) { return ret; } - auto prompt = new DeleteItemPrompt(service(), this); - return prompt; + auto prompt = DeleteItemPrompt::Create(service(), this); + return prompt.value(); } DBusReturn Item::getSecret(Session* session) diff --git a/src/fdosecrets/objects/Item.h b/src/fdosecrets/objects/Item.h index 99601d950..746850e79 100644 --- a/src/fdosecrets/objects/Item.h +++ b/src/fdosecrets/objects/Item.h @@ -41,8 +41,18 @@ namespace FdoSecrets class Item : public DBusObject { Q_OBJECT - public: + explicit Item(Collection* parent, Entry* backend); + public: + /** + * @brief Create a new instance of `Item`. + * @param parent the owning `Collection` + * @param backend the `Entry` containing the data + * @return pointer to newly created Item, or nullptr if error + * This may be caused by + * - DBus path registration error + */ + static Item* Create(Collection* parent, Entry* backend); DBusReturn locked() const; @@ -91,6 +101,12 @@ namespace FdoSecrets void doDelete(); private: + /** + * @brief Register self on DBus + * @return + */ + bool registerSelf(); + /** * Check if the backend is a valid object, send error reply if not. * @return No error if the backend is valid. diff --git a/src/fdosecrets/objects/Prompt.cpp b/src/fdosecrets/objects/Prompt.cpp index cb3cb4f48..b20be86f1 100644 --- a/src/fdosecrets/objects/Prompt.cpp +++ b/src/fdosecrets/objects/Prompt.cpp @@ -17,6 +17,7 @@ #include "Prompt.h" +#include "fdosecrets/FdoSecretsPlugin.h" #include "fdosecrets/FdoSecretsSettings.h" #include "fdosecrets/objects/Collection.h" #include "fdosecrets/objects/Item.h" @@ -35,13 +36,19 @@ namespace FdoSecrets PromptBase::PromptBase(Service* parent) : DBusObject(parent) { - registerWithPath( - QStringLiteral("%1/prompt/%2").arg(p()->objectPath().path(), Tools::uuidToHex(QUuid::createUuid())), - new PromptAdaptor(this)); - connect(this, &PromptBase::completed, this, &PromptBase::deleteLater); } + bool PromptBase::registerSelf() + { + auto path = QStringLiteral(DBUS_PATH_TEMPLATE_PROMPT).arg(p()->objectPath().path(), Tools::uuidToHex(QUuid::createUuid())); + bool ok = registerWithPath(path, new PromptAdaptor(this)); + if (!ok) { + service()->plugin()->emitError(tr("Failed to register item on DBus at path '%1'").arg(path)); + } + return ok; + } + QWindow* PromptBase::findWindow(const QString& windowId) { // find parent window, or nullptr if not found @@ -69,6 +76,15 @@ namespace FdoSecrets return {}; } + DBusReturn DeleteCollectionPrompt::Create(Service* parent, Collection* coll) + { + std::unique_ptr res{new DeleteCollectionPrompt(parent, coll)}; + if (!res->registerSelf()) { + return DBusReturn<>::Error(QDBusError::InvalidObjectPath); + } + return res.release(); + } + DeleteCollectionPrompt::DeleteCollectionPrompt(Service* parent, Collection* coll) : PromptBase(parent) , m_collection(coll) @@ -100,6 +116,15 @@ namespace FdoSecrets return {}; } + DBusReturn CreateCollectionPrompt::Create(Service* parent) + { + std::unique_ptr res{new CreateCollectionPrompt(parent)}; + if (!res->registerSelf()) { + return DBusReturn<>::Error(QDBusError::InvalidObjectPath); + } + return res.release(); + } + CreateCollectionPrompt::CreateCollectionPrompt(Service* parent) : PromptBase(parent) { @@ -136,6 +161,15 @@ namespace FdoSecrets return {}; } + DBusReturn LockCollectionsPrompt::Create(Service* parent, const QList& colls) + { + std::unique_ptr res{new LockCollectionsPrompt(parent, colls)}; + if (!res->registerSelf()) { + return DBusReturn<>::Error(QDBusError::InvalidObjectPath); + } + return res.release(); + } + LockCollectionsPrompt::LockCollectionsPrompt(Service* parent, const QList& colls) : PromptBase(parent) { @@ -179,6 +213,15 @@ namespace FdoSecrets return {}; } + DBusReturn UnlockCollectionsPrompt::Create(Service* parent, const QList& coll) + { + std::unique_ptr res{new UnlockCollectionsPrompt(parent, coll)}; + if (!res->registerSelf()) { + return DBusReturn<>::Error(QDBusError::InvalidObjectPath); + } + return res.release(); + } + UnlockCollectionsPrompt::UnlockCollectionsPrompt(Service* parent, const QList& colls) : PromptBase(parent) { @@ -246,6 +289,15 @@ namespace FdoSecrets return {}; } + DBusReturn DeleteItemPrompt::Create(Service* parent, Item* item) + { + std::unique_ptr res{new DeleteItemPrompt(parent, item)}; + if (!res->registerSelf()) { + return DBusReturn<>::Error(QDBusError::InvalidObjectPath); + } + return res.release(); + } + DeleteItemPrompt::DeleteItemPrompt(Service* parent, Item* item) : PromptBase(parent) , m_item(item) diff --git a/src/fdosecrets/objects/Prompt.h b/src/fdosecrets/objects/Prompt.h index 683642df5..10939dcbc 100644 --- a/src/fdosecrets/objects/Prompt.h +++ b/src/fdosecrets/objects/Prompt.h @@ -36,8 +36,6 @@ namespace FdoSecrets { Q_OBJECT public: - explicit PromptBase(Service* parent); - virtual DBusReturn prompt(const QString& windowId) = 0; virtual DBusReturn dismiss(); @@ -46,6 +44,9 @@ namespace FdoSecrets void completed(bool dismissed, const QVariant& result); protected: + explicit PromptBase(Service* parent); + + bool registerSelf(); QWindow* findWindow(const QString& windowId); Service* service() const; }; @@ -56,8 +57,9 @@ namespace FdoSecrets { Q_OBJECT - public: explicit DeleteCollectionPrompt(Service* parent, Collection* coll); + public: + static DBusReturn Create(Service* parent, Collection* coll); DBusReturn prompt(const QString& windowId) override; @@ -69,8 +71,9 @@ namespace FdoSecrets { Q_OBJECT - public: explicit CreateCollectionPrompt(Service* parent); + public: + static DBusReturn Create(Service* parent); DBusReturn prompt(const QString& windowId) override; DBusReturn dismiss() override; @@ -82,8 +85,10 @@ namespace FdoSecrets class LockCollectionsPrompt : public PromptBase { Q_OBJECT - public: + explicit LockCollectionsPrompt(Service* parent, const QList& colls); + public: + static DBusReturn Create(Service* parent, const QList& colls); DBusReturn prompt(const QString& windowId) override; DBusReturn dismiss() override; @@ -96,8 +101,10 @@ namespace FdoSecrets class UnlockCollectionsPrompt : public PromptBase { Q_OBJECT - public: + explicit UnlockCollectionsPrompt(Service* parent, const QList& coll); + public: + static DBusReturn Create(Service* parent, const QList& coll); DBusReturn prompt(const QString& windowId) override; DBusReturn dismiss() override; @@ -116,8 +123,9 @@ namespace FdoSecrets { Q_OBJECT - public: explicit DeleteItemPrompt(Service* parent, Item* item); + public: + static DBusReturn Create(Service* parent, Item* item); DBusReturn prompt(const QString& windowId) override; diff --git a/src/fdosecrets/objects/Service.cpp b/src/fdosecrets/objects/Service.cpp index 892ba68a4..34ace7213 100644 --- a/src/fdosecrets/objects/Service.cpp +++ b/src/fdosecrets/objects/Service.cpp @@ -31,6 +31,8 @@ #include #include +#include + namespace { constexpr auto DEFAULT_ALIAS = "default"; @@ -38,6 +40,14 @@ namespace namespace FdoSecrets { + std::unique_ptr Service::Create(FdoSecretsPlugin* plugin, QPointer dbTabs) + { + std::unique_ptr res{new Service(plugin, std::move(dbTabs))}; + if (!res->initialize()) { + return {}; + } + return res; + } Service::Service(FdoSecretsPlugin* plugin, QPointer dbTabs) // clazy: exclude=ctor-missing-parent-argument @@ -59,16 +69,19 @@ namespace FdoSecrets bool Service::initialize() { if (!QDBusConnection::sessionBus().registerService(QStringLiteral(DBUS_SERVICE_SECRET))) { - emit error(tr("Failed to register DBus service at %1.
").arg(QLatin1String(DBUS_SERVICE_SECRET)) + plugin()->emitError(tr("Failed to register DBus service at %1.
").arg(QLatin1String(DBUS_SERVICE_SECRET)) + m_plugin->reportExistingService()); return false; } - registerWithPath(QStringLiteral(DBUS_PATH_SECRETS), new ServiceAdaptor(this)); + if (!registerWithPath(QStringLiteral(DBUS_PATH_SECRETS), new ServiceAdaptor(this))) { + plugin()->emitError(tr("Failed to register DBus path %1.
").arg(QStringLiteral(DBUS_PATH_SECRETS))); + return false; + } // Connect to service unregistered signal m_serviceWatcher.reset(new QDBusServiceWatcher()); - connect(m_serviceWatcher.data(), + connect(m_serviceWatcher.get(), &QDBusServiceWatcher::serviceUnregistered, this, &Service::dbusServiceUnregistered); @@ -106,11 +119,10 @@ namespace FdoSecrets monitorDatabaseExposedGroup(dbWidget); }); - auto coll = new Collection(this, dbWidget); - // Creation may fail if the database is not exposed. - // This is okay, because we monitor the expose settings above - if (!coll->isValid()) { - coll->deleteLater(); + auto coll = Collection::Create(this, dbWidget); + if (!coll) { + // The creation may fail if the database is not exposed. + // This is okay, because we monitor the expose settings above return; } @@ -184,8 +196,9 @@ namespace FdoSecrets Q_ASSERT(m_serviceWatcher); auto removed = m_serviceWatcher->removeWatchedService(service); - Q_UNUSED(removed); - Q_ASSERT(removed); + if (!removed) { + qDebug("FdoSecrets: Failed to remove service watcher"); + } Session::CleanupNegotiation(service); auto sess = m_peerToSession.value(service, nullptr); @@ -218,7 +231,10 @@ namespace FdoSecrets if (!ciphers) { return DBusReturn<>::Error(QDBusError::NotSupported); } - result = new Session(std::move(ciphers), callingPeerName(), this); + result = Session::Create(std::move(ciphers), callingPeerName(), this); + if (!result) { + return DBusReturn<>::Error(QDBusError::InvalidObjectPath); + } m_sessions.append(result); m_peerToSession[peer] = result; @@ -240,12 +256,15 @@ namespace FdoSecrets // return existing collection if alias is non-empty and exists. auto collection = findCollection(alias); if (!collection) { - auto cp = new CreateCollectionPrompt(this); - prompt = cp; + auto cp = CreateCollectionPrompt::Create(this); + if (cp.isError()) { + return cp; + } + prompt = cp.value(); - // collection will be created when the prompt complets. + // collection will be created when the prompt completes. // once it's done, we set additional properties on the collection - connect(cp, &CreateCollectionPrompt::collectionCreated, cp, [alias, properties](Collection* coll) { + connect(cp.value(), &CreateCollectionPrompt::collectionCreated, cp.value(), [alias, properties](Collection* coll) { coll->setProperties(properties).okOrDie(); if (!alias.isEmpty()) { coll->addAlias(alias).okOrDie(); @@ -314,7 +333,11 @@ namespace FdoSecrets } } if (!toUnlock.isEmpty()) { - prompt = new UnlockCollectionsPrompt(this, toUnlock); + auto up = UnlockCollectionsPrompt::Create(this, toUnlock); + if (up.isError()) { + return up; + } + prompt = up.value(); } return unlocked; } @@ -352,7 +375,11 @@ namespace FdoSecrets } } if (!toLock.isEmpty()) { - prompt = new LockCollectionsPrompt(this, toLock); + auto lp = LockCollectionsPrompt::Create(this, toLock); + if (lp.isError()) { + return lp; + } + prompt = lp.value(); } return locked; } diff --git a/src/fdosecrets/objects/Service.h b/src/fdosecrets/objects/Service.h index 4e0eeb0ff..d8d7529d8 100644 --- a/src/fdosecrets/objects/Service.h +++ b/src/fdosecrets/objects/Service.h @@ -24,9 +24,10 @@ #include #include #include -#include #include +#include + class QDBusServiceWatcher; class DatabaseTabWidget; @@ -47,11 +48,17 @@ namespace FdoSecrets class Service : public DBusObject // clazy: exclude=ctor-missing-parent-argument { Q_OBJECT - public: - explicit Service(FdoSecretsPlugin* plugin, QPointer dbTabs); - ~Service() override; - bool initialize(); + explicit Service(FdoSecretsPlugin* plugin, QPointer dbTabs); + public: + /** + * @brief Create a new instance of `Service`. Its parent is set to `null` + * @return pointer to newly created Service, or nullptr if error + * This may be caused by + * - failed initialization + */ + static std::unique_ptr Create(FdoSecretsPlugin* plugin, QPointer dbTabs); + ~Service() override; DBusReturn openSession(const QString& algorithm, const QVariant& input, Session*& result); DBusReturn @@ -82,12 +89,6 @@ namespace FdoSecrets void sessionOpened(Session* sess); void sessionClosed(Session* sess); - /** - * Report error message to the GUI - * @param msg - */ - void error(const QString& msg); - /** * Finish signal for async action doUnlockDatabaseInDialog * @param accepted If false, the action is canceled by the user @@ -131,6 +132,8 @@ namespace FdoSecrets void onCollectionAliasRemoved(const QString& alias); private: + bool initialize(); + /** * Find collection by alias name * @param alias @@ -158,7 +161,7 @@ namespace FdoSecrets bool m_insdieEnsureDefaultAlias; - QScopedPointer m_serviceWatcher; + std::unique_ptr m_serviceWatcher; }; } // namespace FdoSecrets diff --git a/src/fdosecrets/objects/Session.cpp b/src/fdosecrets/objects/Session.cpp index 4845752a1..1d5020197 100644 --- a/src/fdosecrets/objects/Session.cpp +++ b/src/fdosecrets/objects/Session.cpp @@ -16,6 +16,7 @@ */ #include "Session.h" +#include "fdosecrets/FdoSecretsPlugin.h" #include "fdosecrets/objects/SessionCipher.h" #include "core/Tools.h" @@ -25,14 +26,33 @@ namespace FdoSecrets QHash Session::negoniationState; + Session* Session::Create(std::unique_ptr&& cipher, const QString& peer, Service* parent) + { + std::unique_ptr res{new Session(std::move(cipher), peer, parent)}; + + if (!res->registerSelf()) { + return nullptr; + } + + return res.release(); + } + Session::Session(std::unique_ptr&& cipher, const QString& peer, Service* parent) : DBusObject(parent) , m_cipher(std::move(cipher)) , m_peer(peer) , m_id(QUuid::createUuid()) { - registerWithPath(QStringLiteral(DBUS_PATH_TEMPLATE_SESSION).arg(p()->objectPath().path(), id()), - new SessionAdaptor(this)); + } + + bool Session::registerSelf() + { + auto path = QStringLiteral(DBUS_PATH_TEMPLATE_SESSION).arg(p()->objectPath().path(), id()); + bool ok = registerWithPath(path, new SessionAdaptor(this)); + if (!ok) { + service()->plugin()->emitError(tr("Failed to register session on DBus at path '%1'").arg(path)); + } + return ok; } void Session::CleanupNegotiation(const QString& peer) @@ -58,6 +78,11 @@ namespace FdoSecrets return Tools::uuidToHex(m_id); } + Service* Session::service() const + { + return qobject_cast(parent()); + } + std::unique_ptr Session::CreateCiphers(const QString& peer, const QString& algorithm, const QVariant& input, diff --git a/src/fdosecrets/objects/Session.h b/src/fdosecrets/objects/Session.h index 472cc6e5a..199a7cccf 100644 --- a/src/fdosecrets/objects/Session.h +++ b/src/fdosecrets/objects/Session.h @@ -37,6 +37,8 @@ namespace FdoSecrets class Session : public DBusObject { Q_OBJECT + + explicit Session(std::unique_ptr&& cipher, const QString& peer, Service* parent); public: static std::unique_ptr CreateCiphers(const QString& peer, const QString& algorithm, @@ -45,7 +47,16 @@ namespace FdoSecrets bool& incomplete); static void CleanupNegotiation(const QString& peer); - explicit Session(std::unique_ptr&& cipher, const QString& peer, Service* parent); + /** + * @brief Create a new instance of `Session`. + * @param cipher the negotiated cipher + * @param peer connecting peer + * @param parent the owning Service + * @return pointer to newly created Session, or nullptr if error + * This may be caused by + * - DBus path registration error + */ + static Session* Create(std::unique_ptr&& cipher, const QString& peer, Service* parent); DBusReturn close(); @@ -71,6 +82,8 @@ namespace FdoSecrets QString id() const; + Service* service() const; + signals: /** * The session is going to be closed @@ -78,6 +91,9 @@ namespace FdoSecrets */ void aboutToClose(); + private: + bool registerSelf(); + private: std::unique_ptr m_cipher; QString m_peer;