aboutsummaryrefslogtreecommitdiff
path: root/credentials.cpp
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2023-08-28 00:20:54 +0200
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2023-09-18 10:35:30 +0200
commit5bbe04c9ca091a0626f34afe5e3ba2141e2963de (patch)
tree35e76183618fe557b4ded5735fb846e3c6cf3995 /credentials.cpp
parentd32b9e93572c5e6999a7323139de38cc1a7197cf (diff)
WIP OMEMO TrustDb/JidDb
Diffstat (limited to 'credentials.cpp')
-rw-r--r--credentials.cpp251
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();
}