aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/connection.cpp36
-rw-r--r--lib/connection.h47
2 files changed, 78 insertions, 5 deletions
diff --git a/lib/connection.cpp b/lib/connection.cpp
index 6ad24fba..1989050e 100644
--- a/lib/connection.cpp
+++ b/lib/connection.cpp
@@ -30,7 +30,6 @@
#include "csapi/capabilities.h"
#include "csapi/joining.h"
#include "csapi/leaving.h"
-#include "csapi/login.h"
#include "csapi/logout.h"
#include "csapi/receipts.h"
#include "csapi/room_send.h"
@@ -111,6 +110,8 @@ public:
GetCapabilitiesJob* capabilitiesJob = nullptr;
GetCapabilitiesJob::Capabilities capabilities;
+ QVector<GetLoginFlowsJob::LoginFlow> loginFlows;
+
#ifdef Quotient_E2EE_ENABLED
QScopedPointer<EncryptionManager> encryptionManager;
#endif // Quotient_E2EE_ENABLED
@@ -1004,6 +1005,21 @@ QUrl Connection::homeserver() const { return d->data->baseUrl(); }
QString Connection::domain() const { return userId().section(':', 1); }
+QVector<GetLoginFlowsJob::LoginFlow> Connection::loginFlows() const
+{
+ return d->loginFlows;
+}
+
+bool Connection::supportsPasswordAuth() const
+{
+ return d->loginFlows.contains(LoginFlows::Password);
+}
+
+bool Connection::supportsSso() const
+{
+ return d->loginFlows.contains(LoginFlows::SSO);
+}
+
Room* Connection::room(const QString& roomId, JoinStates states) const
{
Room* room = d->roomMap.value({ roomId, false }, nullptr);
@@ -1400,11 +1416,21 @@ QByteArray Connection::generateTxnId() const
void Connection::setHomeserver(const QUrl& url)
{
- if (homeserver() == url)
- return;
+ if (homeserver() != url) {
+ d->data->setBaseUrl(url);
+ d->loginFlows.clear();
+ emit homeserverChanged(homeserver());
+ }
- d->data->setBaseUrl(url);
- emit homeserverChanged(homeserver());
+ // Whenever a homeserver is updated, retrieve available login flows from it
+ auto* j = callApi<GetLoginFlowsJob>(BackgroundRequest);
+ connect(j, &BaseJob::finished, this, [this, j] {
+ if (j->status().good())
+ d->loginFlows = j->flows();
+ else
+ d->loginFlows.clear();
+ emit loginFlowsChanged();
+ });
}
void Connection::saveRoomState(Room* r) const
diff --git a/lib/connection.h b/lib/connection.h
index b57f0ca8..9d89ca43 100644
--- a/lib/connection.h
+++ b/lib/connection.h
@@ -21,6 +21,7 @@
#include "joinstate.h"
#include "qt_connection_util.h"
+#include "csapi/login.h"
#include "csapi/create_room.h"
#include "events/accountdataevents.h"
@@ -36,6 +37,8 @@ namespace QtOlm {
class Account;
}
+Q_DECLARE_METATYPE(Quotient::GetLoginFlowsJob::LoginFlow)
+
namespace Quotient {
Q_NAMESPACE
@@ -58,6 +61,28 @@ class SendToDeviceJob;
class SendMessageJob;
class LeaveRoomJob;
+// To simplify comparisons of LoginFlows
+
+inline bool operator==(const GetLoginFlowsJob::LoginFlow& lhs,
+ const GetLoginFlowsJob::LoginFlow& rhs)
+{
+ return lhs.type == rhs.type;
+}
+
+inline bool operator!=(const GetLoginFlowsJob::LoginFlow& lhs,
+ const GetLoginFlowsJob::LoginFlow& rhs)
+{
+ return !(lhs == rhs);
+}
+
+/// Predefined login flows
+struct LoginFlows {
+ using LoginFlow = GetLoginFlowsJob::LoginFlow;
+ static inline const LoginFlow Password { "m.login.password" };
+ static inline const LoginFlow SSO { "m.login.sso" };
+ static inline const LoginFlow Token { "m.login.token" };
+};
+
class Connection;
using room_factory_t =
@@ -117,6 +142,9 @@ class Connection : public QObject {
Q_PROPERTY(QUrl homeserver READ homeserver WRITE setHomeserver NOTIFY
homeserverChanged)
Q_PROPERTY(QString domain READ domain NOTIFY homeserverChanged)
+ Q_PROPERTY(QVector<Quotient::GetLoginFlowsJob::LoginFlow> loginFlows READ loginFlows NOTIFY loginFlowsChanged)
+ Q_PROPERTY(bool supportsSso READ supportsSso NOTIFY loginFlowsChanged)
+ Q_PROPERTY(bool supportsPasswordAuth READ supportsPasswordAuth NOTIFY loginFlowsChanged)
Q_PROPERTY(bool cacheState READ cacheState WRITE setCacheState NOTIFY
cacheStateChanged)
Q_PROPERTY(bool lazyLoading READ lazyLoading WRITE setLazyLoading NOTIFY
@@ -281,6 +309,12 @@ public:
QUrl homeserver() const;
/** Get the domain name used for ids/aliases on the server */
QString domain() const;
+ /** Get the list of supported login flows */
+ QVector<GetLoginFlowsJob::LoginFlow> loginFlows() const;
+ /** Check whether the current homeserver supports password auth */
+ bool supportsPasswordAuth() const;
+ /** Check whether the current homeserver supports SSO */
+ bool supportsSso() const;
/** Find a room by its id and a mask of applicable states */
Q_INVOKABLE Quotient::Room*
room(const QString& roomId,
@@ -421,6 +455,18 @@ public:
std::forward<JobArgTs>(jobArgs)...);
}
+ /*! Get a request URL for a job with specified type and arguments
+ *
+ * This calls JobT::makeRequestUrl() prepending the connection's homeserver
+ * to the list of arguments.
+ */
+ template <typename JobT, typename... JobArgTs>
+ QUrl getUrlForApi(JobArgTs&&... jobArgs) const
+ {
+ return JobT::makeRequestUrl(homeserver(),
+ std::forward<JobArgTs>(jobArgs)...);
+ }
+
/** Generate a new transaction id. Transaction id's are unique within
* a single Connection object
*/
@@ -609,6 +655,7 @@ signals:
void resolveError(QString error);
void homeserverChanged(QUrl baseUrl);
+ void loginFlowsChanged();
void capabilitiesLoaded();
void connected();