aboutsummaryrefslogtreecommitdiff
path: root/lib/accountregistry.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/accountregistry.cpp')
-rw-r--r--lib/accountregistry.cpp137
1 files changed, 137 insertions, 0 deletions
diff --git a/lib/accountregistry.cpp b/lib/accountregistry.cpp
new file mode 100644
index 00000000..ad7c5f99
--- /dev/null
+++ b/lib/accountregistry.cpp
@@ -0,0 +1,137 @@
+// SPDX-FileCopyrightText: Kitsune Ral <Kitsune-Ral@users.sf.net>
+// SPDX-FileCopyrightText: Tobias Fella <fella@posteo.de>
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+#include "accountregistry.h"
+
+#include "connection.h"
+#include <QtCore/QCoreApplication>
+
+using namespace Quotient;
+
+void AccountRegistry::add(Connection* a)
+{
+ if (contains(a))
+ return;
+ beginInsertRows(QModelIndex(), size(), size());
+ push_back(a);
+ endInsertRows();
+ emit accountCountChanged();
+}
+
+void AccountRegistry::drop(Connection* a)
+{
+ if (const auto idx = indexOf(a); idx != -1) {
+ beginRemoveRows(QModelIndex(), idx, idx);
+ remove(idx);
+ endRemoveRows();
+ }
+ Q_ASSERT(!contains(a));
+}
+
+bool AccountRegistry::isLoggedIn(const QString &userId) const
+{
+ return std::any_of(cbegin(), cend(), [&userId](const Connection* a) {
+ return a->userId() == userId;
+ });
+}
+
+QVariant AccountRegistry::data(const QModelIndex& index, int role) const
+{
+ if (!index.isValid() || index.row() >= count())
+ return {};
+
+ if (role == AccountRole)
+ return QVariant::fromValue(at(index.row()));
+
+ return {};
+}
+
+int AccountRegistry::rowCount(const QModelIndex& parent) const
+{
+ return parent.isValid() ? 0 : count();
+}
+
+QHash<int, QByteArray> AccountRegistry::roleNames() const
+{
+ return { { AccountRole, "connection" } };
+}
+
+Connection* AccountRegistry::get(const QString& userId)
+{
+ for (const auto &connection : *this) {
+ if (connection->userId() == userId)
+ return connection;
+ }
+ return nullptr;
+}
+
+QKeychain::ReadPasswordJob* AccountRegistry::loadAccessTokenFromKeychain(const QString& userId)
+{
+ qCDebug(MAIN) << "Reading access token from keychain for" << userId;
+ auto job = new QKeychain::ReadPasswordJob(qAppName(), this);
+ job->setKey(userId);
+ job->start();
+
+ return job;
+}
+
+void AccountRegistry::invokeLogin()
+{
+ const auto accounts = SettingsGroup("Accounts").childGroups();
+ for (const auto& accountId : accounts) {
+ AccountSettings account { accountId };
+ m_accountsLoading += accountId;
+ emit accountsLoadingChanged();
+
+ if (account.homeserver().isEmpty())
+ continue;
+
+ auto accessTokenLoadingJob =
+ loadAccessTokenFromKeychain(account.userId());
+ connect(accessTokenLoadingJob, &QKeychain::Job::finished, this,
+ [accountId, this, accessTokenLoadingJob]() {
+ if (accessTokenLoadingJob->error()
+ != QKeychain::Error::NoError) {
+ emit keychainError(accessTokenLoadingJob->error());
+ return;
+ }
+
+ AccountSettings account { accountId };
+ auto connection = new Connection(account.homeserver());
+ connect(connection, &Connection::connected, this,
+ [connection, this, accountId] {
+ connection->loadState();
+ connection->setLazyLoading(true);
+
+ connection->syncLoop();
+
+ m_accountsLoading.removeAll(accountId);
+ emit accountsLoadingChanged();
+ });
+ connect(connection, &Connection::loginError, this,
+ [this, connection, accountId](const QString& error,
+ const QString& details) {
+ emit loginError(connection, error, details);
+
+ m_accountsLoading.removeAll(accountId);
+ emit accountsLoadingChanged();
+ });
+ connect(connection, &Connection::resolveError, this,
+ [this, connection, accountId](const QString& error) {
+ emit resolveError(connection, error);
+
+ m_accountsLoading.removeAll(accountId);
+ emit accountsLoadingChanged();
+ });
+ connection->assumeIdentity(
+ account.userId(), accessTokenLoadingJob->binaryData(),
+ account.deviceId());
+ });
+ }
+}
+
+QStringList AccountRegistry::accountsLoading() const
+{
+ return m_accountsLoading;
+}