diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2023-08-28 00:20:54 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2023-09-18 10:35:30 +0200 |
| commit | 5bbe04c9ca091a0626f34afe5e3ba2141e2963de (patch) | |
| tree | 35e76183618fe557b4ded5735fb846e3c6cf3995 /credentials.cpp | |
| parent | d32b9e93572c5e6999a7323139de38cc1a7197cf (diff) | |
WIP OMEMO TrustDb/JidDb
Diffstat (limited to 'credentials.cpp')
| -rw-r--r-- | credentials.cpp | 251 |
1 files changed, 183 insertions, 68 deletions
diff --git a/credentials.cpp b/credentials.cpp index 8d6a01b..5cd6e6f 100644 --- a/credentials.cpp +++ b/credentials.cpp @@ -1,103 +1,218 @@ #include "credentials.h" -#include <QEventLoop> #include <qt5keychain/keychain.h> +#include <QXmppPromise.h> #include <QXmppConfiguration.h> #include <iostream> static const QString service = "xxcc", sep = ";"; -QList<Credentials::Pair> Credentials::load() +QXmppTask<Credentials::PairListResult> Credentials::load( + Credentials::PairList &pairs, + QStringList::const_iterator &it, + QStringList::const_iterator end) { - const QStringList users = storedUsers(); - QList<Pair> ret; + if (it == end) + return QXmpp::Private::makeReadyTask<PairListResult>( + PairListResult(pairs)); - for (const auto &user : users) - { - QKeychain::ReadPasswordJob job(service); - QEventLoop loop; - - job.setKey(user); - job.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit); - job.start(); - loop.exec(); + QXmppPromise<PairListResult> promise; - const QString pwd = job.textData(); + load(*it).then(this, + [=] (LoadResult &&result) mutable + { + if (std::holds_alternative<QString>(result)) + { + pairs << Pair(*it, std::get<QString>(result)); + + load(pairs, ++it, end).then(this, + [=] (PairListResult &&result) mutable + { + promise.finish(result); + }); + } + else if (std::holds_alternative<Error>(result)) + promise.finish(Error{std::get<Error>(result)}); + }); + + return promise.task(); +} - if (job.error()) - std::cerr << "Failed to retrieve password for " << qPrintable(user) - << ": " << qPrintable(job.errorString()) << std::endl; - else - ret.append(Pair(user, pwd)); - } +QXmppTask<Credentials::PairListResult> Credentials::load() +{ + QXmppPromise<PairListResult> promise; - return ret; + storedUsers().then(this, + [=] (Users &&result) mutable + { + if (std::holds_alternative<QStringList>(result)) + { + PairList pairs; + auto list = new QStringList(std::get<QStringList>(result)); + auto begin = list->cbegin(); + const auto end = list->cend(); + + load(pairs, begin, end).then(this, + [=] (PairListResult &&result) mutable + { + delete list; + promise.finish(result); + }); + } + else if (std::holds_alternative<Error>(result)) + promise.finish(Error{std::get<Error>(result)}); + }); + + return promise.task(); } -void Credentials::store(Client *c) +QXmppTask<Credentials::StoreResult> Credentials::store(Client *c) { - QKeychain::WritePasswordJob job(service); + QXmppPromise<StoreResult> promise; const QXmppConfiguration &cfg = c->configuration(); const QString user = cfg.jidBare(); - QEventLoop loop; - - job.setKey(user); - job.setTextData(cfg.password()); - job.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit); - job.start(); - loop.exec(); - - if (job.error()) - std::cerr << "Failed to store password: " - << qPrintable(job.errorString()) << std::endl; - else - storeUser(user); + + store(user, cfg.password()).then(this, + [=] (StoreResult &&result) mutable + { + store(user).then(this, + [=] (StoreResult &&result) mutable + { + promise.finish(result); + }); + }); + + return promise.task(); } -void Credentials::storeUser(const QString &user) +QXmppTask<Credentials::StoreResult> Credentials::store(const QString &user) { - QString list = storedUsersList(); - QKeychain::WritePasswordJob job(service); - QEventLoop loop; + QXmppPromise<StoreResult> promise; + + storedUsersList().then(this, + [=] (LoadResult &&result) mutable + { + if (std::holds_alternative<QString>(result)) + { + auto &list = std::get<QString>(result); + + if (!list.isEmpty()) + list += sep; + + list += user; + store("users", list).then(this, + [=] (StoreResult &&result) mutable + { + promise.finish(result); + }); + } + else if (std::holds_alternative<Error>(result)) + { + store("users", user).then(this, + [=] (StoreResult &&result) mutable + { + promise.finish(result); + }); + } + }); + + return promise.task(); +} - if (!list.isEmpty()) - list += sep; +QXmppTask<Credentials::LoadResult> Credentials::storedUsersList() +{ + QXmppPromise<LoadResult> promise; - list += user; + load("users").then(this, + [=] (LoadResult &&result) mutable + { + promise.finish(result); + }); - job.setKey("users"); - job.setTextData(list); - job.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit); - job.start(); - loop.exec(); + return promise.task(); - if (job.error()) - std::cerr << "Failed to store user: " - << qPrintable(job.errorString()) << std::endl; } -QString Credentials::storedUsersList() +QXmppTask<Credentials::LoadResult> Credentials::load(const QString &key) { - QKeychain::ReadPasswordJob job(service); - QString ret; - QEventLoop loop; + QXmppPromise<LoadResult> promise; + auto job = new QKeychain::ReadPasswordJob(service); - job.setKey("users"); - job.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit); - job.start(); - loop.exec(); + job->setKey(key); + job->connect(job, &QKeychain::Job::finished, this, + [=] (QKeychain::Job *const job) mutable + { + auto readjob = dynamic_cast<QKeychain::ReadPasswordJob *>(job); - const QString users = job.textData(); + if (readjob->error()) + { + const auto error = "Failed to load " + key + ": " + + readjob->errorString(); - if (job.error()) - std::cerr << "Failed to retrieve users: " - << qPrintable(job.errorString()) << std::endl; - else - ret = users; + std::cerr << qPrintable(error) << std::endl; + promise.finish(Error{error}); + } + else + { + auto users = readjob->textData(); - return ret; + promise.finish(QString(users)); + } + }); + + job->start(); + return promise.task(); } -QStringList Credentials::storedUsers() +QXmppTask<Credentials::StoreResult> Credentials::store(const QString &key, + const QString &value) { - return storedUsersList().split(sep); + QXmppPromise<StoreResult> promise; + auto job = new QKeychain::WritePasswordJob(service); + + job->setKey(key); + job->setTextData(value); + job->connect(job, &QKeychain::Job::finished, this, + [=] (QKeychain::Job *const job) mutable + { + if (job->error()) + { + StoreResult sr; + + const auto error = "Failed to store " + key + ": " + + job->errorString(); + + std::cerr << qPrintable(error) << std::endl; + sr = Error{error}; + promise.finish(StoreResult(sr)); + } + else + promise.finish(Success{}); + }); + + job->start(); + return promise.task(); +} + +QXmppTask<Credentials::Users> Credentials::storedUsers() +{ + QXmppPromise<Users> promise; + + storedUsersList().then(this, + [=] (LoadResult &&result) mutable + { + if (std::holds_alternative<QString>(result)) + { + const auto &value = std::get<QString>(result); + + promise.finish(QStringList(value.split(sep))); + } + else if (std::holds_alternative<Error>(result)) + { + const auto &error = std::get<Error>(result); + + promise.finish(Error{error.description}); + } + }); + + return promise.task(); } |
