diff options
Diffstat (limited to 'lib/csapi')
124 files changed, 6816 insertions, 6290 deletions
diff --git a/lib/csapi/account-data.cpp b/lib/csapi/account-data.cpp index 40388673..7d4f1ad7 100644 --- a/lib/csapi/account-data.cpp +++ b/lib/csapi/account-data.cpp @@ -22,8 +22,23 @@ SetAccountDataJob::SetAccountDataJob(const QString& userId, const QString& type, setRequestData(Data(toJson(content))); } +QUrl GetAccountDataJob::makeRequestUrl(QUrl baseUrl, const QString& userId, + const QString& type) +{ + return BaseJob::makeRequestUrl(std::move(baseUrl), + basePath % "/user/" % userId + % "/account_data/" % type); +} + +static const auto GetAccountDataJobName = QStringLiteral("GetAccountDataJob"); + +GetAccountDataJob::GetAccountDataJob(const QString& userId, const QString& type) + : BaseJob(HttpVerb::Get, GetAccountDataJobName, + basePath % "/user/" % userId % "/account_data/" % type) +{} + static const auto SetAccountDataPerRoomJobName = - QStringLiteral("SetAccountDataPerRoomJob"); + QStringLiteral("SetAccountDataPerRoomJob"); SetAccountDataPerRoomJob::SetAccountDataPerRoomJob(const QString& userId, const QString& roomId, @@ -31,7 +46,28 @@ SetAccountDataPerRoomJob::SetAccountDataPerRoomJob(const QString& userId, const QJsonObject& content) : BaseJob(HttpVerb::Put, SetAccountDataPerRoomJobName, basePath % "/user/" % userId % "/rooms/" % roomId - % "/account_data/" % type) + % "/account_data/" % type) { setRequestData(Data(toJson(content))); } + +QUrl GetAccountDataPerRoomJob::makeRequestUrl(QUrl baseUrl, + const QString& userId, + const QString& roomId, + const QString& type) +{ + return BaseJob::makeRequestUrl(std::move(baseUrl), + basePath % "/user/" % userId % "/rooms/" + % roomId % "/account_data/" % type); +} + +static const auto GetAccountDataPerRoomJobName = + QStringLiteral("GetAccountDataPerRoomJob"); + +GetAccountDataPerRoomJob::GetAccountDataPerRoomJob(const QString& userId, + const QString& roomId, + const QString& type) + : BaseJob(HttpVerb::Get, GetAccountDataPerRoomJobName, + basePath % "/user/" % userId % "/rooms/" % roomId + % "/account_data/" % type) +{} diff --git a/lib/csapi/account-data.h b/lib/csapi/account-data.h index 669a4e2c..75bb9ce3 100644 --- a/lib/csapi/account-data.h +++ b/lib/csapi/account-data.h @@ -8,49 +8,118 @@ #include <QtCore/QJsonObject> -namespace QMatrixClient { - // Operations - - /// Set some account_data for the user. - /// - /// Set some account_data for the client. This config is only visible to the - /// user that set the account_data. The config will be synced to clients in - /// the top-level ``account_data``. - class SetAccountDataJob : public BaseJob - { - public: - /*! Set some account_data for the user. - * \param userId - * The id of the user to set account_data for. The access token must - * be authorized to make requests for this user id. \param type The - * event type of the account_data to set. Custom types should be - * namespaced to avoid clashes. - * \param content - * The content of the account_data - */ - explicit SetAccountDataJob(const QString& userId, const QString& type, - const QJsonObject& content = {}); - }; - - /// Set some account_data for the user. - /// - /// Set some account_data for the client on a given room. This config is - /// only visible to the user that set the account_data. The config will be - /// synced to clients in the per-room ``account_data``. - class SetAccountDataPerRoomJob : public BaseJob - { - public: - /*! Set some account_data for the user. - * \param userId - * The id of the user to set account_data for. The access token must - * be authorized to make requests for this user id. \param roomId The id - * of the room to set account_data on. \param type The event type of the - * account_data to set. Custom types should be namespaced to avoid - * clashes. \param content The content of the account_data - */ - explicit SetAccountDataPerRoomJob(const QString& userId, - const QString& roomId, - const QString& type, - const QJsonObject& content = {}); - }; +namespace QMatrixClient +{ + +// Operations + +/// Set some account_data for the user. +/*! + * Set some account_data for the client. This config is only visible to the user + * that set the account_data. The config will be synced to clients in the + * top-level ``account_data``. + */ +class SetAccountDataJob : public BaseJob +{ +public: + /*! Set some account_data for the user. + * \param userId + * The ID of the user to set account_data for. The access token must be + * authorized to make requests for this user ID. + * \param type + * The event type of the account_data to set. Custom types should be + * namespaced to avoid clashes. + * \param content + * The content of the account_data + */ + explicit SetAccountDataJob(const QString& userId, const QString& type, + const QJsonObject& content = {}); +}; + +/// Get some account_data for the user. +/*! + * Get some account_data for the client. This config is only visible to the user + * that set the account_data. + */ +class GetAccountDataJob : public BaseJob +{ +public: + /*! Get some account_data for the user. + * \param userId + * The ID of the user to get account_data for. The access token must be + * authorized to make requests for this user ID. + * \param type + * The event type of the account_data to get. Custom types should be + * namespaced to avoid clashes. + */ + explicit GetAccountDataJob(const QString& userId, const QString& type); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetAccountDataJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& userId, + const QString& type); +}; + +/// Set some account_data for the user. +/*! + * Set some account_data for the client on a given room. This config is only + * visible to the user that set the account_data. The config will be synced to + * clients in the per-room ``account_data``. + */ +class SetAccountDataPerRoomJob : public BaseJob +{ +public: + /*! Set some account_data for the user. + * \param userId + * The ID of the user to set account_data for. The access token must be + * authorized to make requests for this user ID. + * \param roomId + * The ID of the room to set account_data on. + * \param type + * The event type of the account_data to set. Custom types should be + * namespaced to avoid clashes. + * \param content + * The content of the account_data + */ + explicit SetAccountDataPerRoomJob(const QString& userId, + const QString& roomId, const QString& type, + const QJsonObject& content = {}); +}; + +/// Get some account_data for the user. +/*! + * Get some account_data for the client on a given room. This config is only + * visible to the user that set the account_data. + */ +class GetAccountDataPerRoomJob : public BaseJob +{ +public: + /*! Get some account_data for the user. + * \param userId + * The ID of the user to set account_data for. The access token must be + * authorized to make requests for this user ID. + * \param roomId + * The ID of the room to get account_data for. + * \param type + * The event type of the account_data to get. Custom types should be + * namespaced to avoid clashes. + */ + explicit GetAccountDataPerRoomJob(const QString& userId, + const QString& roomId, + const QString& type); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetAccountDataPerRoomJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& userId, + const QString& roomId, const QString& type); +}; + } // namespace QMatrixClient diff --git a/lib/csapi/admin.cpp b/lib/csapi/admin.cpp index 7922ffe3..58334118 100644 --- a/lib/csapi/admin.cpp +++ b/lib/csapi/admin.cpp @@ -12,39 +12,45 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); -namespace QMatrixClient { - // Converters - - template <> struct JsonObjectConverter<GetWhoIsJob::ConnectionInfo> { - static void fillFrom(const QJsonObject& jo, - GetWhoIsJob::ConnectionInfo& result) - { - fromJson(jo.value("ip"_ls), result.ip); - fromJson(jo.value("last_seen"_ls), result.lastSeen); - fromJson(jo.value("user_agent"_ls), result.userAgent); - } - }; - - template <> struct JsonObjectConverter<GetWhoIsJob::SessionInfo> { - static void fillFrom(const QJsonObject& jo, - GetWhoIsJob::SessionInfo& result) - { - fromJson(jo.value("connections"_ls), result.connections); - } - }; - - template <> struct JsonObjectConverter<GetWhoIsJob::DeviceInfo> { - static void fillFrom(const QJsonObject& jo, - GetWhoIsJob::DeviceInfo& result) - { - fromJson(jo.value("sessions"_ls), result.sessions); - } - }; +// Converters +namespace QMatrixClient +{ + +template <> +struct JsonObjectConverter<GetWhoIsJob::ConnectionInfo> +{ + static void fillFrom(const QJsonObject& jo, + GetWhoIsJob::ConnectionInfo& result) + { + fromJson(jo.value("ip"_ls), result.ip); + fromJson(jo.value("last_seen"_ls), result.lastSeen); + fromJson(jo.value("user_agent"_ls), result.userAgent); + } +}; + +template <> +struct JsonObjectConverter<GetWhoIsJob::SessionInfo> +{ + static void fillFrom(const QJsonObject& jo, GetWhoIsJob::SessionInfo& result) + { + fromJson(jo.value("connections"_ls), result.connections); + } +}; + +template <> +struct JsonObjectConverter<GetWhoIsJob::DeviceInfo> +{ + static void fillFrom(const QJsonObject& jo, GetWhoIsJob::DeviceInfo& result) + { + fromJson(jo.value("sessions"_ls), result.sessions); + } +}; + } // namespace QMatrixClient class GetWhoIsJob::Private { - public: +public: QString userId; QHash<QString, DeviceInfo> devices; }; @@ -59,10 +65,9 @@ static const auto GetWhoIsJobName = QStringLiteral("GetWhoIsJob"); GetWhoIsJob::GetWhoIsJob(const QString& userId) : BaseJob(HttpVerb::Get, GetWhoIsJobName, - basePath % "/admin/whois/" % userId), - d(new Private) -{ -} + basePath % "/admin/whois/" % userId) + , d(new Private) +{} GetWhoIsJob::~GetWhoIsJob() = default; @@ -78,5 +83,6 @@ BaseJob::Status GetWhoIsJob::parseJson(const QJsonDocument& data) auto json = data.object(); fromJson(json.value("user_id"_ls), d->userId); fromJson(json.value("devices"_ls), d->devices); + return Success; } diff --git a/lib/csapi/admin.h b/lib/csapi/admin.h index 3c21e2cb..bc27c025 100644 --- a/lib/csapi/admin.h +++ b/lib/csapi/admin.h @@ -4,92 +4,94 @@ #pragma once +#include "converters.h" + #include "jobs/basejob.h" -#include "converters.h" #include <QtCore/QHash> #include <QtCore/QVector> -namespace QMatrixClient { - // Operations - - /// Gets information about a particular user. - /// - /// Gets information about a particular user. - /// - /// This API may be restricted to only be called by the user being looked - /// up, or by a server admin. Server-local administrator privileges are not - /// specified in this document. - class GetWhoIsJob : public BaseJob +namespace QMatrixClient +{ + +// Operations + +/// Gets information about a particular user. +/*! + * Gets information about a particular user. + * + * This API may be restricted to only be called by the user being looked + * up, or by a server admin. Server-local administrator privileges are not + * specified in this document. + */ +class GetWhoIsJob : public BaseJob +{ +public: + // Inner data structures + + /// Gets information about a particular user.This API may be restricted to + /// only be called by the user being lookedup, or by a server admin. + /// Server-local administrator privileges are notspecified in this document. + struct ConnectionInfo { - public: - // Inner data structures - - /// Gets information about a particular user. - /// - /// This API may be restricted to only be called by the user being - /// looked up, or by a server admin. Server-local administrator - /// privileges are not specified in this document. - struct ConnectionInfo { - /// Most recently seen IP address of the session. - QString ip; - /// Unix timestamp that the session was last active. - Omittable<qint64> lastSeen; - /// User agent string last seen in the session. - QString userAgent; - }; - - /// Gets information about a particular user. - /// - /// This API may be restricted to only be called by the user being - /// looked up, or by a server admin. Server-local administrator - /// privileges are not specified in this document. - struct SessionInfo { - /// Information particular connections in the session. - QVector<ConnectionInfo> connections; - }; - - /// Gets information about a particular user. - /// - /// This API may be restricted to only be called by the user being - /// looked up, or by a server admin. Server-local administrator - /// privileges are not specified in this document. - struct DeviceInfo { - /// A user's sessions (i.e. what they did with an access token from - /// one login). - QVector<SessionInfo> sessions; - }; - - // Construction/destruction - - /*! Gets information about a particular user. - * \param userId - * The user to look up. - */ - explicit GetWhoIsJob(const QString& userId); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetWhoIsJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& userId); - - ~GetWhoIsJob() override; - - // Result properties - - /// The Matrix user ID of the user. - const QString& userId() const; - /// Each key is an identitfier for one of the user's devices. - const QHash<QString, DeviceInfo>& devices() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; + /// Most recently seen IP address of the session. + QString ip; + /// Unix timestamp that the session was last active. + Omittable<qint64> lastSeen; + /// User agent string last seen in the session. + QString userAgent; }; + + /// Gets information about a particular user.This API may be restricted to + /// only be called by the user being lookedup, or by a server admin. + /// Server-local administrator privileges are notspecified in this document. + struct SessionInfo + { + /// Information particular connections in the session. + QVector<ConnectionInfo> connections; + }; + + /// Gets information about a particular user.This API may be restricted to + /// only be called by the user being lookedup, or by a server admin. + /// Server-local administrator privileges are notspecified in this document. + struct DeviceInfo + { + /// A user's sessions (i.e. what they did with an access token from one + /// login). + QVector<SessionInfo> sessions; + }; + + // Construction/destruction + + /*! Gets information about a particular user. + * \param userId + * The user to look up. + */ + explicit GetWhoIsJob(const QString& userId); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetWhoIsJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& userId); + + ~GetWhoIsJob() override; + + // Result properties + + /// The Matrix user ID of the user. + const QString& userId() const; + /// Each key is an identitfier for one of the user's devices. + const QHash<QString, DeviceInfo>& devices() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + } // namespace QMatrixClient diff --git a/lib/csapi/administrative_contact.cpp b/lib/csapi/administrative_contact.cpp index f64f2723..067fb68a 100644 --- a/lib/csapi/administrative_contact.cpp +++ b/lib/csapi/administrative_contact.cpp @@ -12,25 +12,28 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); -namespace QMatrixClient { - // Converters - - template <> - struct JsonObjectConverter<GetAccount3PIDsJob::ThirdPartyIdentifier> { - static void fillFrom(const QJsonObject& jo, - GetAccount3PIDsJob::ThirdPartyIdentifier& result) - { - fromJson(jo.value("medium"_ls), result.medium); - fromJson(jo.value("address"_ls), result.address); - fromJson(jo.value("validated_at"_ls), result.validatedAt); - fromJson(jo.value("added_at"_ls), result.addedAt); - } - }; +// Converters +namespace QMatrixClient +{ + +template <> +struct JsonObjectConverter<GetAccount3PIDsJob::ThirdPartyIdentifier> +{ + static void fillFrom(const QJsonObject& jo, + GetAccount3PIDsJob::ThirdPartyIdentifier& result) + { + fromJson(jo.value("medium"_ls), result.medium); + fromJson(jo.value("address"_ls), result.address); + fromJson(jo.value("validated_at"_ls), result.validatedAt); + fromJson(jo.value("added_at"_ls), result.addedAt); + } +}; + } // namespace QMatrixClient class GetAccount3PIDsJob::Private { - public: +public: QVector<ThirdPartyIdentifier> threepids; }; @@ -43,11 +46,9 @@ QUrl GetAccount3PIDsJob::makeRequestUrl(QUrl baseUrl) static const auto GetAccount3PIDsJobName = QStringLiteral("GetAccount3PIDsJob"); GetAccount3PIDsJob::GetAccount3PIDsJob() - : BaseJob(HttpVerb::Get, GetAccount3PIDsJobName, - basePath % "/account/3pid"), - d(new Private) -{ -} + : BaseJob(HttpVerb::Get, GetAccount3PIDsJobName, basePath % "/account/3pid") + , d(new Private) +{} GetAccount3PIDsJob::~GetAccount3PIDsJob() = default; @@ -61,21 +62,26 @@ BaseJob::Status GetAccount3PIDsJob::parseJson(const QJsonDocument& data) { auto json = data.object(); fromJson(json.value("threepids"_ls), d->threepids); + return Success; } -namespace QMatrixClient { - // Converters - - template <> struct JsonObjectConverter<Post3PIDsJob::ThreePidCredentials> { - static void dumpTo(QJsonObject& jo, - const Post3PIDsJob::ThreePidCredentials& pod) - { - addParam<>(jo, QStringLiteral("client_secret"), pod.clientSecret); - addParam<>(jo, QStringLiteral("id_server"), pod.idServer); - addParam<>(jo, QStringLiteral("sid"), pod.sid); - } - }; +// Converters +namespace QMatrixClient +{ + +template <> +struct JsonObjectConverter<Post3PIDsJob::ThreePidCredentials> +{ + static void dumpTo(QJsonObject& jo, + const Post3PIDsJob::ThreePidCredentials& pod) + { + addParam<>(jo, QStringLiteral("client_secret"), pod.clientSecret); + addParam<>(jo, QStringLiteral("id_server"), pod.idServer); + addParam<>(jo, QStringLiteral("sid"), pod.sid); + } +}; + } // namespace QMatrixClient static const auto Post3PIDsJobName = QStringLiteral("Post3PIDsJob"); @@ -91,7 +97,7 @@ Post3PIDsJob::Post3PIDsJob(const ThreePidCredentials& threePidCreds, } static const auto Delete3pidFromAccountJobName = - QStringLiteral("Delete3pidFromAccountJob"); + QStringLiteral("Delete3pidFromAccountJob"); Delete3pidFromAccountJob::Delete3pidFromAccountJob(const QString& medium, const QString& address) @@ -106,19 +112,19 @@ Delete3pidFromAccountJob::Delete3pidFromAccountJob(const QString& medium, class RequestTokenTo3PIDEmailJob::Private { - public: +public: Sid data; }; static const auto RequestTokenTo3PIDEmailJobName = - QStringLiteral("RequestTokenTo3PIDEmailJob"); + QStringLiteral("RequestTokenTo3PIDEmailJob"); RequestTokenTo3PIDEmailJob::RequestTokenTo3PIDEmailJob( - const QString& clientSecret, const QString& email, int sendAttempt, - const QString& idServer, const QString& nextLink) + const QString& clientSecret, const QString& email, int sendAttempt, + const QString& idServer, const QString& nextLink) : BaseJob(HttpVerb::Post, RequestTokenTo3PIDEmailJobName, - basePath % "/account/3pid/email/requestToken", false), - d(new Private) + basePath % "/account/3pid/email/requestToken", false) + , d(new Private) { QJsonObject _data; addParam<>(_data, QStringLiteral("client_secret"), clientSecret); @@ -141,20 +147,20 @@ BaseJob::Status RequestTokenTo3PIDEmailJob::parseJson(const QJsonDocument& data) class RequestTokenTo3PIDMSISDNJob::Private { - public: +public: Sid data; }; static const auto RequestTokenTo3PIDMSISDNJobName = - QStringLiteral("RequestTokenTo3PIDMSISDNJob"); + QStringLiteral("RequestTokenTo3PIDMSISDNJob"); RequestTokenTo3PIDMSISDNJob::RequestTokenTo3PIDMSISDNJob( - const QString& clientSecret, const QString& country, - const QString& phoneNumber, int sendAttempt, const QString& idServer, - const QString& nextLink) + const QString& clientSecret, const QString& country, + const QString& phoneNumber, int sendAttempt, const QString& idServer, + const QString& nextLink) : BaseJob(HttpVerb::Post, RequestTokenTo3PIDMSISDNJobName, - basePath % "/account/3pid/msisdn/requestToken", false), - d(new Private) + basePath % "/account/3pid/msisdn/requestToken", false) + , d(new Private) { QJsonObject _data; addParam<>(_data, QStringLiteral("client_secret"), clientSecret); @@ -170,8 +176,7 @@ RequestTokenTo3PIDMSISDNJob::~RequestTokenTo3PIDMSISDNJob() = default; const Sid& RequestTokenTo3PIDMSISDNJob::data() const { return d->data; } -BaseJob::Status -RequestTokenTo3PIDMSISDNJob::parseJson(const QJsonDocument& data) +BaseJob::Status RequestTokenTo3PIDMSISDNJob::parseJson(const QJsonDocument& data) { fromJson(data, d->data); return Success; diff --git a/lib/csapi/administrative_contact.h b/lib/csapi/administrative_contact.h index d99fde42..7f2d0cdc 100644 --- a/lib/csapi/administrative_contact.h +++ b/lib/csapi/administrative_contact.h @@ -4,17 +4,71 @@ #pragma once -#include "jobs/basejob.h" - #include "converters.h" + #include "csapi/../identity/definitions/sid.h" + +#include "jobs/basejob.h" + #include <QtCore/QVector> -namespace QMatrixClient { - // Operations +namespace QMatrixClient +{ + +// Operations + +/// Gets a list of a user's third party identifiers. +/*! + * Gets a list of the third party identifiers that the homeserver has + * associated with the user's account. + * + * This is *not* the same as the list of third party identifiers bound to + * the user's Matrix ID in identity servers. + * + * Identifiers in this list may be used by the homeserver as, for example, + * identifiers that it will accept to reset the user's account password. + */ +class GetAccount3PIDsJob : public BaseJob +{ +public: + // Inner data structures + + /// Gets a list of the third party identifiers that the homeserver + /// hasassociated with the user's account.This is *not* the same as the list + /// of third party identifiers bound tothe user's Matrix ID in identity + /// servers.Identifiers in this list may be used by the homeserver as, for + /// example,identifiers that it will accept to reset the user's account + /// password. + struct ThirdPartyIdentifier + { + /// The medium of the third party identifier. + QString medium; + /// The third party identifier address. + QString address; + /// The timestamp, in milliseconds, when the identifier wasvalidated by + /// the identity server. + qint64 validatedAt; + /// The timestamp, in milliseconds, when the homeserver associated the + /// third party identifier with the user. + qint64 addedAt; + }; + + // Construction/destruction + + explicit GetAccount3PIDsJob(); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetAccount3PIDsJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl); + + ~GetAccount3PIDsJob() override; + + // Result properties - /// Gets a list of a user's third party identifiers. - /// /// Gets a list of the third party identifiers that the homeserver has /// associated with the user's account. /// @@ -23,227 +77,183 @@ namespace QMatrixClient { /// /// Identifiers in this list may be used by the homeserver as, for example, /// identifiers that it will accept to reset the user's account password. - class GetAccount3PIDsJob : public BaseJob - { - public: - // Inner data structures - - /// Gets a list of the third party identifiers that the homeserver has - /// associated with the user's account. - /// - /// This is *not* the same as the list of third party identifiers bound - /// to the user's Matrix ID in identity servers. - /// - /// Identifiers in this list may be used by the homeserver as, for - /// example, identifiers that it will accept to reset the user's account - /// password. - struct ThirdPartyIdentifier { - /// The medium of the third party identifier. - QString medium; - /// The third party identifier address. - QString address; - /// The timestamp, in milliseconds, when the identifier was - /// validated by the identity server. - qint64 validatedAt; - /// The timestamp, in milliseconds, when the homeserver associated - /// the third party identifier with the user. - qint64 addedAt; - }; - - // Construction/destruction - - explicit GetAccount3PIDsJob(); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetAccount3PIDsJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl); - - ~GetAccount3PIDsJob() override; - - // Result properties - - /// Gets a list of the third party identifiers that the homeserver has - /// associated with the user's account. - /// - /// This is *not* the same as the list of third party identifiers bound - /// to the user's Matrix ID in identity servers. - /// - /// Identifiers in this list may be used by the homeserver as, for - /// example, identifiers that it will accept to reset the user's account - /// password. - const QVector<ThirdPartyIdentifier>& threepids() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; + const QVector<ThirdPartyIdentifier>& threepids() const; - /// Adds contact information to the user's account. - /// - /// Adds contact information to the user's account. - class Post3PIDsJob : public BaseJob - { - public: - // Inner data structures - - /// The third party credentials to associate with the account. - struct ThreePidCredentials { - /// The client secret used in the session with the identity server. - QString clientSecret; - /// The identity server to use. - QString idServer; - /// The session identifier given by the identity server. - QString sid; - }; - - // Construction/destruction - - /*! Adds contact information to the user's account. - * \param threePidCreds - * The third party credentials to associate with the account. - * \param bind - * Whether the homeserver should also bind this third party - * identifier to the account's Matrix ID with the passed identity - * server. Default: ``false``. - */ - explicit Post3PIDsJob(const ThreePidCredentials& threePidCreds, - Omittable<bool> bind = none); - }; +protected: + Status parseJson(const QJsonDocument& data) override; - /// Deletes a third party identifier from the user's account - /// - /// Removes a third party identifier from the user's account. This might not - /// cause an unbind of the identifier from the identity server. - class Delete3pidFromAccountJob : public BaseJob - { - public: - /*! Deletes a third party identifier from the user's account - * \param medium - * The medium of the third party identifier being removed. - * \param address - * The third party address being removed. - */ - explicit Delete3pidFromAccountJob(const QString& medium, - const QString& address); - }; +private: + class Private; + QScopedPointer<Private> d; +}; - /// Begins the validation process for an email address for association with - /// the user's account. - /// - /// Proxies the Identity Service API ``validate/email/requestToken``, but - /// first checks that the given email address is **not** already associated - /// with an account on this homeserver. This API should be used to request - /// validation tokens when adding an email address to an account. This API's - /// parameters and response are identical to that of the - /// |/register/email/requestToken|_ endpoint. - class RequestTokenTo3PIDEmailJob : public BaseJob - { - public: - /*! Begins the validation process for an email address for association with the user's account. - * \param clientSecret - * A unique string generated by the client, and used to identify the - * validation attempt. It must be a string consisting of the - * characters - * ``[0-9a-zA-Z.=_-]``. Its length must not exceed 255 characters and - * it must not be empty. \param email The email address to validate. - * \param sendAttempt - * The server will only send an email if the ``send_attempt`` - * is a number greater than the most recent one which it has seen, - * scoped to that ``email`` + ``client_secret`` pair. This is to - * avoid repeatedly sending the same email in the case of request - * retries between the POSTing user and the identity server. - * The client should increment this value if they desire a new - * email (e.g. a reminder) to be sent. - * \param idServer - * The hostname of the identity server to communicate with. May - * optionally include a port. - * \param nextLink - * Optional. When the validation is completed, the identity - * server will redirect the user to this URL. - */ - explicit RequestTokenTo3PIDEmailJob(const QString& clientSecret, - const QString& email, - int sendAttempt, - const QString& idServer, - const QString& nextLink = {}); - ~RequestTokenTo3PIDEmailJob() override; - - // Result properties - - /// An email was sent to the given address. - const Sid& data() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; +/// Adds contact information to the user's account. +/*! + * Adds contact information to the user's account. + */ +class Post3PIDsJob : public BaseJob +{ +public: + // Inner data structures - /// Begins the validation process for a phone number for association with - /// the user's account. - /// - /// Proxies the Identity Service API ``validate/msisdn/requestToken``, but - /// first checks that the given phone number is **not** already associated - /// with an account on this homeserver. This API should be used to request - /// validation tokens when adding a phone number to an account. This API's - /// parameters and response are identical to that of the - /// |/register/msisdn/requestToken|_ endpoint. - class RequestTokenTo3PIDMSISDNJob : public BaseJob + /// The third party credentials to associate with the account. + struct ThreePidCredentials { - public: - /*! Begins the validation process for a phone number for association with the user's account. - * \param clientSecret - * A unique string generated by the client, and used to identify the - * validation attempt. It must be a string consisting of the - * characters - * ``[0-9a-zA-Z.=_-]``. Its length must not exceed 255 characters and - * it must not be empty. \param country The two-letter uppercase ISO - * country code that the number in - * ``phone_number`` should be parsed as if it were dialled from. - * \param phoneNumber - * The phone number to validate. - * \param sendAttempt - * The server will only send an SMS if the ``send_attempt`` is a - * number greater than the most recent one which it has seen, - * scoped to that ``country`` + ``phone_number`` + ``client_secret`` - * triple. This is to avoid repeatedly sending the same SMS in - * the case of request retries between the POSTing user and the - * identity server. The client should increment this value if - * they desire a new SMS (e.g. a reminder) to be sent. - * \param idServer - * The hostname of the identity server to communicate with. May - * optionally include a port. - * \param nextLink - * Optional. When the validation is completed, the identity - * server will redirect the user to this URL. - */ - explicit RequestTokenTo3PIDMSISDNJob(const QString& clientSecret, - const QString& country, - const QString& phoneNumber, - int sendAttempt, - const QString& idServer, - const QString& nextLink = {}); - ~RequestTokenTo3PIDMSISDNJob() override; - - // Result properties - - /// An SMS message was sent to the given phone number. - const Sid& data() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; + /// The client secret used in the session with the identity server. + QString clientSecret; + /// The identity server to use. + QString idServer; + /// The session identifier given by the identity server. + QString sid; }; + + // Construction/destruction + + /*! Adds contact information to the user's account. + * \param threePidCreds + * The third party credentials to associate with the account. + * \param bind + * Whether the homeserver should also bind this third party + * identifier to the account's Matrix ID with the passed identity + * server. Default: ``false``. + */ + explicit Post3PIDsJob(const ThreePidCredentials& threePidCreds, + Omittable<bool> bind = none); +}; + +/// Deletes a third party identifier from the user's account +/*! + * Removes a third party identifier from the user's account. This might not + * cause an unbind of the identifier from the identity server. + */ +class Delete3pidFromAccountJob : public BaseJob +{ +public: + /*! Deletes a third party identifier from the user's account + * \param medium + * The medium of the third party identifier being removed. + * \param address + * The third party address being removed. + */ + explicit Delete3pidFromAccountJob(const QString& medium, + const QString& address); +}; + +/// Begins the validation process for an email address for association with the +/// user's account. +/*! + * Proxies the Identity Service API ``validate/email/requestToken``, but + * first checks that the given email address is **not** already associated + * with an account on this homeserver. This API should be used to request + * validation tokens when adding an email address to an account. This API's + * parameters and response are identical to that of the + * |/register/email/requestToken|_ endpoint. + */ +class RequestTokenTo3PIDEmailJob : public BaseJob +{ +public: + /*! Begins the validation process for an email address for association with + * the user's account. \param clientSecret A unique string generated by the + * client, and used to identify the validation attempt. It must be a string + * consisting of the characters + * ``[0-9a-zA-Z.=_-]``. Its length must not exceed 255 characters and it + * must not be empty. + * \param email + * The email address to validate. + * \param sendAttempt + * The server will only send an email if the ``send_attempt`` + * is a number greater than the most recent one which it has seen, + * scoped to that ``email`` + ``client_secret`` pair. This is to + * avoid repeatedly sending the same email in the case of request + * retries between the POSTing user and the identity server. + * The client should increment this value if they desire a new + * email (e.g. a reminder) to be sent. + * \param idServer + * The hostname of the identity server to communicate with. May + * optionally include a port. + * \param nextLink + * Optional. When the validation is completed, the identity + * server will redirect the user to this URL. + */ + explicit RequestTokenTo3PIDEmailJob(const QString& clientSecret, + const QString& email, int sendAttempt, + const QString& idServer, + const QString& nextLink = {}); + + ~RequestTokenTo3PIDEmailJob() override; + + // Result properties + + /// An email was sent to the given address. + const Sid& data() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Begins the validation process for a phone number for association with the +/// user's account. +/*! + * Proxies the Identity Service API ``validate/msisdn/requestToken``, but + * first checks that the given phone number is **not** already associated + * with an account on this homeserver. This API should be used to request + * validation tokens when adding a phone number to an account. This API's + * parameters and response are identical to that of the + * |/register/msisdn/requestToken|_ endpoint. + */ +class RequestTokenTo3PIDMSISDNJob : public BaseJob +{ +public: + /*! Begins the validation process for a phone number for association with + * the user's account. \param clientSecret A unique string generated by the + * client, and used to identify the validation attempt. It must be a string + * consisting of the characters + * ``[0-9a-zA-Z.=_-]``. Its length must not exceed 255 characters and it + * must not be empty. + * \param country + * The two-letter uppercase ISO country code that the number in + * ``phone_number`` should be parsed as if it were dialled from. + * \param phoneNumber + * The phone number to validate. + * \param sendAttempt + * The server will only send an SMS if the ``send_attempt`` is a + * number greater than the most recent one which it has seen, + * scoped to that ``country`` + ``phone_number`` + ``client_secret`` + * triple. This is to avoid repeatedly sending the same SMS in + * the case of request retries between the POSTing user and the + * identity server. The client should increment this value if + * they desire a new SMS (e.g. a reminder) to be sent. + * \param idServer + * The hostname of the identity server to communicate with. May + * optionally include a port. + * \param nextLink + * Optional. When the validation is completed, the identity + * server will redirect the user to this URL. + */ + explicit RequestTokenTo3PIDMSISDNJob(const QString& clientSecret, + const QString& country, + const QString& phoneNumber, + int sendAttempt, + const QString& idServer, + const QString& nextLink = {}); + + ~RequestTokenTo3PIDMSISDNJob() override; + + // Result properties + + /// An SMS message was sent to the given phone number. + const Sid& data() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + } // namespace QMatrixClient diff --git a/lib/csapi/appservice_room_directory.cpp b/lib/csapi/appservice_room_directory.cpp index cf76874c..74e037cd 100644 --- a/lib/csapi/appservice_room_directory.cpp +++ b/lib/csapi/appservice_room_directory.cpp @@ -13,15 +13,12 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); static const auto UpdateAppserviceRoomDirectoryVsibilityJobName = - QStringLiteral("UpdateAppserviceRoomDirectoryVsibilityJob"); + QStringLiteral("UpdateAppserviceRoomDirectoryVsibilityJob"); -UpdateAppserviceRoomDirectoryVsibilityJob:: - UpdateAppserviceRoomDirectoryVsibilityJob(const QString& networkId, - const QString& roomId, - const QString& visibility) +UpdateAppserviceRoomDirectoryVsibilityJob::UpdateAppserviceRoomDirectoryVsibilityJob( + const QString& networkId, const QString& roomId, const QString& visibility) : BaseJob(HttpVerb::Put, UpdateAppserviceRoomDirectoryVsibilityJobName, - basePath % "/directory/list/appservice/" % networkId % "/" - % roomId) + basePath % "/directory/list/appservice/" % networkId % "/" % roomId) { QJsonObject _data; addParam<>(_data, QStringLiteral("visibility"), visibility); diff --git a/lib/csapi/appservice_room_directory.h b/lib/csapi/appservice_room_directory.h index 2ee680c9..d1c3f89f 100644 --- a/lib/csapi/appservice_room_directory.h +++ b/lib/csapi/appservice_room_directory.h @@ -6,37 +6,40 @@ #include "jobs/basejob.h" -namespace QMatrixClient { - // Operations +namespace QMatrixClient +{ + +// Operations + +/// Updates a room's visibility in the application service's room directory. +/*! + * Updates the visibility of a given room on the application service's room + * directory. + * + * This API is similar to the room directory visibility API used by clients + * to update the homeserver's more general room directory. + * + * This API requires the use of an application service access token + * (``as_token``) instead of a typical client's access_token. This API cannot be + * invoked by users who are not identified as application services. + */ +class UpdateAppserviceRoomDirectoryVsibilityJob : public BaseJob +{ +public: + /*! Updates a room's visibility in the application service's room directory. + * \param networkId + * The protocol (network) ID to update the room list for. This would + * have been provided by the application service as being listed as + * a supported protocol. + * \param roomId + * The room ID to add to the directory. + * \param visibility + * Whether the room should be visible (public) in the directory + * or not (private). + */ + explicit UpdateAppserviceRoomDirectoryVsibilityJob(const QString& networkId, + const QString& roomId, + const QString& visibility); +}; - /// Updates a room's visibility in the application service's room directory. - /// - /// Updates the visibility of a given room on the application service's room - /// directory. - /// - /// This API is similar to the room directory visibility API used by clients - /// to update the homeserver's more general room directory. - /// - /// This API requires the use of an application service access token - /// (``as_token``) instead of a typical client's access_token. This API - /// cannot be invoked by users who are not identified as application - /// services. - class UpdateAppserviceRoomDirectoryVsibilityJob : public BaseJob - { - public: - /*! Updates a room's visibility in the application service's room directory. - * \param networkId - * The protocol (network) ID to update the room list for. This would - * have been provided by the application service as being listed as - * a supported protocol. - * \param roomId - * The room ID to add to the directory. - * \param visibility - * Whether the room should be visible (public) in the directory - * or not (private). - */ - explicit UpdateAppserviceRoomDirectoryVsibilityJob( - const QString& networkId, const QString& roomId, - const QString& visibility); - }; } // namespace QMatrixClient diff --git a/lib/csapi/banning.cpp b/lib/csapi/banning.cpp index 201126c3..a46e78f1 100644 --- a/lib/csapi/banning.cpp +++ b/lib/csapi/banning.cpp @@ -16,8 +16,7 @@ static const auto BanJobName = QStringLiteral("BanJob"); BanJob::BanJob(const QString& roomId, const QString& userId, const QString& reason) - : BaseJob(HttpVerb::Post, BanJobName, - basePath % "/rooms/" % roomId % "/ban") + : BaseJob(HttpVerb::Post, BanJobName, basePath % "/rooms/" % roomId % "/ban") { QJsonObject _data; addParam<>(_data, QStringLiteral("user_id"), userId); diff --git a/lib/csapi/banning.h b/lib/csapi/banning.h index e1886f0e..0aa5785b 100644 --- a/lib/csapi/banning.h +++ b/lib/csapi/banning.h @@ -6,51 +6,56 @@ #include "jobs/basejob.h" -namespace QMatrixClient { - // Operations +namespace QMatrixClient +{ - /// Ban a user in the room. - /// - /// Ban a user in the room. If the user is currently in the room, also kick - /// them. - /// - /// When a user is banned from a room, they may not join it or be invited to - /// it until they are unbanned. - /// - /// The caller must have the required power level in order to perform this - /// operation. - class BanJob : public BaseJob - { - public: - /*! Ban a user in the room. - * \param roomId - * The room identifier (not alias) from which the user should be - * banned. \param userId The fully qualified user ID of the user being - * banned. \param reason The reason the user has been banned. This will - * be supplied as the ``reason`` on the target's updated - * `m.room.member`_ event. - */ - explicit BanJob(const QString& roomId, const QString& userId, - const QString& reason = {}); - }; +// Operations + +/// Ban a user in the room. +/*! + * Ban a user in the room. If the user is currently in the room, also kick them. + * + * When a user is banned from a room, they may not join it or be invited to it + * until they are unbanned. + * + * The caller must have the required power level in order to perform this + * operation. + */ +class BanJob : public BaseJob +{ +public: + /*! Ban a user in the room. + * \param roomId + * The room identifier (not alias) from which the user should be banned. + * \param userId + * The fully qualified user ID of the user being banned. + * \param reason + * The reason the user has been banned. This will be supplied as the + * ``reason`` on the target's updated `m.room.member`_ event. + */ + explicit BanJob(const QString& roomId, const QString& userId, + const QString& reason = {}); +}; + +/// Unban a user from the room. +/*! + * Unban a user from the room. This allows them to be invited to the room, + * and join if they would otherwise be allowed to join according to its join + * rules. + * + * The caller must have the required power level in order to perform this + * operation. + */ +class UnbanJob : public BaseJob +{ +public: + /*! Unban a user from the room. + * \param roomId + * The room identifier (not alias) from which the user should be unbanned. + * \param userId + * The fully qualified user ID of the user being unbanned. + */ + explicit UnbanJob(const QString& roomId, const QString& userId); +}; - /// Unban a user from the room. - /// - /// Unban a user from the room. This allows them to be invited to the room, - /// and join if they would otherwise be allowed to join according to its - /// join rules. - /// - /// The caller must have the required power level in order to perform this - /// operation. - class UnbanJob : public BaseJob - { - public: - /*! Unban a user from the room. - * \param roomId - * The room identifier (not alias) from which the user should be - * unbanned. \param userId The fully qualified user ID of the user being - * unbanned. - */ - explicit UnbanJob(const QString& roomId, const QString& userId); - }; } // namespace QMatrixClient diff --git a/lib/csapi/capabilities.cpp b/lib/csapi/capabilities.cpp index 0fb9fbae..9a054fe9 100644 --- a/lib/csapi/capabilities.cpp +++ b/lib/csapi/capabilities.cpp @@ -12,43 +12,48 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); -namespace QMatrixClient { - // Converters - - template <> - struct JsonObjectConverter<GetCapabilitiesJob::ChangePasswordCapability> { - static void - fillFrom(const QJsonObject& jo, - GetCapabilitiesJob::ChangePasswordCapability& result) - { - fromJson(jo.value("enabled"_ls), result.enabled); - } - }; - - template <> - struct JsonObjectConverter<GetCapabilitiesJob::RoomVersionsCapability> { - static void fillFrom(const QJsonObject& jo, - GetCapabilitiesJob::RoomVersionsCapability& result) - { - fromJson(jo.value("default"_ls), result.defaultVersion); - fromJson(jo.value("available"_ls), result.available); - } - }; - - template <> struct JsonObjectConverter<GetCapabilitiesJob::Capabilities> { - static void fillFrom(QJsonObject jo, - GetCapabilitiesJob::Capabilities& result) - { - fromJson(jo.take("m.change_password"_ls), result.changePassword); - fromJson(jo.take("m.room_versions"_ls), result.roomVersions); - fromJson(jo, result.additionalProperties); - } - }; +// Converters +namespace QMatrixClient +{ + +template <> +struct JsonObjectConverter<GetCapabilitiesJob::ChangePasswordCapability> +{ + static void fillFrom(const QJsonObject& jo, + GetCapabilitiesJob::ChangePasswordCapability& result) + { + fromJson(jo.value("enabled"_ls), result.enabled); + } +}; + +template <> +struct JsonObjectConverter<GetCapabilitiesJob::RoomVersionsCapability> +{ + static void fillFrom(const QJsonObject& jo, + GetCapabilitiesJob::RoomVersionsCapability& result) + { + fromJson(jo.value("default"_ls), result.defaultVersion); + fromJson(jo.value("available"_ls), result.available); + } +}; + +template <> +struct JsonObjectConverter<GetCapabilitiesJob::Capabilities> +{ + static void fillFrom(QJsonObject jo, + GetCapabilitiesJob::Capabilities& result) + { + fromJson(jo.take("m.change_password"_ls), result.changePassword); + fromJson(jo.take("m.room_versions"_ls), result.roomVersions); + fromJson(jo, result.additionalProperties); + } +}; + } // namespace QMatrixClient class GetCapabilitiesJob::Private { - public: +public: Capabilities capabilities; }; @@ -61,11 +66,9 @@ QUrl GetCapabilitiesJob::makeRequestUrl(QUrl baseUrl) static const auto GetCapabilitiesJobName = QStringLiteral("GetCapabilitiesJob"); GetCapabilitiesJob::GetCapabilitiesJob() - : BaseJob(HttpVerb::Get, GetCapabilitiesJobName, - basePath % "/capabilities"), - d(new Private) -{ -} + : BaseJob(HttpVerb::Get, GetCapabilitiesJobName, basePath % "/capabilities") + , d(new Private) +{} GetCapabilitiesJob::~GetCapabilitiesJob() = default; @@ -78,8 +81,9 @@ BaseJob::Status GetCapabilitiesJob::parseJson(const QJsonDocument& data) { auto json = data.object(); if (!json.contains("capabilities"_ls)) - return { JsonParseError, + return { IncorrectResponse, "The key 'capabilities' not found in the response" }; fromJson(json.value("capabilities"_ls), d->capabilities); + return Success; } diff --git a/lib/csapi/capabilities.h b/lib/csapi/capabilities.h index 6282c2fd..f6e7ad06 100644 --- a/lib/csapi/capabilities.h +++ b/lib/csapi/capabilities.h @@ -4,75 +4,84 @@ #pragma once +#include "converters.h" + #include "jobs/basejob.h" -#include "converters.h" #include <QtCore/QHash> #include <QtCore/QJsonObject> -namespace QMatrixClient { - // Operations +namespace QMatrixClient +{ + +// Operations + +/// Gets information about the server's capabilities. +/*! + * Gets information about the server's supported feature set + * and other relevant capabilities. + */ +class GetCapabilitiesJob : public BaseJob +{ +public: + // Inner data structures - /// Gets information about the server's capabilities. - /// - /// Gets information about the server's supported feature set - /// and other relevant capabilities. - class GetCapabilitiesJob : public BaseJob + /// Capability to indicate if the user can change their password. + struct ChangePasswordCapability { - public: - // Inner data structures + /// True if the user can change their password, false otherwise. + bool enabled; + }; - /// Capability to indicate if the user can change their password. - struct ChangePasswordCapability { - /// True if the user can change their password, false otherwise. - bool enabled; - }; + /// The room versions the server supports. + struct RoomVersionsCapability + { + /// The default room version the server is using for new rooms. + QString defaultVersion; + /// A detailed description of the room versions the server supports. + QHash<QString, QString> available; + }; + /// The custom capabilities the server supports, using theJava package + /// naming convention. + struct Capabilities + { + /// Capability to indicate if the user can change their password. + Omittable<ChangePasswordCapability> changePassword; /// The room versions the server supports. - struct RoomVersionsCapability { - /// The default room version the server is using for new rooms. - QString defaultVersion; - /// A detailed description of the room versions the server supports. - QHash<QString, QString> available; - }; - - /// Gets information about the server's supported feature set - /// and other relevant capabilities. - struct Capabilities { - /// Capability to indicate if the user can change their password. - Omittable<ChangePasswordCapability> changePassword; - /// The room versions the server supports. - Omittable<RoomVersionsCapability> roomVersions; - /// The custom capabilities the server supports, using the - /// Java package naming convention. - QHash<QString, QJsonObject> additionalProperties; - }; - - // Construction/destruction - - explicit GetCapabilitiesJob(); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetCapabilitiesJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl); - - ~GetCapabilitiesJob() override; - - // Result properties - - /// Gets information about the server's supported feature set - /// and other relevant capabilities. - const Capabilities& capabilities() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; + Omittable<RoomVersionsCapability> roomVersions; + + /// The custom capabilities the server supports, using theJava package + /// naming convention. + QHash<QString, QJsonObject> additionalProperties; }; + + // Construction/destruction + + explicit GetCapabilitiesJob(); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetCapabilitiesJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl); + + ~GetCapabilitiesJob() override; + + // Result properties + + /// The custom capabilities the server supports, using the + /// Java package naming convention. + const Capabilities& capabilities() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + } // namespace QMatrixClient diff --git a/lib/csapi/content-repo.cpp b/lib/csapi/content-repo.cpp index d59449b9..c2720d63 100644 --- a/lib/csapi/content-repo.cpp +++ b/lib/csapi/content-repo.cpp @@ -15,7 +15,7 @@ static const auto basePath = QStringLiteral("/_matrix/media/r0"); class UploadContentJob::Private { - public: +public: QString contentUri; }; @@ -31,11 +31,10 @@ static const auto UploadContentJobName = QStringLiteral("UploadContentJob"); UploadContentJob::UploadContentJob(QIODevice* content, const QString& filename, const QString& contentType) : BaseJob(HttpVerb::Post, UploadContentJobName, basePath % "/upload", - queryToUploadContent(filename)), - d(new Private) + queryToUploadContent(filename)) + , d(new Private) { setRequestHeader("Content-Type", contentType.toLatin1()); - setRequestData(Data(content)); } @@ -47,15 +46,16 @@ BaseJob::Status UploadContentJob::parseJson(const QJsonDocument& data) { auto json = data.object(); if (!json.contains("content_uri"_ls)) - return { JsonParseError, + return { IncorrectResponse, "The key 'content_uri' not found in the response" }; fromJson(json.value("content_uri"_ls), d->contentUri); + return Success; } class GetContentJob::Private { - public: +public: QString contentType; QString contentDisposition; QIODevice* data; @@ -73,7 +73,7 @@ QUrl GetContentJob::makeRequestUrl(QUrl baseUrl, const QString& serverName, { return BaseJob::makeRequestUrl(std::move(baseUrl), basePath % "/download/" % serverName % "/" - % mediaId, + % mediaId, queryToGetContent(allowRemote)); } @@ -83,8 +83,8 @@ GetContentJob::GetContentJob(const QString& serverName, const QString& mediaId, bool allowRemote) : BaseJob(HttpVerb::Get, GetContentJobName, basePath % "/download/" % serverName % "/" % mediaId, - queryToGetContent(allowRemote), {}, false), - d(new Private) + queryToGetContent(allowRemote), {}, false) + , d(new Private) { setExpectedContentTypes({ "*/*" }); } @@ -110,7 +110,7 @@ BaseJob::Status GetContentJob::parseReply(QNetworkReply* reply) class GetContentOverrideNameJob::Private { - public: +public: QString contentType; QString contentDisposition; QIODevice* data; @@ -131,12 +131,12 @@ QUrl GetContentOverrideNameJob::makeRequestUrl(QUrl baseUrl, { return BaseJob::makeRequestUrl(std::move(baseUrl), basePath % "/download/" % serverName % "/" - % mediaId % "/" % fileName, + % mediaId % "/" % fileName, queryToGetContentOverrideName(allowRemote)); } static const auto GetContentOverrideNameJobName = - QStringLiteral("GetContentOverrideNameJob"); + QStringLiteral("GetContentOverrideNameJob"); GetContentOverrideNameJob::GetContentOverrideNameJob(const QString& serverName, const QString& mediaId, @@ -144,9 +144,9 @@ GetContentOverrideNameJob::GetContentOverrideNameJob(const QString& serverName, bool allowRemote) : BaseJob(HttpVerb::Get, GetContentOverrideNameJobName, basePath % "/download/" % serverName % "/" % mediaId % "/" - % fileName, - queryToGetContentOverrideName(allowRemote), {}, false), - d(new Private) + % fileName, + queryToGetContentOverrideName(allowRemote), {}, false) + , d(new Private) { setExpectedContentTypes({ "*/*" }); } @@ -175,7 +175,7 @@ BaseJob::Status GetContentOverrideNameJob::parseReply(QNetworkReply* reply) class GetContentThumbnailJob::Private { - public: +public: QString contentType; QIODevice* data; }; @@ -199,24 +199,23 @@ QUrl GetContentThumbnailJob::makeRequestUrl(QUrl baseUrl, bool allowRemote) { return BaseJob::makeRequestUrl( - std::move(baseUrl), - basePath % "/thumbnail/" % serverName % "/" % mediaId, - queryToGetContentThumbnail(width, height, method, allowRemote)); + std::move(baseUrl), + basePath % "/thumbnail/" % serverName % "/" % mediaId, + queryToGetContentThumbnail(width, height, method, allowRemote)); } static const auto GetContentThumbnailJobName = - QStringLiteral("GetContentThumbnailJob"); + QStringLiteral("GetContentThumbnailJob"); GetContentThumbnailJob::GetContentThumbnailJob(const QString& serverName, - const QString& mediaId, - int width, int height, - const QString& method, + const QString& mediaId, int width, + int height, const QString& method, bool allowRemote) : BaseJob(HttpVerb::Get, GetContentThumbnailJobName, basePath % "/thumbnail/" % serverName % "/" % mediaId, queryToGetContentThumbnail(width, height, method, allowRemote), - {}, false), - d(new Private) + {}, false) + , d(new Private) { setExpectedContentTypes({ "image/jpeg", "image/png" }); } @@ -239,7 +238,7 @@ BaseJob::Status GetContentThumbnailJob::parseReply(QNetworkReply* reply) class GetUrlPreviewJob::Private { - public: +public: Omittable<qint64> matrixImageSize; QString ogImage; }; @@ -255,8 +254,7 @@ BaseJob::Query queryToGetUrlPreview(const QString& url, Omittable<qint64> ts) QUrl GetUrlPreviewJob::makeRequestUrl(QUrl baseUrl, const QString& url, Omittable<qint64> ts) { - return BaseJob::makeRequestUrl(std::move(baseUrl), - basePath % "/preview_url", + return BaseJob::makeRequestUrl(std::move(baseUrl), basePath % "/preview_url", queryToGetUrlPreview(url, ts)); } @@ -264,10 +262,9 @@ static const auto GetUrlPreviewJobName = QStringLiteral("GetUrlPreviewJob"); GetUrlPreviewJob::GetUrlPreviewJob(const QString& url, Omittable<qint64> ts) : BaseJob(HttpVerb::Get, GetUrlPreviewJobName, basePath % "/preview_url", - queryToGetUrlPreview(url, ts)), - d(new Private) -{ -} + queryToGetUrlPreview(url, ts)) + , d(new Private) +{} GetUrlPreviewJob::~GetUrlPreviewJob() = default; @@ -283,12 +280,13 @@ BaseJob::Status GetUrlPreviewJob::parseJson(const QJsonDocument& data) auto json = data.object(); fromJson(json.value("matrix:image:size"_ls), d->matrixImageSize); fromJson(json.value("og:image"_ls), d->ogImage); + return Success; } class GetConfigJob::Private { - public: +public: Omittable<qint64> uploadSize; }; @@ -300,10 +298,9 @@ QUrl GetConfigJob::makeRequestUrl(QUrl baseUrl) static const auto GetConfigJobName = QStringLiteral("GetConfigJob"); GetConfigJob::GetConfigJob() - : BaseJob(HttpVerb::Get, GetConfigJobName, basePath % "/config"), - d(new Private) -{ -} + : BaseJob(HttpVerb::Get, GetConfigJobName, basePath % "/config") + , d(new Private) +{} GetConfigJob::~GetConfigJob() = default; @@ -313,5 +310,6 @@ BaseJob::Status GetConfigJob::parseJson(const QJsonDocument& data) { auto json = data.object(); fromJson(json.value("m.upload.size"_ls), d->uploadSize); + return Success; } diff --git a/lib/csapi/content-repo.h b/lib/csapi/content-repo.h index 1bef6380..9f267f6c 100644 --- a/lib/csapi/content-repo.h +++ b/lib/csapi/content-repo.h @@ -4,276 +4,282 @@ #pragma once +#include "converters.h" + #include "jobs/basejob.h" -#include "converters.h" #include <QtCore/QIODevice> -namespace QMatrixClient { - // Operations - - /// Upload some content to the content repository. - class UploadContentJob : public BaseJob - { - public: - /*! Upload some content to the content repository. - * \param content - * \param filename - * The name of the file being uploaded - * \param contentType - * The content type of the file being uploaded - */ - explicit UploadContentJob(QIODevice* content, - const QString& filename = {}, - const QString& contentType = {}); - ~UploadContentJob() override; - - // Result properties - - /// The MXC URI to the uploaded content. - const QString& contentUri() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; - - /// Download content from the content repository. - class GetContentJob : public BaseJob - { - public: - /*! Download content from the content repository. - * \param serverName - * The server name from the ``mxc://`` URI (the authoritory component) - * \param mediaId - * The media ID from the ``mxc://`` URI (the path component) - * \param allowRemote - * Indicates to the server that it should not attempt to fetch the - * media if it is deemed remote. This is to prevent routing loops where - * the server contacts itself. Defaults to true if not provided. - */ - explicit GetContentJob(const QString& serverName, +namespace QMatrixClient +{ + +// Operations + +/// Upload some content to the content repository. + +class UploadContentJob : public BaseJob +{ +public: + /*! Upload some content to the content repository. + * \param content + * \param filename + * The name of the file being uploaded + * \param contentType + * The content type of the file being uploaded + */ + explicit UploadContentJob(QIODevice* content, const QString& filename = {}, + const QString& contentType = {}); + + ~UploadContentJob() override; + + // Result properties + + /// The MXC URI to the uploaded content. + const QString& contentUri() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Download content from the content repository. + +class GetContentJob : public BaseJob +{ +public: + /*! Download content from the content repository. + * \param serverName + * The server name from the ``mxc://`` URI (the authoritory component) + * \param mediaId + * The media ID from the ``mxc://`` URI (the path component) + * \param allowRemote + * Indicates to the server that it should not attempt to fetch the media + * if it is deemed remote. This is to prevent routing loops where the server + * contacts itself. Defaults to true if not provided. + */ + explicit GetContentJob(const QString& serverName, const QString& mediaId, + bool allowRemote = true); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetContentJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& serverName, const QString& mediaId, bool allowRemote = true); - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetContentJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& serverName, - const QString& mediaId, - bool allowRemote = true); - - ~GetContentJob() override; - - // Result properties - - /// The content type of the file that was previously uploaded. - const QString& contentType() const; - /// The name of the file that was previously uploaded, if set. - const QString& contentDisposition() const; - /// The content that was previously uploaded. - QIODevice* data() const; - - protected: - Status parseReply(QNetworkReply* reply) override; - - private: - class Private; - QScopedPointer<Private> d; - }; - - /// Download content from the content repository as a given filename. - class GetContentOverrideNameJob : public BaseJob - { - public: - /*! Download content from the content repository as a given filename. - * \param serverName - * The server name from the ``mxc://`` URI (the authoritory component) - * \param mediaId - * The media ID from the ``mxc://`` URI (the path component) - * \param fileName - * The filename to give in the Content-Disposition - * \param allowRemote - * Indicates to the server that it should not attempt to fetch the - * media if it is deemed remote. This is to prevent routing loops where - * the server contacts itself. Defaults to true if not provided. - */ - explicit GetContentOverrideNameJob(const QString& serverName, - const QString& mediaId, - const QString& fileName, - bool allowRemote = true); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetContentOverrideNameJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& serverName, - const QString& mediaId, - const QString& fileName, - bool allowRemote = true); - - ~GetContentOverrideNameJob() override; - - // Result properties - - /// The content type of the file that was previously uploaded. - const QString& contentType() const; - /// The name of file given in the request - const QString& contentDisposition() const; - /// The content that was previously uploaded. - QIODevice* data() const; - - protected: - Status parseReply(QNetworkReply* reply) override; - - private: - class Private; - QScopedPointer<Private> d; - }; - - /// Download a thumbnail of the content from the content repository. - class GetContentThumbnailJob : public BaseJob - { - public: - /*! Download a thumbnail of the content from the content repository. - * \param serverName - * The server name from the ``mxc://`` URI (the authoritory component) - * \param mediaId - * The media ID from the ``mxc://`` URI (the path component) - * \param width - * The *desired* width of the thumbnail. The actual thumbnail may not - * match the size specified. - * \param height - * The *desired* height of the thumbnail. The actual thumbnail may not - * match the size specified. - * \param method - * The desired resizing method. - * \param allowRemote - * Indicates to the server that it should not attempt to fetch the - * media if it is deemed remote. This is to prevent routing loops where - * the server contacts itself. Defaults to true if not provided. - */ - explicit GetContentThumbnailJob(const QString& serverName, - const QString& mediaId, int width, - int height, const QString& method = {}, - bool allowRemote = true); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetContentThumbnailJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& serverName, - const QString& mediaId, int width, - int height, const QString& method = {}, - bool allowRemote = true); - - ~GetContentThumbnailJob() override; - - // Result properties - - /// The content type of the thumbnail. - const QString& contentType() const; - /// A thumbnail of the requested content. - QIODevice* data() const; - - protected: - Status parseReply(QNetworkReply* reply) override; - - private: - class Private; - QScopedPointer<Private> d; - }; - - /// Get information about a URL for a client - class GetUrlPreviewJob : public BaseJob - { - public: - /*! Get information about a URL for a client - * \param url - * The URL to get a preview of - * \param ts - * The preferred point in time to return a preview for. The server may - * return a newer version if it does not have the requested version - * available. - */ - explicit GetUrlPreviewJob(const QString& url, - Omittable<qint64> ts = none); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetUrlPreviewJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& url, - Omittable<qint64> ts = none); - - ~GetUrlPreviewJob() override; - - // Result properties - - /// The byte-size of the image. Omitted if there is no image attached. - Omittable<qint64> matrixImageSize() const; - /// An MXC URI to the image. Omitted if there is no image. - const QString& ogImage() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; - - /// Get the configuration for the content repository. - /// - /// This endpoint allows clients to retrieve the configuration of the - /// content repository, such as upload limitations. Clients SHOULD use this - /// as a guide when using content repository endpoints. All values are - /// intentionally left optional. Clients SHOULD follow the advice given in - /// the field description when the field is not available. - /// - /// **NOTE:** Both clients and server administrators should be aware that - /// proxies between the client and the server may affect the apparent - /// behaviour of content repository APIs, for example, proxies may enforce a - /// lower upload size limit than is advertised by the server on this - /// endpoint. - class GetConfigJob : public BaseJob - { - public: - explicit GetConfigJob(); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetConfigJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl); - - ~GetConfigJob() override; - - // Result properties - - /// The maximum size an upload can be in bytes. - /// Clients SHOULD use this as a guide when uploading content. - /// If not listed or null, the size limit should be treated as unknown. - Omittable<qint64> uploadSize() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; + ~GetContentJob() override; + + // Result properties + + /// The content type of the file that was previously uploaded. + const QString& contentType() const; + /// The name of the file that was previously uploaded, if set. + const QString& contentDisposition() const; + /// The content that was previously uploaded. + QIODevice* data() const; + +protected: + Status parseReply(QNetworkReply* reply) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Download content from the content repository as a given filename. + +class GetContentOverrideNameJob : public BaseJob +{ +public: + /*! Download content from the content repository as a given filename. + * \param serverName + * The server name from the ``mxc://`` URI (the authoritory component) + * \param mediaId + * The media ID from the ``mxc://`` URI (the path component) + * \param fileName + * The filename to give in the Content-Disposition + * \param allowRemote + * Indicates to the server that it should not attempt to fetch the media + * if it is deemed remote. This is to prevent routing loops where the server + * contacts itself. Defaults to true if not provided. + */ + explicit GetContentOverrideNameJob(const QString& serverName, + const QString& mediaId, + const QString& fileName, + bool allowRemote = true); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetContentOverrideNameJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& serverName, + const QString& mediaId, const QString& fileName, + bool allowRemote = true); + + ~GetContentOverrideNameJob() override; + + // Result properties + + /// The content type of the file that was previously uploaded. + const QString& contentType() const; + /// The name of file given in the request + const QString& contentDisposition() const; + /// The content that was previously uploaded. + QIODevice* data() const; + +protected: + Status parseReply(QNetworkReply* reply) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Download a thumbnail of the content from the content repository. + +class GetContentThumbnailJob : public BaseJob +{ +public: + /*! Download a thumbnail of the content from the content repository. + * \param serverName + * The server name from the ``mxc://`` URI (the authoritory component) + * \param mediaId + * The media ID from the ``mxc://`` URI (the path component) + * \param width + * The *desired* width of the thumbnail. The actual thumbnail may not + * match the size specified. + * \param height + * The *desired* height of the thumbnail. The actual thumbnail may not + * match the size specified. + * \param method + * The desired resizing method. + * \param allowRemote + * Indicates to the server that it should not attempt to fetch the media + * if it is deemed remote. This is to prevent routing loops where the server + * contacts itself. Defaults to true if not provided. + */ + explicit GetContentThumbnailJob(const QString& serverName, + const QString& mediaId, int width, + int height, const QString& method = {}, + bool allowRemote = true); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetContentThumbnailJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& serverName, + const QString& mediaId, int width, int height, + const QString& method = {}, + bool allowRemote = true); + + ~GetContentThumbnailJob() override; + + // Result properties + + /// The content type of the thumbnail. + const QString& contentType() const; + /// A thumbnail of the requested content. + QIODevice* data() const; + +protected: + Status parseReply(QNetworkReply* reply) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Get information about a URL for a client + +class GetUrlPreviewJob : public BaseJob +{ +public: + /*! Get information about a URL for a client + * \param url + * The URL to get a preview of + * \param ts + * The preferred point in time to return a preview for. The server may + * return a newer version if it does not have the requested version + * available. + */ + explicit GetUrlPreviewJob(const QString& url, Omittable<qint64> ts = none); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetUrlPreviewJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& url, + Omittable<qint64> ts = none); + + ~GetUrlPreviewJob() override; + + // Result properties + + /// The byte-size of the image. Omitted if there is no image attached. + Omittable<qint64> matrixImageSize() const; + /// An MXC URI to the image. Omitted if there is no image. + const QString& ogImage() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Get the configuration for the content repository. +/*! + * This endpoint allows clients to retrieve the configuration of the content + * repository, such as upload limitations. + * Clients SHOULD use this as a guide when using content repository endpoints. + * All values are intentionally left optional. Clients SHOULD follow + * the advice given in the field description when the field is not available. + * + * **NOTE:** Both clients and server administrators should be aware that proxies + * between the client and the server may affect the apparent behaviour of + * content repository APIs, for example, proxies may enforce a lower upload size + * limit than is advertised by the server on this endpoint. + */ +class GetConfigJob : public BaseJob +{ +public: + explicit GetConfigJob(); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetConfigJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl); + + ~GetConfigJob() override; + + // Result properties + + /// The maximum size an upload can be in bytes. + /// Clients SHOULD use this as a guide when uploading content. + /// If not listed or null, the size limit should be treated as unknown. + Omittable<qint64> uploadSize() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + } // namespace QMatrixClient diff --git a/lib/csapi/create_room.cpp b/lib/csapi/create_room.cpp index 47a13d8e..e94cb008 100644 --- a/lib/csapi/create_room.cpp +++ b/lib/csapi/create_room.cpp @@ -12,33 +12,37 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); -namespace QMatrixClient { - // Converters - - template <> struct JsonObjectConverter<CreateRoomJob::Invite3pid> { - static void dumpTo(QJsonObject& jo, - const CreateRoomJob::Invite3pid& pod) - { - addParam<>(jo, QStringLiteral("id_server"), pod.idServer); - addParam<>(jo, QStringLiteral("medium"), pod.medium); - addParam<>(jo, QStringLiteral("address"), pod.address); - } - }; - - template <> struct JsonObjectConverter<CreateRoomJob::StateEvent> { - static void dumpTo(QJsonObject& jo, - const CreateRoomJob::StateEvent& pod) - { - addParam<>(jo, QStringLiteral("type"), pod.type); - addParam<IfNotEmpty>(jo, QStringLiteral("state_key"), pod.stateKey); - addParam<>(jo, QStringLiteral("content"), pod.content); - } - }; +// Converters +namespace QMatrixClient +{ + +template <> +struct JsonObjectConverter<CreateRoomJob::Invite3pid> +{ + static void dumpTo(QJsonObject& jo, const CreateRoomJob::Invite3pid& pod) + { + addParam<>(jo, QStringLiteral("id_server"), pod.idServer); + addParam<>(jo, QStringLiteral("medium"), pod.medium); + addParam<>(jo, QStringLiteral("address"), pod.address); + } +}; + +template <> +struct JsonObjectConverter<CreateRoomJob::StateEvent> +{ + static void dumpTo(QJsonObject& jo, const CreateRoomJob::StateEvent& pod) + { + addParam<>(jo, QStringLiteral("type"), pod.type); + addParam<IfNotEmpty>(jo, QStringLiteral("state_key"), pod.stateKey); + addParam<>(jo, QStringLiteral("content"), pod.content); + } +}; + } // namespace QMatrixClient class CreateRoomJob::Private { - public: +public: QString roomId; }; @@ -53,8 +57,8 @@ CreateRoomJob::CreateRoomJob(const QString& visibility, const QVector<StateEvent>& initialState, const QString& preset, Omittable<bool> isDirect, const QJsonObject& powerLevelContentOverride) - : BaseJob(HttpVerb::Post, CreateRoomJobName, basePath % "/createRoom"), - d(new Private) + : BaseJob(HttpVerb::Post, CreateRoomJobName, basePath % "/createRoom") + , d(new Private) { QJsonObject _data; addParam<IfNotEmpty>(_data, QStringLiteral("visibility"), visibility); @@ -83,8 +87,9 @@ BaseJob::Status CreateRoomJob::parseJson(const QJsonDocument& data) { auto json = data.object(); if (!json.contains("room_id"_ls)) - return { JsonParseError, + return { IncorrectResponse, "The key 'room_id' not found in the response" }; fromJson(json.value("room_id"_ls), d->roomId); + return Success; } diff --git a/lib/csapi/create_room.h b/lib/csapi/create_room.h index 4348bd63..a066a3f3 100644 --- a/lib/csapi/create_room.h +++ b/lib/csapi/create_room.h @@ -4,269 +4,235 @@ #pragma once +#include "converters.h" + #include "jobs/basejob.h" -#include "converters.h" #include <QtCore/QJsonObject> #include <QtCore/QVector> -namespace QMatrixClient { - // Operations +namespace QMatrixClient +{ + +// Operations + +/// Create a new room +/*! + * Create a new room with various configuration options. + * + * The server MUST apply the normal state resolution rules when creating + * the new room, including checking power levels for each event. It MUST + * apply the events implied by the request in the following order: + * + * 0. A default ``m.room.power_levels`` event, giving the room creator + * (and not other members) permission to send state events. Overridden + * by the ``power_level_content_override`` parameter. + * + * 1. Events set by the ``preset``. Currently these are the + * ``m.room.join_rules``, + * ``m.room.history_visibility``, and ``m.room.guest_access`` state events. + * + * 2. Events listed in ``initial_state``, in the order that they are + * listed. + * + * 3. Events implied by ``name`` and ``topic`` (``m.room.name`` and + * ``m.room.topic`` state events). + * + * 4. Invite events implied by ``invite`` and ``invite_3pid`` (``m.room.member`` + * with + * ``membership: invite`` and ``m.room.third_party_invite``). + * + * The available presets do the following with respect to room state: + * + * ======================== ============== ====================== + * ================ ========= Preset ``join_rules`` + * ``history_visibility`` ``guest_access`` Other + * ======================== ============== ====================== + * ================ ========= + * ``private_chat`` ``invite`` ``shared`` ``can_join`` + * ``trusted_private_chat`` ``invite`` ``shared`` ``can_join`` All + * invitees are given the same power level as the room creator. + * ``public_chat`` ``public`` ``shared`` ``forbidden`` + * ======================== ============== ====================== + * ================ ========= + * + * The server will create a ``m.room.create`` event in the room with the + * requesting user as the creator, alongside other keys provided in the + * ``creation_content``. + */ +class CreateRoomJob : public BaseJob +{ +public: + // Inner data structures - /// Create a new room - /// - /// Create a new room with various configuration options. - /// - /// The server MUST apply the normal state resolution rules when creating - /// the new room, including checking power levels for each event. It MUST - /// apply the events implied by the request in the following order: - /// - /// 0. A default ``m.room.power_levels`` event, giving the room creator - /// (and not other members) permission to send state events. Overridden - /// by the ``power_level_content_override`` parameter. - /// - /// 1. Events set by the ``preset``. Currently these are the - /// ``m.room.join_rules``, - /// ``m.room.history_visibility``, and ``m.room.guest_access`` state - /// events. - /// - /// 2. Events listed in ``initial_state``, in the order that they are - /// listed. - /// - /// 3. Events implied by ``name`` and ``topic`` (``m.room.name`` and - /// ``m.room.topic`` - /// state events). - /// - /// 4. Invite events implied by ``invite`` and ``invite_3pid`` - /// (``m.room.member`` with - /// ``membership: invite`` and ``m.room.third_party_invite``). - /// - /// The available presets do the following with respect to room state: - /// - /// ======================== ============== ====================== - /// ================ ========= - /// Preset ``join_rules`` ``history_visibility`` - /// ``guest_access`` Other - /// ======================== ============== ====================== - /// ================ ========= - /// ``private_chat`` ``invite`` ``shared`` ``can_join`` - /// ``trusted_private_chat`` ``invite`` ``shared`` ``can_join`` All - /// invitees are given the same power level as the room creator. - /// ``public_chat`` ``public`` ``shared`` ``forbidden`` - /// ======================== ============== ====================== - /// ================ ========= - /// - /// The server will create a ``m.room.create`` event in the room with the - /// requesting user as the creator, alongside other keys provided in the - /// ``creation_content``. - class CreateRoomJob : public BaseJob + /// Create a new room with various configuration options.The server MUST + /// apply the normal state resolution rules when creatingthe new room, + /// including checking power levels for each event. It MUSTapply the events + /// implied by the request in the following order:0. A default + /// ``m.room.power_levels`` event, giving the room creator (and not other + /// members) permission to send state events. Overridden by the + /// ``power_level_content_override`` parameter.1. Events set by the + /// ``preset``. Currently these are the ``m.room.join_rules``, + /// ``m.room.history_visibility``, and ``m.room.guest_access`` state + /// events.2. Events listed in ``initial_state``, in the order that they are + /// listed.3. Events implied by ``name`` and ``topic`` (``m.room.name`` and + /// ``m.room.topic`` state events).4. Invite events implied by ``invite`` + /// and ``invite_3pid`` (``m.room.member`` with ``membership: invite`` and + /// ``m.room.third_party_invite``).The available presets do the following + /// with respect to room state:======================== ============== + /// ====================== ================ ========= Preset + /// ``join_rules`` ``history_visibility`` ``guest_access`` + /// Other======================== ============== ====================== + /// ================ =========``private_chat`` ``invite`` + /// ``shared`` ``can_join````trusted_private_chat`` ``invite`` + /// ``shared`` ``can_join`` All invitees are given the + /// same power level as the room creator.``public_chat`` ``public`` + /// ``shared`` ``forbidden``======================== + /// ============== ====================== ================ =========The + /// server will create a ``m.room.create`` event in the room with + /// therequesting user as the creator, alongside other keys provided in + /// the``creation_content``. + struct Invite3pid { - public: - // Inner data structures + /// The hostname+port of the identity server which should be used for + /// third party identifier lookups. + QString idServer; + /// The kind of address being passed in the address field, for example + /// ``email``. + QString medium; + /// The invitee's third party identifier. + QString address; + }; - /// Create a new room with various configuration options. - /// - /// The server MUST apply the normal state resolution rules when - /// creating the new room, including checking power levels for each - /// event. It MUST apply the events implied by the request in the - /// following order: - /// - /// 0. A default ``m.room.power_levels`` event, giving the room creator - /// (and not other members) permission to send state events. - /// Overridden by the ``power_level_content_override`` parameter. - /// - /// 1. Events set by the ``preset``. Currently these are the - /// ``m.room.join_rules``, - /// ``m.room.history_visibility``, and ``m.room.guest_access`` state - /// events. - /// - /// 2. Events listed in ``initial_state``, in the order that they are - /// listed. - /// - /// 3. Events implied by ``name`` and ``topic`` (``m.room.name`` and - /// ``m.room.topic`` - /// state events). - /// - /// 4. Invite events implied by ``invite`` and ``invite_3pid`` - /// (``m.room.member`` with - /// ``membership: invite`` and ``m.room.third_party_invite``). - /// - /// The available presets do the following with respect to room state: - /// - /// ======================== ============== ====================== - /// ================ ========= - /// Preset ``join_rules`` ``history_visibility`` - /// ``guest_access`` Other - /// ======================== ============== ====================== - /// ================ ========= - /// ``private_chat`` ``invite`` ``shared`` ``can_join`` - /// ``trusted_private_chat`` ``invite`` ``shared`` ``can_join`` - /// All invitees are given the same power level as the room creator. - /// ``public_chat`` ``public`` ``shared`` ``forbidden`` - /// ======================== ============== ====================== - /// ================ ========= - /// - /// The server will create a ``m.room.create`` event in the room with - /// the requesting user as the creator, alongside other keys provided in - /// the - /// ``creation_content``. - struct Invite3pid { - /// The hostname+port of the identity server which should be used - /// for third party identifier lookups. - QString idServer; - /// The kind of address being passed in the address field, for - /// example ``email``. - QString medium; - /// The invitee's third party identifier. - QString address; - }; + /// Create a new room with various configuration options.The server MUST + /// apply the normal state resolution rules when creatingthe new room, + /// including checking power levels for each event. It MUSTapply the events + /// implied by the request in the following order:0. A default + /// ``m.room.power_levels`` event, giving the room creator (and not other + /// members) permission to send state events. Overridden by the + /// ``power_level_content_override`` parameter.1. Events set by the + /// ``preset``. Currently these are the ``m.room.join_rules``, + /// ``m.room.history_visibility``, and ``m.room.guest_access`` state + /// events.2. Events listed in ``initial_state``, in the order that they are + /// listed.3. Events implied by ``name`` and ``topic`` (``m.room.name`` and + /// ``m.room.topic`` state events).4. Invite events implied by ``invite`` + /// and ``invite_3pid`` (``m.room.member`` with ``membership: invite`` and + /// ``m.room.third_party_invite``).The available presets do the following + /// with respect to room state:======================== ============== + /// ====================== ================ ========= Preset + /// ``join_rules`` ``history_visibility`` ``guest_access`` + /// Other======================== ============== ====================== + /// ================ =========``private_chat`` ``invite`` + /// ``shared`` ``can_join````trusted_private_chat`` ``invite`` + /// ``shared`` ``can_join`` All invitees are given the + /// same power level as the room creator.``public_chat`` ``public`` + /// ``shared`` ``forbidden``======================== + /// ============== ====================== ================ =========The + /// server will create a ``m.room.create`` event in the room with + /// therequesting user as the creator, alongside other keys provided in + /// the``creation_content``. + struct StateEvent + { + /// The type of event to send. + QString type; + /// The state_key of the state event. Defaults to an empty string. + QString stateKey; + /// The content of the event. + QJsonObject content; + }; - /// Create a new room with various configuration options. - /// - /// The server MUST apply the normal state resolution rules when - /// creating the new room, including checking power levels for each - /// event. It MUST apply the events implied by the request in the - /// following order: - /// - /// 0. A default ``m.room.power_levels`` event, giving the room creator - /// (and not other members) permission to send state events. - /// Overridden by the ``power_level_content_override`` parameter. - /// - /// 1. Events set by the ``preset``. Currently these are the - /// ``m.room.join_rules``, - /// ``m.room.history_visibility``, and ``m.room.guest_access`` state - /// events. - /// - /// 2. Events listed in ``initial_state``, in the order that they are - /// listed. - /// - /// 3. Events implied by ``name`` and ``topic`` (``m.room.name`` and - /// ``m.room.topic`` - /// state events). - /// - /// 4. Invite events implied by ``invite`` and ``invite_3pid`` - /// (``m.room.member`` with - /// ``membership: invite`` and ``m.room.third_party_invite``). - /// - /// The available presets do the following with respect to room state: - /// - /// ======================== ============== ====================== - /// ================ ========= - /// Preset ``join_rules`` ``history_visibility`` - /// ``guest_access`` Other - /// ======================== ============== ====================== - /// ================ ========= - /// ``private_chat`` ``invite`` ``shared`` ``can_join`` - /// ``trusted_private_chat`` ``invite`` ``shared`` ``can_join`` - /// All invitees are given the same power level as the room creator. - /// ``public_chat`` ``public`` ``shared`` ``forbidden`` - /// ======================== ============== ====================== - /// ================ ========= - /// - /// The server will create a ``m.room.create`` event in the room with - /// the requesting user as the creator, alongside other keys provided in - /// the - /// ``creation_content``. - struct StateEvent { - /// The type of event to send. - QString type; - /// The state_key of the state event. Defaults to an empty string. - QString stateKey; - /// The content of the event. - QJsonObject content; - }; + // Construction/destruction - // Construction/destruction + /*! Create a new room + * \param visibility + * A ``public`` visibility indicates that the room will be shown + * in the published room list. A ``private`` visibility will hide + * the room from the published room list. Rooms default to + * ``private`` visibility if this key is not included. NB: This + * should not be confused with ``join_rules`` which also uses the + * word ``public``. + * \param roomAliasName + * The desired room alias **local part**. If this is included, a + * room alias will be created and mapped to the newly created + * room. The alias will belong on the *same* homeserver which + * created the room. For example, if this was set to "foo" and + * sent to the homeserver "example.com" the complete room alias + * would be ``#foo:example.com``. + * + * The complete room alias will become the canonical alias for + * the room. + * \param name + * If this is included, an ``m.room.name`` event will be sent + * into the room to indicate the name of the room. See Room + * Events for more information on ``m.room.name``. + * \param topic + * If this is included, an ``m.room.topic`` event will be sent + * into the room to indicate the topic for the room. See Room + * Events for more information on ``m.room.topic``. + * \param invite + * A list of user IDs to invite to the room. This will tell the + * server to invite everyone in the list to the newly created room. + * \param invite3pid + * A list of objects representing third party IDs to invite into + * the room. + * \param roomVersion + * The room version to set for the room. If not provided, the homeserver + * is to use its configured default. If provided, the homeserver will return + * a 400 error with the errcode ``M_UNSUPPORTED_ROOM_VERSION`` if it does + * not support the room version. \param creationContent Extra keys, such as + * ``m.federate``, to be added to the content of the `m.room.create`_ event. + * The server will clobber the following keys: ``creator``, + * ``room_version``. Future versions of the specification may allow the + * server to clobber other keys. \param initialState A list of state events + * to set in the new room. This allows the user to override the default + * state events set in the new room. The expected format of the state events + * are an object with type, state_key and content keys set. + * + * Takes precedence over events set by ``preset``, but gets + * overriden by ``name`` and ``topic`` keys. + * \param preset + * Convenience parameter for setting various default state events + * based on a preset. + * + * If unspecified, the server should use the ``visibility`` to determine + * which preset to use. A visbility of ``public`` equates to a preset of + * ``public_chat`` and ``private`` visibility equates to a preset of + * ``private_chat``. + * \param isDirect + * This flag makes the server set the ``is_direct`` flag on the + * ``m.room.member`` events sent to the users in ``invite`` and + * ``invite_3pid``. See `Direct Messaging`_ for more information. + * \param powerLevelContentOverride + * The power level content to override in the default power level + * event. This object is applied on top of the generated + * `m.room.power_levels`_ event content prior to it being sent to the room. + * Defaults to overriding nothing. + */ + explicit CreateRoomJob(const QString& visibility = {}, + const QString& roomAliasName = {}, + const QString& name = {}, const QString& topic = {}, + const QStringList& invite = {}, + const QVector<Invite3pid>& invite3pid = {}, + const QString& roomVersion = {}, + const QJsonObject& creationContent = {}, + const QVector<StateEvent>& initialState = {}, + const QString& preset = {}, + Omittable<bool> isDirect = none, + const QJsonObject& powerLevelContentOverride = {}); - /*! Create a new room - * \param visibility - * A ``public`` visibility indicates that the room will be shown - * in the published room list. A ``private`` visibility will hide - * the room from the published room list. Rooms default to - * ``private`` visibility if this key is not included. NB: This - * should not be confused with ``join_rules`` which also uses the - * word ``public``. - * \param roomAliasName - * The desired room alias **local part**. If this is included, a - * room alias will be created and mapped to the newly created - * room. The alias will belong on the *same* homeserver which - * created the room. For example, if this was set to "foo" and - * sent to the homeserver "example.com" the complete room alias - * would be ``#foo:example.com``. - * - * The complete room alias will become the canonical alias for - * the room. - * \param name - * If this is included, an ``m.room.name`` event will be sent - * into the room to indicate the name of the room. See Room - * Events for more information on ``m.room.name``. - * \param topic - * If this is included, an ``m.room.topic`` event will be sent - * into the room to indicate the topic for the room. See Room - * Events for more information on ``m.room.topic``. - * \param invite - * A list of user IDs to invite to the room. This will tell the - * server to invite everyone in the list to the newly created room. - * \param invite3pid - * A list of objects representing third party IDs to invite into - * the room. - * \param roomVersion - * The room version to set for the room. If not provided, the - * homeserver is to use its configured default. If provided, the - * homeserver will return a 400 error with the errcode - * ``M_UNSUPPORTED_ROOM_VERSION`` if it does not support the room - * version. \param creationContent Extra keys, such as ``m.federate``, - * to be added to the content of the `m.room.create`_ event. The server - * will clobber the following keys: ``creator``, ``room_version``. - * Future versions of the specification may allow the server to clobber - * other keys. \param initialState A list of state events to set in the - * new room. This allows the user to override the default state events - * set in the new room. The expected format of the state events are an - * object with type, state_key and content keys set. - * - * Takes precedence over events set by ``preset``, but gets - * overriden by ``name`` and ``topic`` keys. - * \param preset - * Convenience parameter for setting various default state events - * based on a preset. - * - * If unspecified, the server should use the ``visibility`` to - * determine which preset to use. A visbility of ``public`` equates to a - * preset of - * ``public_chat`` and ``private`` visibility equates to a preset of - * ``private_chat``. - * \param isDirect - * This flag makes the server set the ``is_direct`` flag on the - * ``m.room.member`` events sent to the users in ``invite`` and - * ``invite_3pid``. See `Direct Messaging`_ for more information. - * \param powerLevelContentOverride - * The power level content to override in the default power level - * event. This object is applied on top of the generated - * `m.room.power_levels`_ event content prior to it being sent to the - * room. Defaults to overriding nothing. - */ - explicit CreateRoomJob( - const QString& visibility = {}, - const QString& roomAliasName = {}, const QString& name = {}, - const QString& topic = {}, const QStringList& invite = {}, - const QVector<Invite3pid>& invite3pid = {}, - const QString& roomVersion = {}, - const QJsonObject& creationContent = {}, - const QVector<StateEvent>& initialState = {}, - const QString& preset = {}, Omittable<bool> isDirect = none, - const QJsonObject& powerLevelContentOverride = {}); - ~CreateRoomJob() override; + ~CreateRoomJob() override; - // Result properties + // Result properties - /// The created room's ID. - const QString& roomId() const; + /// The created room's ID. + const QString& roomId() const; - protected: - Status parseJson(const QJsonDocument& data) override; +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; - private: - class Private; - QScopedPointer<Private> d; - }; } // namespace QMatrixClient diff --git a/lib/csapi/definitions/auth_data.cpp b/lib/csapi/definitions/auth_data.cpp index f40a3a90..b0303a19 100644 --- a/lib/csapi/definitions/auth_data.cpp +++ b/lib/csapi/definitions/auth_data.cpp @@ -4,21 +4,25 @@ #include "auth_data.h" + using namespace QMatrixClient; -void JsonObjectConverter<AuthenticationData>::dumpTo( - QJsonObject& jo, const AuthenticationData& pod) + +void JsonObjectConverter<AuthenticationData>::dumpTo(QJsonObject& jo, const AuthenticationData& pod) { fillJson(jo, pod.authInfo); addParam<>(jo, QStringLiteral("type"), pod.type); addParam<IfNotEmpty>(jo, QStringLiteral("session"), pod.session); -} -void JsonObjectConverter<AuthenticationData>::fillFrom( - QJsonObject jo, AuthenticationData& result) +} + +void JsonObjectConverter<AuthenticationData>::fillFrom(QJsonObject jo, AuthenticationData& result) { fromJson(jo.take("type"_ls), result.type); fromJson(jo.take("session"_ls), result.session); - fromJson(jo, result.authInfo); + } + + + diff --git a/lib/csapi/definitions/auth_data.h b/lib/csapi/definitions/auth_data.h index e25dff7a..689caf49 100644 --- a/lib/csapi/definitions/auth_data.h +++ b/lib/csapi/definitions/auth_data.h @@ -4,27 +4,37 @@ #pragma once + + #include "converters.h" -#include <QtCore/QHash> #include <QtCore/QJsonObject> +#include <QtCore/QHash> + +namespace QMatrixClient +{ + +// Data structures + +/// Used by clients to submit authentication information to the interactive-authentication API +struct AuthenticationData +{ + /// The login type that the client is attempting to complete. + QString type; + /// The value of the session key given by the homeserver. + QString session; + + + /// Keys dependent on the login type + QHash<QString, QJsonObject> authInfo; + +}; + +template <> struct JsonObjectConverter<AuthenticationData> +{ + static void dumpTo(QJsonObject& jo, const AuthenticationData& pod); + static void fillFrom(QJsonObject jo, AuthenticationData& pod);}; + -namespace QMatrixClient { - // Data structures - - /// Used by clients to submit authentication information to the - /// interactive-authentication API - struct AuthenticationData { - /// The login type that the client is attempting to complete. - QString type; - /// The value of the session key given by the homeserver. - QString session; - /// Keys dependent on the login type - QHash<QString, QJsonObject> authInfo; - }; - template <> struct JsonObjectConverter<AuthenticationData> { - static void dumpTo(QJsonObject& jo, const AuthenticationData& pod); - static void fillFrom(QJsonObject jo, AuthenticationData& pod); - }; } // namespace QMatrixClient diff --git a/lib/csapi/definitions/client_device.cpp b/lib/csapi/definitions/client_device.cpp index 2ca58e2f..5710537d 100644 --- a/lib/csapi/definitions/client_device.cpp +++ b/lib/csapi/definitions/client_device.cpp @@ -4,21 +4,27 @@ #include "client_device.h" + using namespace QMatrixClient; + void JsonObjectConverter<Device>::dumpTo(QJsonObject& jo, const Device& pod) { addParam<>(jo, QStringLiteral("device_id"), pod.deviceId); addParam<IfNotEmpty>(jo, QStringLiteral("display_name"), pod.displayName); addParam<IfNotEmpty>(jo, QStringLiteral("last_seen_ip"), pod.lastSeenIp); addParam<IfNotEmpty>(jo, QStringLiteral("last_seen_ts"), pod.lastSeenTs); -} -void JsonObjectConverter<Device>::fillFrom(const QJsonObject& jo, - Device& result) +} + +void JsonObjectConverter<Device>::fillFrom(const QJsonObject& jo, Device& result) { fromJson(jo.value("device_id"_ls), result.deviceId); fromJson(jo.value("display_name"_ls), result.displayName); fromJson(jo.value("last_seen_ip"_ls), result.lastSeenIp); fromJson(jo.value("last_seen_ts"_ls), result.lastSeenTs); + } + + + diff --git a/lib/csapi/definitions/client_device.h b/lib/csapi/definitions/client_device.h index b473a037..7c63a9b6 100644 --- a/lib/csapi/definitions/client_device.h +++ b/lib/csapi/definitions/client_device.h @@ -4,31 +4,37 @@ #pragma once + + #include "converters.h" #include "converters.h" -namespace QMatrixClient { - // Data structures - - /// A client device - struct Device { - /// Identifier of this device. - QString deviceId; - /// Display name set by the user for this device. Absent if no name has - /// been set. - QString displayName; - /// The IP address where this device was last seen. (May be a few - /// minutes out of date, for efficiency reasons). - QString lastSeenIp; - /// The timestamp (in milliseconds since the unix epoch) when this - /// devices was last seen. (May be a few minutes out of date, for - /// efficiency reasons). - Omittable<qint64> lastSeenTs; - }; - template <> struct JsonObjectConverter<Device> { - static void dumpTo(QJsonObject& jo, const Device& pod); - static void fillFrom(const QJsonObject& jo, Device& pod); - }; +namespace QMatrixClient +{ + +// Data structures + +/// A client device +struct Device +{ + /// Identifier of this device. + QString deviceId; + /// Display name set by the user for this device. Absent if no name has beenset. + QString displayName; + /// The IP address where this device was last seen. (May be a few minutes outof date, for efficiency reasons). + QString lastSeenIp; + /// The timestamp (in milliseconds since the unix epoch) when this deviceswas last seen. (May be a few minutes out of date, for efficiencyreasons). + Omittable<qint64> lastSeenTs; + + +}; + +template <> struct JsonObjectConverter<Device> +{ + static void dumpTo(QJsonObject& jo, const Device& pod); + static void fillFrom(const QJsonObject& jo, Device& pod);}; + + } // namespace QMatrixClient diff --git a/lib/csapi/definitions/device_keys.cpp b/lib/csapi/definitions/device_keys.cpp index cc5262b7..ffe0cfbe 100644 --- a/lib/csapi/definitions/device_keys.cpp +++ b/lib/csapi/definitions/device_keys.cpp @@ -4,24 +4,29 @@ #include "device_keys.h" + using namespace QMatrixClient; -void JsonObjectConverter<DeviceKeys>::dumpTo(QJsonObject& jo, - const DeviceKeys& pod) + +void JsonObjectConverter<DeviceKeys>::dumpTo(QJsonObject& jo, const DeviceKeys& pod) { addParam<>(jo, QStringLiteral("user_id"), pod.userId); addParam<>(jo, QStringLiteral("device_id"), pod.deviceId); addParam<>(jo, QStringLiteral("algorithms"), pod.algorithms); addParam<>(jo, QStringLiteral("keys"), pod.keys); addParam<>(jo, QStringLiteral("signatures"), pod.signatures); -} -void JsonObjectConverter<DeviceKeys>::fillFrom(const QJsonObject& jo, - DeviceKeys& result) +} + +void JsonObjectConverter<DeviceKeys>::fillFrom(const QJsonObject& jo, DeviceKeys& result) { fromJson(jo.value("user_id"_ls), result.userId); fromJson(jo.value("device_id"_ls), result.deviceId); fromJson(jo.value("algorithms"_ls), result.algorithms); fromJson(jo.value("keys"_ls), result.keys); fromJson(jo.value("signatures"_ls), result.signatures); + } + + + diff --git a/lib/csapi/definitions/device_keys.h b/lib/csapi/definitions/device_keys.h index 6c417ce7..c86db46a 100644 --- a/lib/csapi/definitions/device_keys.h +++ b/lib/csapi/definitions/device_keys.h @@ -4,38 +4,39 @@ #pragma once + + #include "converters.h" #include <QtCore/QHash> -namespace QMatrixClient { - // Data structures - - /// Device identity keys - struct DeviceKeys { - /// The ID of the user the device belongs to. Must match the user ID - /// used when logging in. - QString userId; - /// The ID of the device these keys belong to. Must match the device ID - /// used when logging in. - QString deviceId; - /// The encryption algorithms supported by this device. - QStringList algorithms; - /// Public identity keys. The names of the properties should be in the - /// format ``<algorithm>:<device_id>``. The keys themselves should be - /// encoded as specified by the key algorithm. - QHash<QString, QString> keys; - /// Signatures for the device key object. A map from user ID, to a map - /// from - /// ``<algorithm>:<device_id>`` to the signature. - /// - /// The signature is calculated using the process described at `Signing - /// JSON`_. - QHash<QString, QHash<QString, QString>> signatures; - }; - template <> struct JsonObjectConverter<DeviceKeys> { - static void dumpTo(QJsonObject& jo, const DeviceKeys& pod); - static void fillFrom(const QJsonObject& jo, DeviceKeys& pod); - }; +namespace QMatrixClient +{ + +// Data structures + +/// Device identity keys +struct DeviceKeys +{ + /// The ID of the user the device belongs to. Must match the user ID usedwhen logging in. + QString userId; + /// The ID of the device these keys belong to. Must match the device ID usedwhen logging in. + QString deviceId; + /// The encryption algorithms supported by this device. + QStringList algorithms; + /// Public identity keys. The names of the properties should be in theformat ``<algorithm>:<device_id>``. The keys themselves should beencoded as specified by the key algorithm. + QHash<QString, QString> keys; + /// Signatures for the device key object. A map from user ID, to a map from``<algorithm>:<device_id>`` to the signature.The signature is calculated using the process described at `SigningJSON`_. + QHash<QString, QHash<QString, QString>> signatures; + + +}; + +template <> struct JsonObjectConverter<DeviceKeys> +{ + static void dumpTo(QJsonObject& jo, const DeviceKeys& pod); + static void fillFrom(const QJsonObject& jo, DeviceKeys& pod);}; + + } // namespace QMatrixClient diff --git a/lib/csapi/definitions/event_filter.cpp b/lib/csapi/definitions/event_filter.cpp index 9b2c7a33..8be98c94 100644 --- a/lib/csapi/definitions/event_filter.cpp +++ b/lib/csapi/definitions/event_filter.cpp @@ -4,24 +4,29 @@ #include "event_filter.h" + using namespace QMatrixClient; -void JsonObjectConverter<EventFilter>::dumpTo(QJsonObject& jo, - const EventFilter& pod) + +void JsonObjectConverter<EventFilter>::dumpTo(QJsonObject& jo, const EventFilter& pod) { addParam<IfNotEmpty>(jo, QStringLiteral("limit"), pod.limit); addParam<IfNotEmpty>(jo, QStringLiteral("not_senders"), pod.notSenders); addParam<IfNotEmpty>(jo, QStringLiteral("not_types"), pod.notTypes); addParam<IfNotEmpty>(jo, QStringLiteral("senders"), pod.senders); addParam<IfNotEmpty>(jo, QStringLiteral("types"), pod.types); -} -void JsonObjectConverter<EventFilter>::fillFrom(const QJsonObject& jo, - EventFilter& result) +} + +void JsonObjectConverter<EventFilter>::fillFrom(const QJsonObject& jo, EventFilter& result) { fromJson(jo.value("limit"_ls), result.limit); fromJson(jo.value("not_senders"_ls), result.notSenders); fromJson(jo.value("not_types"_ls), result.notTypes); fromJson(jo.value("senders"_ls), result.senders); fromJson(jo.value("types"_ls), result.types); + } + + + diff --git a/lib/csapi/definitions/event_filter.h b/lib/csapi/definitions/event_filter.h index 5a1a831b..b8b2a983 100644 --- a/lib/csapi/definitions/event_filter.h +++ b/lib/csapi/definitions/event_filter.h @@ -4,36 +4,39 @@ #pragma once + + #include "converters.h" #include "converters.h" -namespace QMatrixClient { - // Data structures - - struct EventFilter { - /// The maximum number of events to return. - Omittable<int> limit; - /// A list of sender IDs to exclude. If this list is absent then no - /// senders are excluded. A matching sender will be excluded even if it - /// is listed in the ``'senders'`` filter. - QStringList notSenders; - /// A list of event types to exclude. If this list is absent then no - /// event types are excluded. A matching type will be excluded even if - /// it is listed in the ``'types'`` filter. A '*' can be used as a - /// wildcard to match any sequence of characters. - QStringList notTypes; - /// A list of senders IDs to include. If this list is absent then all - /// senders are included. - QStringList senders; - /// A list of event types to include. If this list is absent then all - /// event types are included. A ``'*'`` can be used as a wildcard to - /// match any sequence of characters. - QStringList types; - }; - template <> struct JsonObjectConverter<EventFilter> { - static void dumpTo(QJsonObject& jo, const EventFilter& pod); - static void fillFrom(const QJsonObject& jo, EventFilter& pod); - }; +namespace QMatrixClient +{ + +// Data structures + + +struct EventFilter +{ + /// The maximum number of events to return. + Omittable<int> limit; + /// A list of sender IDs to exclude. If this list is absent then no senders are excluded. A matching sender will be excluded even if it is listed in the ``'senders'`` filter. + QStringList notSenders; + /// A list of event types to exclude. If this list is absent then no event types are excluded. A matching type will be excluded even if it is listed in the ``'types'`` filter. A '*' can be used as a wildcard to match any sequence of characters. + QStringList notTypes; + /// A list of senders IDs to include. If this list is absent then all senders are included. + QStringList senders; + /// A list of event types to include. If this list is absent then all event types are included. A ``'*'`` can be used as a wildcard to match any sequence of characters. + QStringList types; + + +}; + +template <> struct JsonObjectConverter<EventFilter> +{ + static void dumpTo(QJsonObject& jo, const EventFilter& pod); + static void fillFrom(const QJsonObject& jo, EventFilter& pod);}; + + } // namespace QMatrixClient diff --git a/lib/csapi/definitions/public_rooms_response.cpp b/lib/csapi/definitions/public_rooms_response.cpp index 199a7a93..2c03b7d3 100644 --- a/lib/csapi/definitions/public_rooms_response.cpp +++ b/lib/csapi/definitions/public_rooms_response.cpp @@ -4,14 +4,14 @@ #include "public_rooms_response.h" + using namespace QMatrixClient; -void JsonObjectConverter<PublicRoomsChunk>::dumpTo(QJsonObject& jo, - const PublicRoomsChunk& pod) + +void JsonObjectConverter<PublicRoomsChunk>::dumpTo(QJsonObject& jo, const PublicRoomsChunk& pod) { addParam<IfNotEmpty>(jo, QStringLiteral("aliases"), pod.aliases); - addParam<IfNotEmpty>(jo, QStringLiteral("canonical_alias"), - pod.canonicalAlias); + addParam<IfNotEmpty>(jo, QStringLiteral("canonical_alias"), pod.canonicalAlias); addParam<IfNotEmpty>(jo, QStringLiteral("name"), pod.name); addParam<>(jo, QStringLiteral("num_joined_members"), pod.numJoinedMembers); addParam<>(jo, QStringLiteral("room_id"), pod.roomId); @@ -19,10 +19,10 @@ void JsonObjectConverter<PublicRoomsChunk>::dumpTo(QJsonObject& jo, addParam<>(jo, QStringLiteral("world_readable"), pod.worldReadable); addParam<>(jo, QStringLiteral("guest_can_join"), pod.guestCanJoin); addParam<IfNotEmpty>(jo, QStringLiteral("avatar_url"), pod.avatarUrl); -} -void JsonObjectConverter<PublicRoomsChunk>::fillFrom(const QJsonObject& jo, - PublicRoomsChunk& result) +} + +void JsonObjectConverter<PublicRoomsChunk>::fillFrom(const QJsonObject& jo, PublicRoomsChunk& result) { fromJson(jo.value("aliases"_ls), result.aliases); fromJson(jo.value("canonical_alias"_ls), result.canonicalAlias); @@ -33,24 +33,28 @@ void JsonObjectConverter<PublicRoomsChunk>::fillFrom(const QJsonObject& jo, fromJson(jo.value("world_readable"_ls), result.worldReadable); fromJson(jo.value("guest_can_join"_ls), result.guestCanJoin); fromJson(jo.value("avatar_url"_ls), result.avatarUrl); + } + -void JsonObjectConverter<PublicRoomsResponse>::dumpTo( - QJsonObject& jo, const PublicRoomsResponse& pod) + +void JsonObjectConverter<PublicRoomsResponse>::dumpTo(QJsonObject& jo, const PublicRoomsResponse& pod) { addParam<>(jo, QStringLiteral("chunk"), pod.chunk); addParam<IfNotEmpty>(jo, QStringLiteral("next_batch"), pod.nextBatch); addParam<IfNotEmpty>(jo, QStringLiteral("prev_batch"), pod.prevBatch); - addParam<IfNotEmpty>(jo, QStringLiteral("total_room_count_estimate"), - pod.totalRoomCountEstimate); -} + addParam<IfNotEmpty>(jo, QStringLiteral("total_room_count_estimate"), pod.totalRoomCountEstimate); -void JsonObjectConverter<PublicRoomsResponse>::fillFrom( - const QJsonObject& jo, PublicRoomsResponse& result) +} + +void JsonObjectConverter<PublicRoomsResponse>::fillFrom(const QJsonObject& jo, PublicRoomsResponse& result) { fromJson(jo.value("chunk"_ls), result.chunk); fromJson(jo.value("next_batch"_ls), result.nextBatch); fromJson(jo.value("prev_batch"_ls), result.prevBatch); - fromJson(jo.value("total_room_count_estimate"_ls), - result.totalRoomCountEstimate); + fromJson(jo.value("total_room_count_estimate"_ls), result.totalRoomCountEstimate); + } + + + diff --git a/lib/csapi/definitions/public_rooms_response.h b/lib/csapi/definitions/public_rooms_response.h index 6d8caf98..d282a592 100644 --- a/lib/csapi/definitions/public_rooms_response.h +++ b/lib/csapi/definitions/public_rooms_response.h @@ -4,60 +4,68 @@ #pragma once + + #include "converters.h" #include "converters.h" #include <QtCore/QVector> -namespace QMatrixClient { - // Data structures - - struct PublicRoomsChunk { - /// Aliases of the room. May be empty. - QStringList aliases; - /// The canonical alias of the room, if any. - QString canonicalAlias; - /// The name of the room, if any. - QString name; - /// The number of members joined to the room. - int numJoinedMembers; - /// The ID of the room. - QString roomId; - /// The topic of the room, if any. - QString topic; - /// Whether the room may be viewed by guest users without joining. - bool worldReadable; - /// Whether guest users may join the room and participate in it. - /// If they can, they will be subject to ordinary power level - /// rules like any other user. - bool guestCanJoin; - /// The URL for the room's avatar, if one is set. - QString avatarUrl; - }; - template <> struct JsonObjectConverter<PublicRoomsChunk> { - static void dumpTo(QJsonObject& jo, const PublicRoomsChunk& pod); - static void fillFrom(const QJsonObject& jo, PublicRoomsChunk& pod); - }; - - /// A list of the rooms on the server. - struct PublicRoomsResponse { - /// A paginated chunk of public rooms. - QVector<PublicRoomsChunk> chunk; - /// A pagination token for the response. The absence of this token - /// means there are no more results to fetch and the client should - /// stop paginating. - QString nextBatch; - /// A pagination token that allows fetching previous results. The - /// absence of this token means there are no results before this - /// batch, i.e. this is the first batch. - QString prevBatch; - /// An estimate on the total number of public rooms, if the - /// server has an estimate. - Omittable<int> totalRoomCountEstimate; - }; - template <> struct JsonObjectConverter<PublicRoomsResponse> { - static void dumpTo(QJsonObject& jo, const PublicRoomsResponse& pod); - static void fillFrom(const QJsonObject& jo, PublicRoomsResponse& pod); - }; +namespace QMatrixClient +{ + +// Data structures + + +struct PublicRoomsChunk +{ + /// Aliases of the room. May be empty. + QStringList aliases; + /// The canonical alias of the room, if any. + QString canonicalAlias; + /// The name of the room, if any. + QString name; + /// The number of members joined to the room. + int numJoinedMembers; + /// The ID of the room. + QString roomId; + /// The topic of the room, if any. + QString topic; + /// Whether the room may be viewed by guest users without joining. + bool worldReadable; + /// Whether guest users may join the room and participate in it.If they can, they will be subject to ordinary power levelrules like any other user. + bool guestCanJoin; + /// The URL for the room's avatar, if one is set. + QString avatarUrl; + + +}; + +template <> struct JsonObjectConverter<PublicRoomsChunk> +{ + static void dumpTo(QJsonObject& jo, const PublicRoomsChunk& pod); + static void fillFrom(const QJsonObject& jo, PublicRoomsChunk& pod);}; + +/// A list of the rooms on the server. +struct PublicRoomsResponse +{ + /// A paginated chunk of public rooms. + QVector<PublicRoomsChunk> chunk; + /// A pagination token for the response. The absence of this tokenmeans there are no more results to fetch and the client shouldstop paginating. + QString nextBatch; + /// A pagination token that allows fetching previous results. Theabsence of this token means there are no results before thisbatch, i.e. this is the first batch. + QString prevBatch; + /// An estimate on the total number of public rooms, if theserver has an estimate. + Omittable<int> totalRoomCountEstimate; + + +}; + +template <> struct JsonObjectConverter<PublicRoomsResponse> +{ + static void dumpTo(QJsonObject& jo, const PublicRoomsResponse& pod); + static void fillFrom(const QJsonObject& jo, PublicRoomsResponse& pod);}; + + } // namespace QMatrixClient diff --git a/lib/csapi/definitions/push_condition.cpp b/lib/csapi/definitions/push_condition.cpp index 5bcb845e..86b3107e 100644 --- a/lib/csapi/definitions/push_condition.cpp +++ b/lib/csapi/definitions/push_condition.cpp @@ -4,22 +4,27 @@ #include "push_condition.h" + using namespace QMatrixClient; -void JsonObjectConverter<PushCondition>::dumpTo(QJsonObject& jo, - const PushCondition& pod) + +void JsonObjectConverter<PushCondition>::dumpTo(QJsonObject& jo, const PushCondition& pod) { addParam<>(jo, QStringLiteral("kind"), pod.kind); addParam<IfNotEmpty>(jo, QStringLiteral("key"), pod.key); addParam<IfNotEmpty>(jo, QStringLiteral("pattern"), pod.pattern); addParam<IfNotEmpty>(jo, QStringLiteral("is"), pod.is); -} -void JsonObjectConverter<PushCondition>::fillFrom(const QJsonObject& jo, - PushCondition& result) +} + +void JsonObjectConverter<PushCondition>::fillFrom(const QJsonObject& jo, PushCondition& result) { fromJson(jo.value("kind"_ls), result.kind); fromJson(jo.value("key"_ls), result.key); fromJson(jo.value("pattern"_ls), result.pattern); fromJson(jo.value("is"_ls), result.is); + } + + + diff --git a/lib/csapi/definitions/push_condition.h b/lib/csapi/definitions/push_condition.h index a4e44e93..e61fb24e 100644 --- a/lib/csapi/definitions/push_condition.h +++ b/lib/csapi/definitions/push_condition.h @@ -4,31 +4,36 @@ #pragma once + + #include "converters.h" -namespace QMatrixClient { - // Data structures - - struct PushCondition { - QString kind; - /// Required for ``event_match`` conditions. The dot-separated field of - /// the event to match. - QString key; - /// Required for ``event_match`` conditions. The glob-style pattern to - /// match against. Patterns with no special glob characters should be - /// treated as having asterisks prepended and appended when testing the - /// condition. - QString pattern; - /// Required for ``room_member_count`` conditions. A decimal integer - /// optionally prefixed by one of, ==, <, >, >= or <=. A prefix of < - /// matches rooms where the member count is strictly less than the given - /// number and so forth. If no prefix is present, this parameter - /// defaults to ==. - QString is; - }; - template <> struct JsonObjectConverter<PushCondition> { - static void dumpTo(QJsonObject& jo, const PushCondition& pod); - static void fillFrom(const QJsonObject& jo, PushCondition& pod); - }; + +namespace QMatrixClient +{ + +// Data structures + + +struct PushCondition +{ + + QString kind; + /// Required for ``event_match`` conditions. The dot-separated field of theevent to match. + QString key; + /// Required for ``event_match`` conditions. The glob-style pattern tomatch against. Patterns with no special glob characters should betreated as having asterisks prepended and appended when testing thecondition. + QString pattern; + /// Required for ``room_member_count`` conditions. A decimal integeroptionally prefixed by one of, ==, <, >, >= or <=. A prefix of < matchesrooms where the member count is strictly less than the given number andso forth. If no prefix is present, this parameter defaults to ==. + QString is; + + +}; + +template <> struct JsonObjectConverter<PushCondition> +{ + static void dumpTo(QJsonObject& jo, const PushCondition& pod); + static void fillFrom(const QJsonObject& jo, PushCondition& pod);}; + + } // namespace QMatrixClient diff --git a/lib/csapi/definitions/push_rule.cpp b/lib/csapi/definitions/push_rule.cpp index fc2be2c7..bfa8a7ef 100644 --- a/lib/csapi/definitions/push_rule.cpp +++ b/lib/csapi/definitions/push_rule.cpp @@ -4,8 +4,10 @@ #include "push_rule.h" + using namespace QMatrixClient; + void JsonObjectConverter<PushRule>::dumpTo(QJsonObject& jo, const PushRule& pod) { addParam<>(jo, QStringLiteral("actions"), pod.actions); @@ -14,10 +16,10 @@ void JsonObjectConverter<PushRule>::dumpTo(QJsonObject& jo, const PushRule& pod) addParam<>(jo, QStringLiteral("rule_id"), pod.ruleId); addParam<IfNotEmpty>(jo, QStringLiteral("conditions"), pod.conditions); addParam<IfNotEmpty>(jo, QStringLiteral("pattern"), pod.pattern); -} -void JsonObjectConverter<PushRule>::fillFrom(const QJsonObject& jo, - PushRule& result) +} + +void JsonObjectConverter<PushRule>::fillFrom(const QJsonObject& jo, PushRule& result) { fromJson(jo.value("actions"_ls), result.actions); fromJson(jo.value("default"_ls), result.isDefault); @@ -25,4 +27,8 @@ void JsonObjectConverter<PushRule>::fillFrom(const QJsonObject& jo, fromJson(jo.value("rule_id"_ls), result.ruleId); fromJson(jo.value("conditions"_ls), result.conditions); fromJson(jo.value("pattern"_ls), result.pattern); + } + + + diff --git a/lib/csapi/definitions/push_rule.h b/lib/csapi/definitions/push_rule.h index d8d2cc0f..98bd904d 100644 --- a/lib/csapi/definitions/push_rule.h +++ b/lib/csapi/definitions/push_rule.h @@ -4,37 +4,45 @@ #pragma once + + #include "converters.h" #include "converters.h" +#include <QtCore/QVariant> #include "csapi/definitions/push_condition.h" #include <QtCore/QJsonObject> -#include <QtCore/QVariant> #include <QtCore/QVector> -namespace QMatrixClient { - // Data structures - - struct PushRule { - /// The actions to perform when this rule is matched. - QVector<QVariant> actions; - /// Whether this is a default rule, or has been set explicitly. - bool isDefault; - /// Whether the push rule is enabled or not. - bool enabled; - /// The ID of this rule. - QString ruleId; - /// The conditions that must hold true for an event in order for a rule - /// to be applied to an event. A rule with no conditions always matches. - /// Only applicable to ``underride`` and ``override`` rules. - QVector<PushCondition> conditions; - /// The glob-style pattern to match against. Only applicable to - /// ``content`` rules. - QString pattern; - }; - template <> struct JsonObjectConverter<PushRule> { - static void dumpTo(QJsonObject& jo, const PushRule& pod); - static void fillFrom(const QJsonObject& jo, PushRule& pod); - }; +namespace QMatrixClient +{ + +// Data structures + + +struct PushRule +{ + /// The actions to perform when this rule is matched. + QVector<QVariant> actions; + /// Whether this is a default rule, or has been set explicitly. + bool isDefault; + /// Whether the push rule is enabled or not. + bool enabled; + /// The ID of this rule. + QString ruleId; + /// The conditions that must hold true for an event in order for a rule to beapplied to an event. A rule with no conditions always matches. Onlyapplicable to ``underride`` and ``override`` rules. + QVector<PushCondition> conditions; + /// The glob-style pattern to match against. Only applicable to ``content``rules. + QString pattern; + + +}; + +template <> struct JsonObjectConverter<PushRule> +{ + static void dumpTo(QJsonObject& jo, const PushRule& pod); + static void fillFrom(const QJsonObject& jo, PushRule& pod);}; + + } // namespace QMatrixClient diff --git a/lib/csapi/definitions/push_ruleset.cpp b/lib/csapi/definitions/push_ruleset.cpp index 6f48d27b..4754e07b 100644 --- a/lib/csapi/definitions/push_ruleset.cpp +++ b/lib/csapi/definitions/push_ruleset.cpp @@ -4,24 +4,29 @@ #include "push_ruleset.h" + using namespace QMatrixClient; -void JsonObjectConverter<PushRuleset>::dumpTo(QJsonObject& jo, - const PushRuleset& pod) + +void JsonObjectConverter<PushRuleset>::dumpTo(QJsonObject& jo, const PushRuleset& pod) { addParam<IfNotEmpty>(jo, QStringLiteral("content"), pod.content); addParam<IfNotEmpty>(jo, QStringLiteral("override"), pod.override); addParam<IfNotEmpty>(jo, QStringLiteral("room"), pod.room); addParam<IfNotEmpty>(jo, QStringLiteral("sender"), pod.sender); addParam<IfNotEmpty>(jo, QStringLiteral("underride"), pod.underride); -} -void JsonObjectConverter<PushRuleset>::fillFrom(const QJsonObject& jo, - PushRuleset& result) +} + +void JsonObjectConverter<PushRuleset>::fillFrom(const QJsonObject& jo, PushRuleset& result) { fromJson(jo.value("content"_ls), result.content); fromJson(jo.value("override"_ls), result.override); fromJson(jo.value("room"_ls), result.room); fromJson(jo.value("sender"_ls), result.sender); fromJson(jo.value("underride"_ls), result.underride); + } + + + diff --git a/lib/csapi/definitions/push_ruleset.h b/lib/csapi/definitions/push_ruleset.h index b2f791c4..e1a2c142 100644 --- a/lib/csapi/definitions/push_ruleset.h +++ b/lib/csapi/definitions/push_ruleset.h @@ -4,25 +4,41 @@ #pragma once -#include "converters.h" + #include "converters.h" + #include "csapi/definitions/push_rule.h" +#include "converters.h" #include <QtCore/QVector> -namespace QMatrixClient { - // Data structures - - struct PushRuleset { - QVector<PushRule> content; - QVector<PushRule> override; - QVector<PushRule> room; - QVector<PushRule> sender; - QVector<PushRule> underride; - }; - template <> struct JsonObjectConverter<PushRuleset> { - static void dumpTo(QJsonObject& jo, const PushRuleset& pod); - static void fillFrom(const QJsonObject& jo, PushRuleset& pod); - }; +namespace QMatrixClient +{ + +// Data structures + + +struct PushRuleset +{ + + QVector<PushRule> content; + + QVector<PushRule> override; + + QVector<PushRule> room; + + QVector<PushRule> sender; + + QVector<PushRule> underride; + + +}; + +template <> struct JsonObjectConverter<PushRuleset> +{ + static void dumpTo(QJsonObject& jo, const PushRuleset& pod); + static void fillFrom(const QJsonObject& jo, PushRuleset& pod);}; + + } // namespace QMatrixClient diff --git a/lib/csapi/definitions/room_event_filter.cpp b/lib/csapi/definitions/room_event_filter.cpp index bd38ebc7..fc859395 100644 --- a/lib/csapi/definitions/room_event_filter.cpp +++ b/lib/csapi/definitions/room_event_filter.cpp @@ -4,22 +4,27 @@ #include "room_event_filter.h" + using namespace QMatrixClient; -void JsonObjectConverter<RoomEventFilter>::dumpTo(QJsonObject& jo, - const RoomEventFilter& pod) + +void JsonObjectConverter<RoomEventFilter>::dumpTo(QJsonObject& jo, const RoomEventFilter& pod) { fillJson<EventFilter>(jo, pod); addParam<IfNotEmpty>(jo, QStringLiteral("not_rooms"), pod.notRooms); addParam<IfNotEmpty>(jo, QStringLiteral("rooms"), pod.rooms); addParam<IfNotEmpty>(jo, QStringLiteral("contains_url"), pod.containsUrl); -} -void JsonObjectConverter<RoomEventFilter>::fillFrom(const QJsonObject& jo, - RoomEventFilter& result) +} + +void JsonObjectConverter<RoomEventFilter>::fillFrom(const QJsonObject& jo, RoomEventFilter& result) { fillFromJson<EventFilter>(jo, result); fromJson(jo.value("not_rooms"_ls), result.notRooms); fromJson(jo.value("rooms"_ls), result.rooms); fromJson(jo.value("contains_url"_ls), result.containsUrl); + } + + + diff --git a/lib/csapi/definitions/room_event_filter.h b/lib/csapi/definitions/room_event_filter.h index 13c82341..92e210fe 100644 --- a/lib/csapi/definitions/room_event_filter.h +++ b/lib/csapi/definitions/room_event_filter.h @@ -4,30 +4,36 @@ #pragma once -#include "converters.h" + #include "converters.h" + #include "csapi/definitions/event_filter.h" +#include "converters.h" + +namespace QMatrixClient +{ + +// Data structures + + +struct RoomEventFilter : EventFilter +{ + /// A list of room IDs to exclude. If this list is absent then no rooms are excluded. A matching room will be excluded even if it is listed in the ``'rooms'`` filter. + QStringList notRooms; + /// A list of room IDs to include. If this list is absent then all rooms are included. + QStringList rooms; + /// If ``true``, includes only events with a ``url`` key in their content. If ``false``, excludes those events. If omitted, ``url`` key is not considered for filtering. + Omittable<bool> containsUrl; + + +}; + +template <> struct JsonObjectConverter<RoomEventFilter> +{ + static void dumpTo(QJsonObject& jo, const RoomEventFilter& pod); + static void fillFrom(const QJsonObject& jo, RoomEventFilter& pod);}; + -namespace QMatrixClient { - // Data structures - - struct RoomEventFilter : EventFilter { - /// A list of room IDs to exclude. If this list is absent then no rooms - /// are excluded. A matching room will be excluded even if it is listed - /// in the ``'rooms'`` filter. - QStringList notRooms; - /// A list of room IDs to include. If this list is absent then all rooms - /// are included. - QStringList rooms; - /// If ``true``, includes only events with a ``url`` key in their - /// content. If ``false``, excludes those events. If omitted, ``url`` - /// key is not considered for filtering. - Omittable<bool> containsUrl; - }; - template <> struct JsonObjectConverter<RoomEventFilter> { - static void dumpTo(QJsonObject& jo, const RoomEventFilter& pod); - static void fillFrom(const QJsonObject& jo, RoomEventFilter& pod); - }; } // namespace QMatrixClient diff --git a/lib/csapi/definitions/sync_filter.cpp b/lib/csapi/definitions/sync_filter.cpp index c06c16ca..a1ef53c5 100644 --- a/lib/csapi/definitions/sync_filter.cpp +++ b/lib/csapi/definitions/sync_filter.cpp @@ -4,29 +4,29 @@ #include "sync_filter.h" + using namespace QMatrixClient; -void JsonObjectConverter<StateFilter>::dumpTo(QJsonObject& jo, - const StateFilter& pod) + +void JsonObjectConverter<StateFilter>::dumpTo(QJsonObject& jo, const StateFilter& pod) { fillJson<RoomEventFilter>(jo, pod); - addParam<IfNotEmpty>(jo, QStringLiteral("lazy_load_members"), - pod.lazyLoadMembers); - addParam<IfNotEmpty>(jo, QStringLiteral("include_redundant_members"), - pod.includeRedundantMembers); -} + addParam<IfNotEmpty>(jo, QStringLiteral("lazy_load_members"), pod.lazyLoadMembers); + addParam<IfNotEmpty>(jo, QStringLiteral("include_redundant_members"), pod.includeRedundantMembers); -void JsonObjectConverter<StateFilter>::fillFrom(const QJsonObject& jo, - StateFilter& result) +} + +void JsonObjectConverter<StateFilter>::fillFrom(const QJsonObject& jo, StateFilter& result) { fillFromJson<RoomEventFilter>(jo, result); fromJson(jo.value("lazy_load_members"_ls), result.lazyLoadMembers); - fromJson(jo.value("include_redundant_members"_ls), - result.includeRedundantMembers); + fromJson(jo.value("include_redundant_members"_ls), result.includeRedundantMembers); + } + -void JsonObjectConverter<RoomFilter>::dumpTo(QJsonObject& jo, - const RoomFilter& pod) + +void JsonObjectConverter<RoomFilter>::dumpTo(QJsonObject& jo, const RoomFilter& pod) { addParam<IfNotEmpty>(jo, QStringLiteral("not_rooms"), pod.notRooms); addParam<IfNotEmpty>(jo, QStringLiteral("rooms"), pod.rooms); @@ -35,10 +35,10 @@ void JsonObjectConverter<RoomFilter>::dumpTo(QJsonObject& jo, addParam<IfNotEmpty>(jo, QStringLiteral("state"), pod.state); addParam<IfNotEmpty>(jo, QStringLiteral("timeline"), pod.timeline); addParam<IfNotEmpty>(jo, QStringLiteral("account_data"), pod.accountData); -} -void JsonObjectConverter<RoomFilter>::fillFrom(const QJsonObject& jo, - RoomFilter& result) +} + +void JsonObjectConverter<RoomFilter>::fillFrom(const QJsonObject& jo, RoomFilter& result) { fromJson(jo.value("not_rooms"_ls), result.notRooms); fromJson(jo.value("rooms"_ls), result.rooms); @@ -47,8 +47,11 @@ void JsonObjectConverter<RoomFilter>::fillFrom(const QJsonObject& jo, fromJson(jo.value("state"_ls), result.state); fromJson(jo.value("timeline"_ls), result.timeline); fromJson(jo.value("account_data"_ls), result.accountData); + } + + void JsonObjectConverter<Filter>::dumpTo(QJsonObject& jo, const Filter& pod) { addParam<IfNotEmpty>(jo, QStringLiteral("event_fields"), pod.eventFields); @@ -56,14 +59,18 @@ void JsonObjectConverter<Filter>::dumpTo(QJsonObject& jo, const Filter& pod) addParam<IfNotEmpty>(jo, QStringLiteral("presence"), pod.presence); addParam<IfNotEmpty>(jo, QStringLiteral("account_data"), pod.accountData); addParam<IfNotEmpty>(jo, QStringLiteral("room"), pod.room); -} -void JsonObjectConverter<Filter>::fillFrom(const QJsonObject& jo, - Filter& result) +} + +void JsonObjectConverter<Filter>::fillFrom(const QJsonObject& jo, Filter& result) { fromJson(jo.value("event_fields"_ls), result.eventFields); fromJson(jo.value("event_format"_ls), result.eventFormat); fromJson(jo.value("presence"_ls), result.presence); fromJson(jo.value("account_data"_ls), result.accountData); fromJson(jo.value("room"_ls), result.room); + } + + + diff --git a/lib/csapi/definitions/sync_filter.h b/lib/csapi/definitions/sync_filter.h index d523c388..551ba2fd 100644 --- a/lib/csapi/definitions/sync_filter.h +++ b/lib/csapi/definitions/sync_filter.h @@ -4,94 +4,83 @@ #pragma once -#include "converters.h" + #include "converters.h" + #include "csapi/definitions/event_filter.h" +#include "converters.h" #include "csapi/definitions/room_event_filter.h" -namespace QMatrixClient { - // Data structures +namespace QMatrixClient +{ + +// Data structures + +/// The state events to include for rooms. +struct StateFilter : RoomEventFilter +{ + /// If ``true``, the only ``m.room.member`` events returned inthe ``state`` section of the ``/sync`` response are thosewhich are definitely necessary for a client to displaythe ``sender`` of the timeline events in that response.If ``false``, ``m.room.member`` events are not filtered.By default, servers should suppress duplicate redundantlazy-loaded ``m.room.member`` events from being sent to a givenclient across multiple calls to ``/sync``, given that most clientscache membership events (see ``include_redundant_members``to change this behaviour). + Omittable<bool> lazyLoadMembers; + /// If ``true``, the ``state`` section of the ``/sync`` response willalways contain the ``m.room.member`` events required to displaythe ``sender`` of the timeline events in that response, assuming``lazy_load_members`` is enabled. This means that redundantduplicate member events may be returned across multiple calls to``/sync``. This is useful for naive clients who never trackmembership data. If ``false``, duplicate ``m.room.member`` eventsmay be suppressed by the server across multiple calls to ``/sync``.If ``lazy_load_members`` is ``false`` this field is ignored. + Omittable<bool> includeRedundantMembers; + + +}; + +template <> struct JsonObjectConverter<StateFilter> +{ + static void dumpTo(QJsonObject& jo, const StateFilter& pod); + static void fillFrom(const QJsonObject& jo, StateFilter& pod);}; +/// Filters to be applied to room data. +struct RoomFilter +{ + /// A list of room IDs to exclude. If this list is absent then no rooms are excluded. A matching room will be excluded even if it is listed in the ``'rooms'`` filter. This filter is applied before the filters in ``ephemeral``, ``state``, ``timeline`` or ``account_data`` + QStringList notRooms; + /// A list of room IDs to include. If this list is absent then all rooms are included. This filter is applied before the filters in ``ephemeral``, ``state``, ``timeline`` or ``account_data`` + QStringList rooms; + /// The events that aren't recorded in the room history, e.g. typing and receipts, to include for rooms. + Omittable<RoomEventFilter> ephemeral; + /// Include rooms that the user has left in the sync, default false + Omittable<bool> includeLeave; /// The state events to include for rooms. - struct StateFilter : RoomEventFilter { - /// If ``true``, the only ``m.room.member`` events returned in - /// the ``state`` section of the ``/sync`` response are those - /// which are definitely necessary for a client to display - /// the ``sender`` of the timeline events in that response. - /// If ``false``, ``m.room.member`` events are not filtered. - /// By default, servers should suppress duplicate redundant - /// lazy-loaded ``m.room.member`` events from being sent to a given - /// client across multiple calls to ``/sync``, given that most clients - /// cache membership events (see ``include_redundant_members`` - /// to change this behaviour). - Omittable<bool> lazyLoadMembers; - /// If ``true``, the ``state`` section of the ``/sync`` response will - /// always contain the ``m.room.member`` events required to display - /// the ``sender`` of the timeline events in that response, assuming - /// ``lazy_load_members`` is enabled. This means that redundant - /// duplicate member events may be returned across multiple calls to - /// ``/sync``. This is useful for naive clients who never track - /// membership data. If ``false``, duplicate ``m.room.member`` events - /// may be suppressed by the server across multiple calls to ``/sync``. - /// If ``lazy_load_members`` is ``false`` this field is ignored. - Omittable<bool> includeRedundantMembers; - }; - template <> struct JsonObjectConverter<StateFilter> { - static void dumpTo(QJsonObject& jo, const StateFilter& pod); - static void fillFrom(const QJsonObject& jo, StateFilter& pod); - }; + Omittable<StateFilter> state; + /// The message and state update events to include for rooms. + Omittable<RoomEventFilter> timeline; + /// The per user account data to include for rooms. + Omittable<RoomEventFilter> accountData; + +}; + +template <> struct JsonObjectConverter<RoomFilter> +{ + static void dumpTo(QJsonObject& jo, const RoomFilter& pod); + static void fillFrom(const QJsonObject& jo, RoomFilter& pod);}; + + +struct Filter +{ + /// List of event fields to include. If this list is absent then all fields are included. The entries may include '.' charaters to indicate sub-fields. So ['content.body'] will include the 'body' field of the 'content' object. A literal '.' character in a field name may be escaped using a '\\'. A server may include more fields than were requested. + QStringList eventFields; + /// The format to use for events. 'client' will return the events in a format suitable for clients. 'federation' will return the raw event as receieved over federation. The default is 'client'. + QString eventFormat; + /// The presence updates to include. + Omittable<EventFilter> presence; + /// The user account data that isn't associated with rooms to include. + Omittable<EventFilter> accountData; /// Filters to be applied to room data. - struct RoomFilter { - /// A list of room IDs to exclude. If this list is absent then no rooms - /// are excluded. A matching room will be excluded even if it is listed - /// in the ``'rooms'`` filter. This filter is applied before the filters - /// in ``ephemeral``, ``state``, ``timeline`` or ``account_data`` - QStringList notRooms; - /// A list of room IDs to include. If this list is absent then all rooms - /// are included. This filter is applied before the filters in - /// ``ephemeral``, ``state``, ``timeline`` or ``account_data`` - QStringList rooms; - /// The events that aren't recorded in the room history, e.g. typing and - /// receipts, to include for rooms. - Omittable<RoomEventFilter> ephemeral; - /// Include rooms that the user has left in the sync, default false - Omittable<bool> includeLeave; - /// The state events to include for rooms. - Omittable<StateFilter> state; - /// The message and state update events to include for rooms. - Omittable<RoomEventFilter> timeline; - /// The per user account data to include for rooms. - Omittable<RoomEventFilter> accountData; - }; - template <> struct JsonObjectConverter<RoomFilter> { - static void dumpTo(QJsonObject& jo, const RoomFilter& pod); - static void fillFrom(const QJsonObject& jo, RoomFilter& pod); - }; - - struct Filter { - /// List of event fields to include. If this list is absent then all - /// fields are included. The entries may include '.' charaters to - /// indicate sub-fields. So ['content.body'] will include the 'body' - /// field of the 'content' object. A literal '.' character in a field - /// name may be escaped using a '\\'. A server may include more fields - /// than were requested. - QStringList eventFields; - /// The format to use for events. 'client' will return the events in a - /// format suitable for clients. 'federation' will return the raw event - /// as receieved over federation. The default is 'client'. - QString eventFormat; - /// The presence updates to include. - Omittable<EventFilter> presence; - /// The user account data that isn't associated with rooms to include. - Omittable<EventFilter> accountData; - /// Filters to be applied to room data. - Omittable<RoomFilter> room; - }; - template <> struct JsonObjectConverter<Filter> { - static void dumpTo(QJsonObject& jo, const Filter& pod); - static void fillFrom(const QJsonObject& jo, Filter& pod); - }; + Omittable<RoomFilter> room; + + +}; + +template <> struct JsonObjectConverter<Filter> +{ + static void dumpTo(QJsonObject& jo, const Filter& pod); + static void fillFrom(const QJsonObject& jo, Filter& pod);}; + + } // namespace QMatrixClient diff --git a/lib/csapi/definitions/user_identifier.cpp b/lib/csapi/definitions/user_identifier.cpp index 998f1b85..02201179 100644 --- a/lib/csapi/definitions/user_identifier.cpp +++ b/lib/csapi/definitions/user_identifier.cpp @@ -4,19 +4,23 @@ #include "user_identifier.h" + using namespace QMatrixClient; -void JsonObjectConverter<UserIdentifier>::dumpTo(QJsonObject& jo, - const UserIdentifier& pod) + +void JsonObjectConverter<UserIdentifier>::dumpTo(QJsonObject& jo, const UserIdentifier& pod) { fillJson(jo, pod.additionalProperties); addParam<>(jo, QStringLiteral("type"), pod.type); -} -void JsonObjectConverter<UserIdentifier>::fillFrom(QJsonObject jo, - UserIdentifier& result) +} + +void JsonObjectConverter<UserIdentifier>::fillFrom(QJsonObject jo, UserIdentifier& result) { fromJson(jo.take("type"_ls), result.type); - fromJson(jo, result.additionalProperties); + } + + + diff --git a/lib/csapi/definitions/user_identifier.h b/lib/csapi/definitions/user_identifier.h index 4a9ce684..831ba191 100644 --- a/lib/csapi/definitions/user_identifier.h +++ b/lib/csapi/definitions/user_identifier.h @@ -4,24 +4,34 @@ #pragma once + + #include "converters.h" #include <QtCore/QVariant> -namespace QMatrixClient { - // Data structures +namespace QMatrixClient +{ + +// Data structures + +/// Identification information for a user +struct UserIdentifier +{ + /// The type of identification. See `Identifier types`_ for supported values and additional property descriptions. + QString type; + /// Identification information for a user - struct UserIdentifier { - /// The type of identification. See `Identifier types`_ for supported - /// values and additional property descriptions. - QString type; - /// Identification information for a user - QVariantHash additionalProperties; - }; - template <> struct JsonObjectConverter<UserIdentifier> { - static void dumpTo(QJsonObject& jo, const UserIdentifier& pod); - static void fillFrom(QJsonObject jo, UserIdentifier& pod); - }; + QVariantHash additionalProperties; + +}; + +template <> struct JsonObjectConverter<UserIdentifier> +{ + static void dumpTo(QJsonObject& jo, const UserIdentifier& pod); + static void fillFrom(QJsonObject jo, UserIdentifier& pod);}; + + } // namespace QMatrixClient diff --git a/lib/csapi/definitions/wellknown/full.cpp b/lib/csapi/definitions/wellknown/full.cpp index 35c0df5b..a2d71db0 100644 --- a/lib/csapi/definitions/wellknown/full.cpp +++ b/lib/csapi/definitions/wellknown/full.cpp @@ -4,22 +4,25 @@ #include "full.h" + using namespace QMatrixClient; -void JsonObjectConverter<DiscoveryInformation>::dumpTo( - QJsonObject& jo, const DiscoveryInformation& pod) + +void JsonObjectConverter<DiscoveryInformation>::dumpTo(QJsonObject& jo, const DiscoveryInformation& pod) { fillJson(jo, pod.additionalProperties); addParam<>(jo, QStringLiteral("m.homeserver"), pod.homeserver); - addParam<IfNotEmpty>(jo, QStringLiteral("m.identity_server"), - pod.identityServer); -} + addParam<IfNotEmpty>(jo, QStringLiteral("m.identity_server"), pod.identityServer); -void JsonObjectConverter<DiscoveryInformation>::fillFrom( - QJsonObject jo, DiscoveryInformation& result) +} + +void JsonObjectConverter<DiscoveryInformation>::fillFrom(QJsonObject jo, DiscoveryInformation& result) { fromJson(jo.take("m.homeserver"_ls), result.homeserver); fromJson(jo.take("m.identity_server"_ls), result.identityServer); - fromJson(jo, result.additionalProperties); + } + + + diff --git a/lib/csapi/definitions/wellknown/full.h b/lib/csapi/definitions/wellknown/full.h index 9b920eda..ef975969 100644 --- a/lib/csapi/definitions/wellknown/full.h +++ b/lib/csapi/definitions/wellknown/full.h @@ -4,32 +4,40 @@ #pragma once + + #include "converters.h" +#include <QtCore/QJsonObject> #include "converters.h" #include "csapi/definitions/wellknown/homeserver.h" #include "csapi/definitions/wellknown/identity_server.h" #include <QtCore/QHash> -#include <QtCore/QJsonObject> -namespace QMatrixClient { - // Data structures - - /// Used by clients to determine the homeserver, identity server, and other - /// optional components they should be interacting with. - struct DiscoveryInformation { - /// Used by clients to determine the homeserver, identity server, and - /// other optional components they should be interacting with. - HomeserverInformation homeserver; - /// Used by clients to determine the homeserver, identity server, and - /// other optional components they should be interacting with. - Omittable<IdentityServerInformation> identityServer; - /// Application-dependent keys using Java package naming convention. - QHash<QString, QJsonObject> additionalProperties; - }; - template <> struct JsonObjectConverter<DiscoveryInformation> { - static void dumpTo(QJsonObject& jo, const DiscoveryInformation& pod); - static void fillFrom(QJsonObject jo, DiscoveryInformation& pod); - }; +namespace QMatrixClient +{ + +// Data structures + +/// Used by clients to determine the homeserver, identity server, and other/// optional components they should be interacting with. +struct DiscoveryInformation +{ + /// Used by clients to determine the homeserver, identity server, and otheroptional components they should be interacting with. + HomeserverInformation homeserver; + /// Used by clients to determine the homeserver, identity server, and otheroptional components they should be interacting with. + Omittable<IdentityServerInformation> identityServer; + + + /// Application-dependent keys using Java package naming convention. + QHash<QString, QJsonObject> additionalProperties; + +}; + +template <> struct JsonObjectConverter<DiscoveryInformation> +{ + static void dumpTo(QJsonObject& jo, const DiscoveryInformation& pod); + static void fillFrom(QJsonObject jo, DiscoveryInformation& pod);}; + + } // namespace QMatrixClient diff --git a/lib/csapi/definitions/wellknown/homeserver.cpp b/lib/csapi/definitions/wellknown/homeserver.cpp index a7337520..a8a5077b 100644 --- a/lib/csapi/definitions/wellknown/homeserver.cpp +++ b/lib/csapi/definitions/wellknown/homeserver.cpp @@ -4,16 +4,21 @@ #include "homeserver.h" + using namespace QMatrixClient; -void JsonObjectConverter<HomeserverInformation>::dumpTo( - QJsonObject& jo, const HomeserverInformation& pod) + +void JsonObjectConverter<HomeserverInformation>::dumpTo(QJsonObject& jo, const HomeserverInformation& pod) { addParam<>(jo, QStringLiteral("base_url"), pod.baseUrl); -} -void JsonObjectConverter<HomeserverInformation>::fillFrom( - const QJsonObject& jo, HomeserverInformation& result) +} + +void JsonObjectConverter<HomeserverInformation>::fillFrom(const QJsonObject& jo, HomeserverInformation& result) { fromJson(jo.value("base_url"_ls), result.baseUrl); + } + + + diff --git a/lib/csapi/definitions/wellknown/homeserver.h b/lib/csapi/definitions/wellknown/homeserver.h index 8bd3c150..fe6af172 100644 --- a/lib/csapi/definitions/wellknown/homeserver.h +++ b/lib/csapi/definitions/wellknown/homeserver.h @@ -4,19 +4,30 @@ #pragma once + + #include "converters.h" -namespace QMatrixClient { - // Data structures - - /// Used by clients to discover homeserver information. - struct HomeserverInformation { - /// The base URL for the homeserver for client-server connections. - QString baseUrl; - }; - template <> struct JsonObjectConverter<HomeserverInformation> { - static void dumpTo(QJsonObject& jo, const HomeserverInformation& pod); - static void fillFrom(const QJsonObject& jo, HomeserverInformation& pod); - }; + +namespace QMatrixClient +{ + +// Data structures + +/// Used by clients to discover homeserver information. +struct HomeserverInformation +{ + /// The base URL for the homeserver for client-server connections. + QString baseUrl; + + +}; + +template <> struct JsonObjectConverter<HomeserverInformation> +{ + static void dumpTo(QJsonObject& jo, const HomeserverInformation& pod); + static void fillFrom(const QJsonObject& jo, HomeserverInformation& pod);}; + + } // namespace QMatrixClient diff --git a/lib/csapi/definitions/wellknown/identity_server.cpp b/lib/csapi/definitions/wellknown/identity_server.cpp index 46a614d8..a9fae614 100644 --- a/lib/csapi/definitions/wellknown/identity_server.cpp +++ b/lib/csapi/definitions/wellknown/identity_server.cpp @@ -4,16 +4,21 @@ #include "identity_server.h" + using namespace QMatrixClient; -void JsonObjectConverter<IdentityServerInformation>::dumpTo( - QJsonObject& jo, const IdentityServerInformation& pod) + +void JsonObjectConverter<IdentityServerInformation>::dumpTo(QJsonObject& jo, const IdentityServerInformation& pod) { addParam<>(jo, QStringLiteral("base_url"), pod.baseUrl); -} -void JsonObjectConverter<IdentityServerInformation>::fillFrom( - const QJsonObject& jo, IdentityServerInformation& result) +} + +void JsonObjectConverter<IdentityServerInformation>::fillFrom(const QJsonObject& jo, IdentityServerInformation& result) { fromJson(jo.value("base_url"_ls), result.baseUrl); + } + + + diff --git a/lib/csapi/definitions/wellknown/identity_server.h b/lib/csapi/definitions/wellknown/identity_server.h index fd53dfc1..4462f86e 100644 --- a/lib/csapi/definitions/wellknown/identity_server.h +++ b/lib/csapi/definitions/wellknown/identity_server.h @@ -4,21 +4,30 @@ #pragma once + + #include "converters.h" -namespace QMatrixClient { - // Data structures - - /// Used by clients to discover identity server information. - struct IdentityServerInformation { - /// The base URL for the identity server for client-server connections. - QString baseUrl; - }; - template <> struct JsonObjectConverter<IdentityServerInformation> { - static void dumpTo(QJsonObject& jo, - const IdentityServerInformation& pod); - static void fillFrom(const QJsonObject& jo, - IdentityServerInformation& pod); - }; + +namespace QMatrixClient +{ + +// Data structures + +/// Used by clients to discover identity server information. +struct IdentityServerInformation +{ + /// The base URL for the identity server for client-server connections. + QString baseUrl; + + +}; + +template <> struct JsonObjectConverter<IdentityServerInformation> +{ + static void dumpTo(QJsonObject& jo, const IdentityServerInformation& pod); + static void fillFrom(const QJsonObject& jo, IdentityServerInformation& pod);}; + + } // namespace QMatrixClient diff --git a/lib/csapi/device_management.cpp b/lib/csapi/device_management.cpp index 7d15bb2b..9135c22d 100644 --- a/lib/csapi/device_management.cpp +++ b/lib/csapi/device_management.cpp @@ -14,7 +14,7 @@ static const auto basePath = QStringLiteral("/_matrix/client/r0"); class GetDevicesJob::Private { - public: +public: QVector<Device> devices; }; @@ -26,10 +26,9 @@ QUrl GetDevicesJob::makeRequestUrl(QUrl baseUrl) static const auto GetDevicesJobName = QStringLiteral("GetDevicesJob"); GetDevicesJob::GetDevicesJob() - : BaseJob(HttpVerb::Get, GetDevicesJobName, basePath % "/devices"), - d(new Private) -{ -} + : BaseJob(HttpVerb::Get, GetDevicesJobName, basePath % "/devices") + , d(new Private) +{} GetDevicesJob::~GetDevicesJob() = default; @@ -39,12 +38,13 @@ BaseJob::Status GetDevicesJob::parseJson(const QJsonDocument& data) { auto json = data.object(); fromJson(json.value("devices"_ls), d->devices); + return Success; } class GetDeviceJob::Private { - public: +public: Device data; }; @@ -57,11 +57,9 @@ QUrl GetDeviceJob::makeRequestUrl(QUrl baseUrl, const QString& deviceId) static const auto GetDeviceJobName = QStringLiteral("GetDeviceJob"); GetDeviceJob::GetDeviceJob(const QString& deviceId) - : BaseJob(HttpVerb::Get, GetDeviceJobName, - basePath % "/devices/" % deviceId), - d(new Private) -{ -} + : BaseJob(HttpVerb::Get, GetDeviceJobName, basePath % "/devices/" % deviceId) + , d(new Private) +{} GetDeviceJob::~GetDeviceJob() = default; @@ -101,8 +99,7 @@ static const auto DeleteDevicesJobName = QStringLiteral("DeleteDevicesJob"); DeleteDevicesJob::DeleteDevicesJob(const QStringList& devices, const Omittable<AuthenticationData>& auth) - : BaseJob(HttpVerb::Post, DeleteDevicesJobName, - basePath % "/delete_devices") + : BaseJob(HttpVerb::Post, DeleteDevicesJobName, basePath % "/delete_devices") { QJsonObject _data; addParam<>(_data, QStringLiteral("devices"), devices); diff --git a/lib/csapi/device_management.h b/lib/csapi/device_management.h index 628f26d2..01838c6f 100644 --- a/lib/csapi/device_management.h +++ b/lib/csapi/device_management.h @@ -4,138 +4,145 @@ #pragma once -#include "jobs/basejob.h" - #include "converters.h" + #include "csapi/definitions/auth_data.h" #include "csapi/definitions/client_device.h" + +#include "jobs/basejob.h" + #include <QtCore/QVector> -namespace QMatrixClient { - // Operations - - /// List registered devices for the current user - /// - /// Gets information about all devices for the current user. - class GetDevicesJob : public BaseJob - { - public: - explicit GetDevicesJob(); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetDevicesJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl); - - ~GetDevicesJob() override; - - // Result properties - - /// A list of all registered devices for this user. - const QVector<Device>& devices() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; - - /// Get a single device - /// - /// Gets information on a single device, by device id. - class GetDeviceJob : public BaseJob - { - public: - /*! Get a single device - * \param deviceId - * The device to retrieve. - */ - explicit GetDeviceJob(const QString& deviceId); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetDeviceJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& deviceId); - - ~GetDeviceJob() override; - - // Result properties - - /// Device information - const Device& data() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; - - /// Update a device - /// - /// Updates the metadata on the given device. - class UpdateDeviceJob : public BaseJob - { - public: - /*! Update a device - * \param deviceId - * The device to update. - * \param displayName - * The new display name for this device. If not given, the - * display name is unchanged. - */ - explicit UpdateDeviceJob(const QString& deviceId, - const QString& displayName = {}); - }; - - /// Delete a device - /// - /// This API endpoint uses the `User-Interactive Authentication API`_. - /// - /// Deletes the given device, and invalidates any access token associated - /// with it. - class DeleteDeviceJob : public BaseJob - { - public: - /*! Delete a device - * \param deviceId - * The device to delete. - * \param auth - * Additional authentication information for the - * user-interactive authentication API. - */ - explicit DeleteDeviceJob( - const QString& deviceId, - const Omittable<AuthenticationData>& auth = none); - }; - - /// Bulk deletion of devices - /// - /// This API endpoint uses the `User-Interactive Authentication API`_. - /// - /// Deletes the given devices, and invalidates any access token associated - /// with them. - class DeleteDevicesJob : public BaseJob - { - public: - /*! Bulk deletion of devices - * \param devices - * The list of device IDs to delete. - * \param auth - * Additional authentication information for the - * user-interactive authentication API. - */ - explicit DeleteDevicesJob( - const QStringList& devices, - const Omittable<AuthenticationData>& auth = none); - }; +namespace QMatrixClient +{ + +// Operations + +/// List registered devices for the current user +/*! + * Gets information about all devices for the current user. + */ +class GetDevicesJob : public BaseJob +{ +public: + explicit GetDevicesJob(); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetDevicesJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl); + + ~GetDevicesJob() override; + + // Result properties + + /// A list of all registered devices for this user. + const QVector<Device>& devices() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Get a single device +/*! + * Gets information on a single device, by device id. + */ +class GetDeviceJob : public BaseJob +{ +public: + /*! Get a single device + * \param deviceId + * The device to retrieve. + */ + explicit GetDeviceJob(const QString& deviceId); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetDeviceJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& deviceId); + + ~GetDeviceJob() override; + + // Result properties + + /// Device information + const Device& data() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Update a device +/*! + * Updates the metadata on the given device. + */ +class UpdateDeviceJob : public BaseJob +{ +public: + /*! Update a device + * \param deviceId + * The device to update. + * \param displayName + * The new display name for this device. If not given, the + * display name is unchanged. + */ + explicit UpdateDeviceJob(const QString& deviceId, + const QString& displayName = {}); +}; + +/// Delete a device +/*! + * This API endpoint uses the `User-Interactive Authentication API`_. + * + * Deletes the given device, and invalidates any access token associated with it. + */ +class DeleteDeviceJob : public BaseJob +{ +public: + /*! Delete a device + * \param deviceId + * The device to delete. + * \param auth + * Additional authentication information for the + * user-interactive authentication API. + */ + explicit DeleteDeviceJob(const QString& deviceId, + const Omittable<AuthenticationData>& auth = none); +}; + +/// Bulk deletion of devices +/*! + * This API endpoint uses the `User-Interactive Authentication API`_. + * + * Deletes the given devices, and invalidates any access token associated with + * them. + */ +class DeleteDevicesJob : public BaseJob +{ +public: + /*! Bulk deletion of devices + * \param devices + * The list of device IDs to delete. + * \param auth + * Additional authentication information for the + * user-interactive authentication API. + */ + explicit DeleteDevicesJob(const QStringList& devices, + const Omittable<AuthenticationData>& auth = none); +}; + } // namespace QMatrixClient diff --git a/lib/csapi/directory.cpp b/lib/csapi/directory.cpp index b4282ffb..992d1da5 100644 --- a/lib/csapi/directory.cpp +++ b/lib/csapi/directory.cpp @@ -14,8 +14,7 @@ static const auto basePath = QStringLiteral("/_matrix/client/r0/directory"); static const auto SetRoomAliasJobName = QStringLiteral("SetRoomAliasJob"); -SetRoomAliasJob::SetRoomAliasJob(const QString& roomAlias, - const QString& roomId) +SetRoomAliasJob::SetRoomAliasJob(const QString& roomAlias, const QString& roomId) : BaseJob(HttpVerb::Put, SetRoomAliasJobName, basePath % "/room/" % roomAlias) { @@ -26,7 +25,7 @@ SetRoomAliasJob::SetRoomAliasJob(const QString& roomAlias, class GetRoomIdByAliasJob::Private { - public: +public: QString roomId; QStringList servers; }; @@ -38,14 +37,13 @@ QUrl GetRoomIdByAliasJob::makeRequestUrl(QUrl baseUrl, const QString& roomAlias) } static const auto GetRoomIdByAliasJobName = - QStringLiteral("GetRoomIdByAliasJob"); + QStringLiteral("GetRoomIdByAliasJob"); GetRoomIdByAliasJob::GetRoomIdByAliasJob(const QString& roomAlias) : BaseJob(HttpVerb::Get, GetRoomIdByAliasJobName, - basePath % "/room/" % roomAlias, false), - d(new Private) -{ -} + basePath % "/room/" % roomAlias, false) + , d(new Private) +{} GetRoomIdByAliasJob::~GetRoomIdByAliasJob() = default; @@ -58,6 +56,7 @@ BaseJob::Status GetRoomIdByAliasJob::parseJson(const QJsonDocument& data) auto json = data.object(); fromJson(json.value("room_id"_ls), d->roomId); fromJson(json.value("servers"_ls), d->servers); + return Success; } @@ -72,5 +71,4 @@ static const auto DeleteRoomAliasJobName = QStringLiteral("DeleteRoomAliasJob"); DeleteRoomAliasJob::DeleteRoomAliasJob(const QString& roomAlias) : BaseJob(HttpVerb::Delete, DeleteRoomAliasJobName, basePath % "/room/" % roomAlias) -{ -} +{} diff --git a/lib/csapi/directory.h b/lib/csapi/directory.h index 6bf5ad14..f5331db8 100644 --- a/lib/csapi/directory.h +++ b/lib/csapi/directory.h @@ -6,86 +6,91 @@ #include "jobs/basejob.h" -namespace QMatrixClient { - // Operations - - /// Create a new mapping from room alias to room ID. - class SetRoomAliasJob : public BaseJob - { - public: - /*! Create a new mapping from room alias to room ID. - * \param roomAlias - * The room alias to set. - * \param roomId - * The room ID to set. - */ - explicit SetRoomAliasJob(const QString& roomAlias, - const QString& roomId); - }; - - /// Get the room ID corresponding to this room alias. - /// - /// Requests that the server resolve a room alias to a room ID. - /// - /// The server will use the federation API to resolve the alias if the - /// domain part of the alias does not correspond to the server's own - /// domain. - class GetRoomIdByAliasJob : public BaseJob - { - public: - /*! Get the room ID corresponding to this room alias. - * \param roomAlias - * The room alias. - */ - explicit GetRoomIdByAliasJob(const QString& roomAlias); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetRoomIdByAliasJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomAlias); - - ~GetRoomIdByAliasJob() override; - - // Result properties - - /// The room ID for this room alias. - const QString& roomId() const; - /// A list of servers that are aware of this room alias. - const QStringList& servers() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; - - /// Remove a mapping of room alias to room ID. - /// - /// Remove a mapping of room alias to room ID. - /// - /// Servers may choose to implement additional access control checks here, - /// for instance that room aliases can only be deleted by their creator or a - /// server administrator. - class DeleteRoomAliasJob : public BaseJob - { - public: - /*! Remove a mapping of room alias to room ID. - * \param roomAlias - * The room alias to remove. - */ - explicit DeleteRoomAliasJob(const QString& roomAlias); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * DeleteRoomAliasJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomAlias); - }; +namespace QMatrixClient +{ + +// Operations + +/// Create a new mapping from room alias to room ID. + +class SetRoomAliasJob : public BaseJob +{ +public: + /*! Create a new mapping from room alias to room ID. + * \param roomAlias + * The room alias to set. + * \param roomId + * The room ID to set. + */ + explicit SetRoomAliasJob(const QString& roomAlias, const QString& roomId); +}; + +/// Get the room ID corresponding to this room alias. +/*! + * Requests that the server resolve a room alias to a room ID. + * + * The server will use the federation API to resolve the alias if the + * domain part of the alias does not correspond to the server's own + * domain. + */ +class GetRoomIdByAliasJob : public BaseJob +{ +public: + /*! Get the room ID corresponding to this room alias. + * \param roomAlias + * The room alias. + */ + explicit GetRoomIdByAliasJob(const QString& roomAlias); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetRoomIdByAliasJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomAlias); + + ~GetRoomIdByAliasJob() override; + + // Result properties + + /// The room ID for this room alias. + const QString& roomId() const; + /// A list of servers that are aware of this room alias. + const QStringList& servers() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Remove a mapping of room alias to room ID. +/*! + * Remove a mapping of room alias to room ID. + * + * Servers may choose to implement additional access control checks here, for + * instance that room aliases can only be deleted by their creator or a server + * administrator. + */ +class DeleteRoomAliasJob : public BaseJob +{ +public: + /*! Remove a mapping of room alias to room ID. + * \param roomAlias + * The room alias to remove. + */ + explicit DeleteRoomAliasJob(const QString& roomAlias); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * DeleteRoomAliasJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomAlias); +}; + } // namespace QMatrixClient diff --git a/lib/csapi/event_context.cpp b/lib/csapi/event_context.cpp index 9ead6ac6..936b2430 100644 --- a/lib/csapi/event_context.cpp +++ b/lib/csapi/event_context.cpp @@ -14,7 +14,7 @@ static const auto basePath = QStringLiteral("/_matrix/client/r0"); class GetEventContextJob::Private { - public: +public: QString begin; QString end; RoomEvents eventsBefore; @@ -36,7 +36,7 @@ QUrl GetEventContextJob::makeRequestUrl(QUrl baseUrl, const QString& roomId, { return BaseJob::makeRequestUrl(std::move(baseUrl), basePath % "/rooms/" % roomId % "/context/" - % eventId, + % eventId, queryToGetEventContext(limit)); } @@ -47,10 +47,9 @@ GetEventContextJob::GetEventContextJob(const QString& roomId, Omittable<int> limit) : BaseJob(HttpVerb::Get, GetEventContextJobName, basePath % "/rooms/" % roomId % "/context/" % eventId, - queryToGetEventContext(limit)), - d(new Private) -{ -} + queryToGetEventContext(limit)) + , d(new Private) +{} GetEventContextJob::~GetEventContextJob() = default; @@ -81,5 +80,6 @@ BaseJob::Status GetEventContextJob::parseJson(const QJsonDocument& data) fromJson(json.value("event"_ls), d->event); fromJson(json.value("events_after"_ls), d->eventsAfter); fromJson(json.value("state"_ls), d->state); + return Success; } diff --git a/lib/csapi/event_context.h b/lib/csapi/event_context.h index cfefc550..ca06f4b9 100644 --- a/lib/csapi/event_context.h +++ b/lib/csapi/event_context.h @@ -4,68 +4,71 @@ #pragma once -#include "jobs/basejob.h" - #include "converters.h" + #include "events/eventloader.h" +#include "jobs/basejob.h" -namespace QMatrixClient { - // Operations +namespace QMatrixClient +{ + +// Operations + +/// Get events and state around the specified event. +/*! + * This API returns a number of events that happened just before and + * after the specified event. This allows clients to get the context + * surrounding an event. + */ +class GetEventContextJob : public BaseJob +{ +public: + /*! Get events and state around the specified event. + * \param roomId + * The room to get events from. + * \param eventId + * The event to get context around. + * \param limit + * The maximum number of events to return. Default: 10. + */ + explicit GetEventContextJob(const QString& roomId, const QString& eventId, + Omittable<int> limit = none); - /// Get events and state around the specified event. - /// - /// This API returns a number of events that happened just before and - /// after the specified event. This allows clients to get the context - /// surrounding an event. - class GetEventContextJob : public BaseJob - { - public: - /*! Get events and state around the specified event. - * \param roomId - * The room to get events from. - * \param eventId - * The event to get context around. - * \param limit - * The maximum number of events to return. Default: 10. - */ - explicit GetEventContextJob(const QString& roomId, - const QString& eventId, - Omittable<int> limit = none); + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetEventContextJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId, + const QString& eventId, + Omittable<int> limit = none); - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetEventContextJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId, - const QString& eventId, - Omittable<int> limit = none); + ~GetEventContextJob() override; - ~GetEventContextJob() override; + // Result properties - // Result properties + /// A token that can be used to paginate backwards with. + const QString& begin() const; + /// A token that can be used to paginate forwards with. + const QString& end() const; + /// A list of room events that happened just before the + /// requested event, in reverse-chronological order. + RoomEvents&& eventsBefore(); + /// Details of the requested event. + RoomEventPtr&& event(); + /// A list of room events that happened just after the + /// requested event, in chronological order. + RoomEvents&& eventsAfter(); + /// The state of the room at the last event returned. + StateEvents&& state(); - /// A token that can be used to paginate backwards with. - const QString& begin() const; - /// A token that can be used to paginate forwards with. - const QString& end() const; - /// A list of room events that happened just before the - /// requested event, in reverse-chronological order. - RoomEvents&& eventsBefore(); - /// Details of the requested event. - RoomEventPtr&& event(); - /// A list of room events that happened just after the - /// requested event, in chronological order. - RoomEvents&& eventsAfter(); - /// The state of the room at the last event returned. - StateEvents&& state(); +protected: + Status parseJson(const QJsonDocument& data) override; - protected: - Status parseJson(const QJsonDocument& data) override; +private: + class Private; + QScopedPointer<Private> d; +}; - private: - class Private; - QScopedPointer<Private> d; - }; } // namespace QMatrixClient diff --git a/lib/csapi/filter.cpp b/lib/csapi/filter.cpp index 40743de4..79dd5ea5 100644 --- a/lib/csapi/filter.cpp +++ b/lib/csapi/filter.cpp @@ -14,7 +14,7 @@ static const auto basePath = QStringLiteral("/_matrix/client/r0"); class DefineFilterJob::Private { - public: +public: QString filterId; }; @@ -22,8 +22,8 @@ static const auto DefineFilterJobName = QStringLiteral("DefineFilterJob"); DefineFilterJob::DefineFilterJob(const QString& userId, const Filter& filter) : BaseJob(HttpVerb::Post, DefineFilterJobName, - basePath % "/user/" % userId % "/filter"), - d(new Private) + basePath % "/user/" % userId % "/filter") + , d(new Private) { setRequestData(Data(toJson(filter))); } @@ -36,34 +36,34 @@ BaseJob::Status DefineFilterJob::parseJson(const QJsonDocument& data) { auto json = data.object(); if (!json.contains("filter_id"_ls)) - return { JsonParseError, + return { IncorrectResponse, "The key 'filter_id' not found in the response" }; fromJson(json.value("filter_id"_ls), d->filterId); + return Success; } class GetFilterJob::Private { - public: +public: Filter data; }; QUrl GetFilterJob::makeRequestUrl(QUrl baseUrl, const QString& userId, const QString& filterId) { - return BaseJob::makeRequestUrl(std::move(baseUrl), - basePath % "/user/" % userId % "/filter/" - % filterId); + return BaseJob::makeRequestUrl(std::move(baseUrl), basePath % "/user/" + % userId % "/filter/" + % filterId); } static const auto GetFilterJobName = QStringLiteral("GetFilterJob"); GetFilterJob::GetFilterJob(const QString& userId, const QString& filterId) : BaseJob(HttpVerb::Get, GetFilterJobName, - basePath % "/user/" % userId % "/filter/" % filterId), - d(new Private) -{ -} + basePath % "/user/" % userId % "/filter/" % filterId) + , d(new Private) +{} GetFilterJob::~GetFilterJob() = default; diff --git a/lib/csapi/filter.h b/lib/csapi/filter.h index 85e05667..0a5a98ae 100644 --- a/lib/csapi/filter.h +++ b/lib/csapi/filter.h @@ -4,82 +4,88 @@ #pragma once -#include "jobs/basejob.h" - #include "converters.h" + #include "csapi/definitions/sync_filter.h" -namespace QMatrixClient { - // Operations - - /// Upload a new filter. - /// - /// Uploads a new filter definition to the homeserver. - /// Returns a filter ID that may be used in future requests to - /// restrict which events are returned to the client. - class DefineFilterJob : public BaseJob - { - public: - /*! Upload a new filter. - * \param userId - * The id of the user uploading the filter. The access token must be - * authorized to make requests for this user id. \param filter Uploads a - * new filter definition to the homeserver. Returns a filter ID that may - * be used in future requests to restrict which events are returned to - * the client. - */ - explicit DefineFilterJob(const QString& userId, const Filter& filter); - ~DefineFilterJob() override; - - // Result properties - - /// The ID of the filter that was created. Cannot start - /// with a ``{`` as this character is used to determine - /// if the filter provided is inline JSON or a previously - /// declared filter by homeservers on some APIs. - const QString& filterId() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; - - /// Download a filter - class GetFilterJob : public BaseJob - { - public: - /*! Download a filter - * \param userId - * The user ID to download a filter for. - * \param filterId - * The filter ID to download. - */ - explicit GetFilterJob(const QString& userId, const QString& filterId); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetFilterJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& userId, - const QString& filterId); - - ~GetFilterJob() override; - - // Result properties - - /// "The filter defintion" - const Filter& data() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; +#include "jobs/basejob.h" + +namespace QMatrixClient +{ + +// Operations + +/// Upload a new filter. +/*! + * Uploads a new filter definition to the homeserver. + * Returns a filter ID that may be used in future requests to + * restrict which events are returned to the client. + */ +class DefineFilterJob : public BaseJob +{ +public: + /*! Upload a new filter. + * \param userId + * The id of the user uploading the filter. The access token must be + * authorized to make requests for this user id. \param filter Uploads a new + * filter definition to the homeserver. Returns a filter ID that may be used + * in future requests to restrict which events are returned to the client. + */ + explicit DefineFilterJob(const QString& userId, const Filter& filter); + + ~DefineFilterJob() override; + + // Result properties + + /// The ID of the filter that was created. Cannot start + /// with a ``{`` as this character is used to determine + /// if the filter provided is inline JSON or a previously + /// declared filter by homeservers on some APIs. + const QString& filterId() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Download a filter + +class GetFilterJob : public BaseJob +{ +public: + /*! Download a filter + * \param userId + * The user ID to download a filter for. + * \param filterId + * The filter ID to download. + */ + explicit GetFilterJob(const QString& userId, const QString& filterId); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetFilterJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& userId, + const QString& filterId); + + ~GetFilterJob() override; + + // Result properties + + /// "The filter defintion" + const Filter& data() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + } // namespace QMatrixClient diff --git a/lib/csapi/inviting.h b/lib/csapi/inviting.h index 12cf1b58..b0911ea8 100644 --- a/lib/csapi/inviting.h +++ b/lib/csapi/inviting.h @@ -6,38 +6,42 @@ #include "jobs/basejob.h" -namespace QMatrixClient { - // Operations +namespace QMatrixClient +{ + +// Operations + +/// Invite a user to participate in a particular room. +/*! + * .. _invite-by-user-id-endpoint: + * + * *Note that there are two forms of this API, which are documented separately. + * This version of the API requires that the inviter knows the Matrix + * identifier of the invitee. The other is documented in the* + * `third party invites section`_. + * + * This API invites a user to participate in a particular room. + * They do not start participating in the room until they actually join the + * room. + * + * Only users currently in a particular room can invite other users to + * join that room. + * + * If the user was invited to the room, the homeserver will append a + * ``m.room.member`` event to the room. + * + * .. _third party invites section: `invite-by-third-party-id-endpoint`_ + */ +class InviteUserJob : public BaseJob +{ +public: + /*! Invite a user to participate in a particular room. + * \param roomId + * The room identifier (not alias) to which to invite the user. + * \param userId + * The fully qualified user ID of the invitee. + */ + explicit InviteUserJob(const QString& roomId, const QString& userId); +}; - /// Invite a user to participate in a particular room. - /// - /// .. _invite-by-user-id-endpoint: - /// - /// *Note that there are two forms of this API, which are documented - /// separately. This version of the API requires that the inviter knows the - /// Matrix identifier of the invitee. The other is documented in the* `third - /// party invites section`_. - /// - /// This API invites a user to participate in a particular room. - /// They do not start participating in the room until they actually join the - /// room. - /// - /// Only users currently in a particular room can invite other users to - /// join that room. - /// - /// If the user was invited to the room, the homeserver will append a - /// ``m.room.member`` event to the room. - /// - /// .. _third party invites section: `invite-by-third-party-id-endpoint`_ - class InviteUserJob : public BaseJob - { - public: - /*! Invite a user to participate in a particular room. - * \param roomId - * The room identifier (not alias) to which to invite the user. - * \param userId - * The fully qualified user ID of the invitee. - */ - explicit InviteUserJob(const QString& roomId, const QString& userId); - }; } // namespace QMatrixClient diff --git a/lib/csapi/joining.cpp b/lib/csapi/joining.cpp index fe4c83e3..cb40cb96 100644 --- a/lib/csapi/joining.cpp +++ b/lib/csapi/joining.cpp @@ -12,35 +12,38 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); -namespace QMatrixClient { - // Converters - - template <> struct JsonObjectConverter<JoinRoomByIdJob::ThirdPartySigned> { - static void dumpTo(QJsonObject& jo, - const JoinRoomByIdJob::ThirdPartySigned& pod) - { - addParam<>(jo, QStringLiteral("sender"), pod.sender); - addParam<>(jo, QStringLiteral("mxid"), pod.mxid); - addParam<>(jo, QStringLiteral("token"), pod.token); - addParam<>(jo, QStringLiteral("signatures"), pod.signatures); - } - }; +// Converters +namespace QMatrixClient +{ + +template <> +struct JsonObjectConverter<JoinRoomByIdJob::ThirdPartySigned> +{ + static void dumpTo(QJsonObject& jo, + const JoinRoomByIdJob::ThirdPartySigned& pod) + { + addParam<>(jo, QStringLiteral("sender"), pod.sender); + addParam<>(jo, QStringLiteral("mxid"), pod.mxid); + addParam<>(jo, QStringLiteral("token"), pod.token); + addParam<>(jo, QStringLiteral("signatures"), pod.signatures); + } +}; + } // namespace QMatrixClient class JoinRoomByIdJob::Private { - public: +public: QString roomId; }; static const auto JoinRoomByIdJobName = QStringLiteral("JoinRoomByIdJob"); JoinRoomByIdJob::JoinRoomByIdJob( - const QString& roomId, - const Omittable<ThirdPartySigned>& thirdPartySigned) + const QString& roomId, const Omittable<ThirdPartySigned>& thirdPartySigned) : BaseJob(HttpVerb::Post, JoinRoomByIdJobName, - basePath % "/rooms/" % roomId % "/join"), - d(new Private) + basePath % "/rooms/" % roomId % "/join") + , d(new Private) { QJsonObject _data; addParam<IfNotEmpty>(_data, QStringLiteral("third_party_signed"), @@ -56,37 +59,43 @@ BaseJob::Status JoinRoomByIdJob::parseJson(const QJsonDocument& data) { auto json = data.object(); if (!json.contains("room_id"_ls)) - return { JsonParseError, + return { IncorrectResponse, "The key 'room_id' not found in the response" }; fromJson(json.value("room_id"_ls), d->roomId); + return Success; } -namespace QMatrixClient { - // Converters - - template <> struct JsonObjectConverter<JoinRoomJob::Signed> { - static void dumpTo(QJsonObject& jo, const JoinRoomJob::Signed& pod) - { - addParam<>(jo, QStringLiteral("sender"), pod.sender); - addParam<>(jo, QStringLiteral("mxid"), pod.mxid); - addParam<>(jo, QStringLiteral("token"), pod.token); - addParam<>(jo, QStringLiteral("signatures"), pod.signatures); - } - }; - - template <> struct JsonObjectConverter<JoinRoomJob::ThirdPartySigned> { - static void dumpTo(QJsonObject& jo, - const JoinRoomJob::ThirdPartySigned& pod) - { - addParam<>(jo, QStringLiteral("signed"), pod.signedData); - } - }; +// Converters +namespace QMatrixClient +{ + +template <> +struct JsonObjectConverter<JoinRoomJob::Signed> +{ + static void dumpTo(QJsonObject& jo, const JoinRoomJob::Signed& pod) + { + addParam<>(jo, QStringLiteral("sender"), pod.sender); + addParam<>(jo, QStringLiteral("mxid"), pod.mxid); + addParam<>(jo, QStringLiteral("token"), pod.token); + addParam<>(jo, QStringLiteral("signatures"), pod.signatures); + } +}; + +template <> +struct JsonObjectConverter<JoinRoomJob::ThirdPartySigned> +{ + static void dumpTo(QJsonObject& jo, const JoinRoomJob::ThirdPartySigned& pod) + { + addParam<>(jo, QStringLiteral("signed"), pod.signedData); + } +}; + } // namespace QMatrixClient class JoinRoomJob::Private { - public: +public: QString roomId; }; @@ -103,8 +112,8 @@ JoinRoomJob::JoinRoomJob(const QString& roomIdOrAlias, const QStringList& serverName, const Omittable<ThirdPartySigned>& thirdPartySigned) : BaseJob(HttpVerb::Post, JoinRoomJobName, - basePath % "/join/" % roomIdOrAlias, queryToJoinRoom(serverName)), - d(new Private) + basePath % "/join/" % roomIdOrAlias, queryToJoinRoom(serverName)) + , d(new Private) { QJsonObject _data; addParam<IfNotEmpty>(_data, QStringLiteral("third_party_signed"), @@ -120,8 +129,9 @@ BaseJob::Status JoinRoomJob::parseJson(const QJsonDocument& data) { auto json = data.object(); if (!json.contains("room_id"_ls)) - return { JsonParseError, + return { IncorrectResponse, "The key 'room_id' not found in the response" }; fromJson(json.value("room_id"_ls), d->roomId); + return Success; } diff --git a/lib/csapi/joining.h b/lib/csapi/joining.h index 5d118dab..a96f323d 100644 --- a/lib/csapi/joining.h +++ b/lib/csapi/joining.h @@ -4,161 +4,165 @@ #pragma once +#include "converters.h" + #include "jobs/basejob.h" -#include "converters.h" #include <QtCore/QJsonObject> -namespace QMatrixClient { - // Operations - - /// Start the requesting user participating in a particular room. - /// - /// *Note that this API requires a room ID, not alias.* - /// ``/join/{roomIdOrAlias}`` *exists if you have a room alias.* - /// - /// This API starts a user participating in a particular room, if that user - /// is allowed to participate in that room. After this call, the client is - /// allowed to see all current state events in the room, and all subsequent - /// events associated with the room until the user leaves the room. - /// - /// After a user has joined a room, the room will appear as an entry in the - /// response of the |/initialSync|_ and |/sync|_ APIs. - /// - /// If a ``third_party_signed`` was supplied, the homeserver must verify - /// that it matches a pending ``m.room.third_party_invite`` event in the - /// room, and perform key validity checking if required by the event. - class JoinRoomByIdJob : public BaseJob +namespace QMatrixClient +{ + +// Operations + +/// Start the requesting user participating in a particular room. +/*! + * *Note that this API requires a room ID, not alias.* ``/join/{roomIdOrAlias}`` + * *exists if you have a room alias.* + * + * This API starts a user participating in a particular room, if that user + * is allowed to participate in that room. After this call, the client is + * allowed to see all current state events in the room, and all subsequent + * events associated with the room until the user leaves the room. + * + * After a user has joined a room, the room will appear as an entry in the + * response of the |/initialSync|_ and |/sync|_ APIs. + * + * If a ``third_party_signed`` was supplied, the homeserver must verify + * that it matches a pending ``m.room.third_party_invite`` event in the + * room, and perform key validity checking if required by the event. + */ +class JoinRoomByIdJob : public BaseJob +{ +public: + // Inner data structures + + /// A signature of an ``m.third_party_invite`` token to prove that this user + /// owns a third party identity which has been invited to the room. + struct ThirdPartySigned { - public: - // Inner data structures - - /// A signature of an ``m.third_party_invite`` token to prove that this - /// user owns a third party identity which has been invited to the room. - struct ThirdPartySigned { - /// The Matrix ID of the user who issued the invite. - QString sender; - /// The Matrix ID of the invitee. - QString mxid; - /// The state key of the m.third_party_invite event. - QString token; - /// A signatures object containing a signature of the entire signed - /// object. - QJsonObject signatures; - }; - - // Construction/destruction - - /*! Start the requesting user participating in a particular room. - * \param roomId - * The room identifier (not alias) to join. - * \param thirdPartySigned - * A signature of an ``m.third_party_invite`` token to prove that this - * user owns a third party identity which has been invited to the room. - */ - explicit JoinRoomByIdJob( - const QString& roomId, - const Omittable<ThirdPartySigned>& thirdPartySigned = none); - ~JoinRoomByIdJob() override; - - // Result properties - - /// The joined room ID. - const QString& roomId() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; + /// The Matrix ID of the user who issued the invite. + QString sender; + /// The Matrix ID of the invitee. + QString mxid; + /// The state key of the m.third_party_invite event. + QString token; + /// A signatures object containing a signature of the entire signed + /// object. + QJsonObject signatures; }; - /// Start the requesting user participating in a particular room. - /// + // Construction/destruction + + /*! Start the requesting user participating in a particular room. + * \param roomId + * The room identifier (not alias) to join. + * \param thirdPartySigned + * A signature of an ``m.third_party_invite`` token to prove that this + * user owns a third party identity which has been invited to the room. + */ + explicit JoinRoomByIdJob( + const QString& roomId, + const Omittable<ThirdPartySigned>& thirdPartySigned = none); + + ~JoinRoomByIdJob() override; + + // Result properties + + /// The joined room ID. + const QString& roomId() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Start the requesting user participating in a particular room. +/*! + * *Note that this API takes either a room ID or alias, unlike* + * ``/room/{roomId}/join``. + * + * This API starts a user participating in a particular room, if that user + * is allowed to participate in that room. After this call, the client is + * allowed to see all current state events in the room, and all subsequent + * events associated with the room until the user leaves the room. + * + * After a user has joined a room, the room will appear as an entry in the + * response of the |/initialSync|_ and |/sync|_ APIs. + * + * If a ``third_party_signed`` was supplied, the homeserver must verify + * that it matches a pending ``m.room.third_party_invite`` event in the + * room, and perform key validity checking if required by the event. + */ +class JoinRoomJob : public BaseJob +{ +public: + // Inner data structures + /// *Note that this API takes either a room ID or alias, unlike* - /// ``/room/{roomId}/join``. - /// - /// This API starts a user participating in a particular room, if that user - /// is allowed to participate in that room. After this call, the client is - /// allowed to see all current state events in the room, and all subsequent - /// events associated with the room until the user leaves the room. - /// - /// After a user has joined a room, the room will appear as an entry in the - /// response of the |/initialSync|_ and |/sync|_ APIs. - /// - /// If a ``third_party_signed`` was supplied, the homeserver must verify - /// that it matches a pending ``m.room.third_party_invite`` event in the - /// room, and perform key validity checking if required by the event. - class JoinRoomJob : public BaseJob + /// ``/room/{roomId}/join``.This API starts a user participating in a + /// particular room, if that useris allowed to participate in that room. + /// After this call, the client isallowed to see all current state events in + /// the room, and all subsequentevents associated with the room until the + /// user leaves the room.After a user has joined a room, the room will + /// appear as an entry in theresponse of the |/initialSync|_ and |/sync|_ + /// APIs.If a ``third_party_signed`` was supplied, the homeserver must + /// verifythat it matches a pending ``m.room.third_party_invite`` event in + /// theroom, and perform key validity checking if required by the event. + struct Signed { - public: - // Inner data structures - - /// *Note that this API takes either a room ID or alias, unlike* - /// ``/room/{roomId}/join``. - /// - /// This API starts a user participating in a particular room, if that - /// user is allowed to participate in that room. After this call, the - /// client is allowed to see all current state events in the room, and - /// all subsequent events associated with the room until the user leaves - /// the room. - /// - /// After a user has joined a room, the room will appear as an entry in - /// the response of the |/initialSync|_ and |/sync|_ APIs. - /// - /// If a ``third_party_signed`` was supplied, the homeserver must verify - /// that it matches a pending ``m.room.third_party_invite`` event in the - /// room, and perform key validity checking if required by the event. - struct Signed { - /// The Matrix ID of the user who issued the invite. - QString sender; - /// The Matrix ID of the invitee. - QString mxid; - /// The state key of the m.third_party_invite event. - QString token; - /// A signatures object containing a signature of the entire signed - /// object. - QJsonObject signatures; - }; + /// The Matrix ID of the user who issued the invite. + QString sender; + /// The Matrix ID of the invitee. + QString mxid; + /// The state key of the m.third_party_invite event. + QString token; + /// A signatures object containing a signature of the entire signed + /// object. + QJsonObject signatures; + }; + /// A signature of an ``m.third_party_invite`` token to prove that this user + /// owns a third party identity which has been invited to the room. + struct ThirdPartySigned + { /// A signature of an ``m.third_party_invite`` token to prove that this /// user owns a third party identity which has been invited to the room. - struct ThirdPartySigned { - /// A signature of an ``m.third_party_invite`` token to prove that - /// this user owns a third party identity which has been invited to - /// the room. - Signed signedData; - }; - - // Construction/destruction - - /*! Start the requesting user participating in a particular room. - * \param roomIdOrAlias - * The room identifier or alias to join. - * \param serverName - * The servers to attempt to join the room through. One of the servers - * must be participating in the room. - * \param thirdPartySigned - * A signature of an ``m.third_party_invite`` token to prove that this - * user owns a third party identity which has been invited to the room. - */ - explicit JoinRoomJob( - const QString& roomIdOrAlias, - const QStringList& serverName = {}, - const Omittable<ThirdPartySigned>& thirdPartySigned = none); - ~JoinRoomJob() override; - - // Result properties - - /// The joined room ID. - const QString& roomId() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; + Signed signedData; }; + + // Construction/destruction + + /*! Start the requesting user participating in a particular room. + * \param roomIdOrAlias + * The room identifier or alias to join. + * \param serverName + * The servers to attempt to join the room through. One of the servers + * must be participating in the room. + * \param thirdPartySigned + * A signature of an ``m.third_party_invite`` token to prove that this + * user owns a third party identity which has been invited to the room. + */ + explicit JoinRoomJob( + const QString& roomIdOrAlias, const QStringList& serverName = {}, + const Omittable<ThirdPartySigned>& thirdPartySigned = none); + + ~JoinRoomJob() override; + + // Result properties + + /// The joined room ID. + const QString& roomId() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + } // namespace QMatrixClient diff --git a/lib/csapi/keys.cpp b/lib/csapi/keys.cpp index 862366a3..1752b865 100644 --- a/lib/csapi/keys.cpp +++ b/lib/csapi/keys.cpp @@ -14,7 +14,7 @@ static const auto basePath = QStringLiteral("/_matrix/client/r0"); class UploadKeysJob::Private { - public: +public: QHash<QString, int> oneTimeKeyCounts; }; @@ -22,8 +22,8 @@ static const auto UploadKeysJobName = QStringLiteral("UploadKeysJob"); UploadKeysJob::UploadKeysJob(const Omittable<DeviceKeys>& deviceKeys, const QHash<QString, QVariant>& oneTimeKeys) - : BaseJob(HttpVerb::Post, UploadKeysJobName, basePath % "/keys/upload"), - d(new Private) + : BaseJob(HttpVerb::Post, UploadKeysJobName, basePath % "/keys/upload") + , d(new Private) { QJsonObject _data; addParam<IfNotEmpty>(_data, QStringLiteral("device_keys"), deviceKeys); @@ -42,37 +42,43 @@ BaseJob::Status UploadKeysJob::parseJson(const QJsonDocument& data) { auto json = data.object(); if (!json.contains("one_time_key_counts"_ls)) - return { JsonParseError, + return { IncorrectResponse, "The key 'one_time_key_counts' not found in the response" }; fromJson(json.value("one_time_key_counts"_ls), d->oneTimeKeyCounts); + return Success; } -namespace QMatrixClient { - // Converters - - template <> struct JsonObjectConverter<QueryKeysJob::UnsignedDeviceInfo> { - static void fillFrom(const QJsonObject& jo, - QueryKeysJob::UnsignedDeviceInfo& result) - { - fromJson(jo.value("device_display_name"_ls), - result.deviceDisplayName); - } - }; - - template <> struct JsonObjectConverter<QueryKeysJob::DeviceInformation> { - static void fillFrom(const QJsonObject& jo, - QueryKeysJob::DeviceInformation& result) - { - fillFromJson<DeviceKeys>(jo, result); - fromJson(jo.value("unsigned"_ls), result.unsignedData); - } - }; +// Converters +namespace QMatrixClient +{ + +template <> +struct JsonObjectConverter<QueryKeysJob::UnsignedDeviceInfo> +{ + static void fillFrom(const QJsonObject& jo, + QueryKeysJob::UnsignedDeviceInfo& result) + { + fromJson(jo.value("device_display_name"_ls), result.deviceDisplayName); + } +}; + +template <> +struct JsonObjectConverter<QueryKeysJob::DeviceInformation> +{ + static void fillFrom(const QJsonObject& jo, + QueryKeysJob::DeviceInformation& result) + { + fillFromJson<DeviceKeys>(jo, result); + fromJson(jo.value("unsigned"_ls), result.unsignedData); + } +}; + } // namespace QMatrixClient class QueryKeysJob::Private { - public: +public: QHash<QString, QJsonObject> failures; QHash<QString, QHash<QString, DeviceInformation>> deviceKeys; }; @@ -81,8 +87,8 @@ static const auto QueryKeysJobName = QStringLiteral("QueryKeysJob"); QueryKeysJob::QueryKeysJob(const QHash<QString, QStringList>& deviceKeys, Omittable<int> timeout, const QString& token) - : BaseJob(HttpVerb::Post, QueryKeysJobName, basePath % "/keys/query"), - d(new Private) + : BaseJob(HttpVerb::Post, QueryKeysJobName, basePath % "/keys/query") + , d(new Private) { QJsonObject _data; addParam<IfNotEmpty>(_data, QStringLiteral("timeout"), timeout); @@ -109,12 +115,13 @@ BaseJob::Status QueryKeysJob::parseJson(const QJsonDocument& data) auto json = data.object(); fromJson(json.value("failures"_ls), d->failures); fromJson(json.value("device_keys"_ls), d->deviceKeys); + return Success; } class ClaimKeysJob::Private { - public: +public: QHash<QString, QJsonObject> failures; QHash<QString, QHash<QString, QVariant>> oneTimeKeys; }; @@ -122,10 +129,10 @@ class ClaimKeysJob::Private static const auto ClaimKeysJobName = QStringLiteral("ClaimKeysJob"); ClaimKeysJob::ClaimKeysJob( - const QHash<QString, QHash<QString, QString>>& oneTimeKeys, - Omittable<int> timeout) - : BaseJob(HttpVerb::Post, ClaimKeysJobName, basePath % "/keys/claim"), - d(new Private) + const QHash<QString, QHash<QString, QString>>& oneTimeKeys, + Omittable<int> timeout) + : BaseJob(HttpVerb::Post, ClaimKeysJobName, basePath % "/keys/claim") + , d(new Private) { QJsonObject _data; addParam<IfNotEmpty>(_data, QStringLiteral("timeout"), timeout); @@ -140,8 +147,7 @@ const QHash<QString, QJsonObject>& ClaimKeysJob::failures() const return d->failures; } -const QHash<QString, QHash<QString, QVariant>>& -ClaimKeysJob::oneTimeKeys() const +const QHash<QString, QHash<QString, QVariant>>& ClaimKeysJob::oneTimeKeys() const { return d->oneTimeKeys; } @@ -151,12 +157,13 @@ BaseJob::Status ClaimKeysJob::parseJson(const QJsonDocument& data) auto json = data.object(); fromJson(json.value("failures"_ls), d->failures); fromJson(json.value("one_time_keys"_ls), d->oneTimeKeys); + return Success; } class GetKeysChangesJob::Private { - public: +public: QStringList changed; QStringList left; }; @@ -181,10 +188,9 @@ static const auto GetKeysChangesJobName = QStringLiteral("GetKeysChangesJob"); GetKeysChangesJob::GetKeysChangesJob(const QString& from, const QString& to) : BaseJob(HttpVerb::Get, GetKeysChangesJobName, basePath % "/keys/changes", - queryToGetKeysChanges(from, to)), - d(new Private) -{ -} + queryToGetKeysChanges(from, to)) + , d(new Private) +{} GetKeysChangesJob::~GetKeysChangesJob() = default; @@ -197,5 +203,6 @@ BaseJob::Status GetKeysChangesJob::parseJson(const QJsonDocument& data) auto json = data.object(); fromJson(json.value("changed"_ls), d->changed); fromJson(json.value("left"_ls), d->left); + return Success; } diff --git a/lib/csapi/keys.h b/lib/csapi/keys.h index a01cd33b..f69028fd 100644 --- a/lib/csapi/keys.h +++ b/lib/csapi/keys.h @@ -4,223 +4,231 @@ #pragma once -#include "jobs/basejob.h" - #include "converters.h" + #include "csapi/definitions/device_keys.h" + +#include "jobs/basejob.h" + #include <QtCore/QHash> #include <QtCore/QJsonObject> #include <QtCore/QVariant> -namespace QMatrixClient { - // Operations +namespace QMatrixClient +{ - /// Upload end-to-end encryption keys. - /// - /// Publishes end-to-end encryption keys for the device. - class UploadKeysJob : public BaseJob - { - public: - /*! Upload end-to-end encryption keys. - * \param deviceKeys - * Identity keys for the device. May be absent if no new - * identity keys are required. - * \param oneTimeKeys - * One-time public keys for "pre-key" messages. The names of - * the properties should be in the format - * ``<algorithm>:<key_id>``. The format of the key is determined - * by the key algorithm. - * - * May be absent if no new one-time keys are required. - */ - explicit UploadKeysJob( - const Omittable<DeviceKeys>& deviceKeys = none, - const QHash<QString, QVariant>& oneTimeKeys = {}); - ~UploadKeysJob() override; - - // Result properties - - /// For each key algorithm, the number of unclaimed one-time keys - /// of that type currently held on the server for this device. - const QHash<QString, int>& oneTimeKeyCounts() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; +// Operations - /// Download device identity keys. - /// - /// Returns the current devices and identity keys for the given users. - class QueryKeysJob : public BaseJob +/// Upload end-to-end encryption keys. +/*! + * Publishes end-to-end encryption keys for the device. + */ +class UploadKeysJob : public BaseJob +{ +public: + /*! Upload end-to-end encryption keys. + * \param deviceKeys + * Identity keys for the device. May be absent if no new + * identity keys are required. + * \param oneTimeKeys + * One-time public keys for "pre-key" messages. The names of + * the properties should be in the format + * ``<algorithm>:<key_id>``. The format of the key is determined + * by the key algorithm. + * + * May be absent if no new one-time keys are required. + */ + explicit UploadKeysJob(const Omittable<DeviceKeys>& deviceKeys = none, + const QHash<QString, QVariant>& oneTimeKeys = {}); + + ~UploadKeysJob() override; + + // Result properties + + /// For each key algorithm, the number of unclaimed one-time keys + /// of that type currently held on the server for this device. + const QHash<QString, int>& oneTimeKeyCounts() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Download device identity keys. +/*! + * Returns the current devices and identity keys for the given users. + */ +class QueryKeysJob : public BaseJob +{ +public: + // Inner data structures + + /// Additional data added to the device key informationby intermediate + /// servers, and not covered by thesignatures. + struct UnsignedDeviceInfo { - public: - // Inner data structures - - /// Additional data added to the device key information - /// by intermediate servers, and not covered by the - /// signatures. - struct UnsignedDeviceInfo { - /// The display name which the user set on the device. - QString deviceDisplayName; - }; - - /// Returns the current devices and identity keys for the given users. - struct DeviceInformation : DeviceKeys { - /// Additional data added to the device key information - /// by intermediate servers, and not covered by the - /// signatures. - Omittable<UnsignedDeviceInfo> unsignedData; - }; - - // Construction/destruction - - /*! Download device identity keys. - * \param deviceKeys - * The keys to be downloaded. A map from user ID, to a list of - * device IDs, or to an empty list to indicate all devices for the - * corresponding user. - * \param timeout - * The time (in milliseconds) to wait when downloading keys from - * remote servers. 10 seconds is the recommended default. - * \param token - * If the client is fetching keys as a result of a device update - * received in a sync request, this should be the 'since' token of that - * sync request, or any later sync token. This allows the server to - * ensure its response contains the keys advertised by the notification - * in that sync. - */ - explicit QueryKeysJob(const QHash<QString, QStringList>& deviceKeys, - Omittable<int> timeout = none, - const QString& token = {}); - ~QueryKeysJob() override; - - // Result properties - - /// If any remote homeservers could not be reached, they are - /// recorded here. The names of the properties are the names of - /// the unreachable servers. - /// - /// If the homeserver could be reached, but the user or device - /// was unknown, no failure is recorded. Instead, the corresponding - /// user or device is missing from the ``device_keys`` result. - const QHash<QString, QJsonObject>& failures() const; - /// Information on the queried devices. A map from user ID, to a - /// map from device ID to device information. For each device, - /// the information returned will be the same as uploaded via - /// ``/keys/upload``, with the addition of an ``unsigned`` - /// property. - const QHash<QString, QHash<QString, DeviceInformation>>& - deviceKeys() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; + /// The display name which the user set on the device. + QString deviceDisplayName; }; - /// Claim one-time encryption keys. - /// - /// Claims one-time keys for use in pre-key messages. - class ClaimKeysJob : public BaseJob + /// Returns the current devices and identity keys for the given users. + struct DeviceInformation : DeviceKeys { - public: - /*! Claim one-time encryption keys. - * \param oneTimeKeys - * The keys to be claimed. A map from user ID, to a map from - * device ID to algorithm name. - * \param timeout - * The time (in milliseconds) to wait when downloading keys from - * remote servers. 10 seconds is the recommended default. - */ - explicit ClaimKeysJob( - const QHash<QString, QHash<QString, QString>>& oneTimeKeys, - Omittable<int> timeout = none); - ~ClaimKeysJob() override; - - // Result properties - - /// If any remote homeservers could not be reached, they are - /// recorded here. The names of the properties are the names of - /// the unreachable servers. - /// - /// If the homeserver could be reached, but the user or device - /// was unknown, no failure is recorded. Instead, the corresponding - /// user or device is missing from the ``one_time_keys`` result. - const QHash<QString, QJsonObject>& failures() const; - /// One-time keys for the queried devices. A map from user ID, to a - /// map from devices to a map from ``<algorithm>:<key_id>`` to the key - /// object. - const QHash<QString, QHash<QString, QVariant>>& oneTimeKeys() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; + /// Additional data added to the device key informationby intermediate + /// servers, and not covered by thesignatures. + Omittable<UnsignedDeviceInfo> unsignedData; }; - /// Query users with recent device key updates. - /// - /// Gets a list of users who have updated their device identity keys since a - /// previous sync token. + // Construction/destruction + + /*! Download device identity keys. + * \param deviceKeys + * The keys to be downloaded. A map from user ID, to a list of + * device IDs, or to an empty list to indicate all devices for the + * corresponding user. + * \param timeout + * The time (in milliseconds) to wait when downloading keys from + * remote servers. 10 seconds is the recommended default. + * \param token + * If the client is fetching keys as a result of a device update received + * in a sync request, this should be the 'since' token of that sync + * request, or any later sync token. This allows the server to ensure its + * response contains the keys advertised by the notification in that sync. + */ + explicit QueryKeysJob(const QHash<QString, QStringList>& deviceKeys, + Omittable<int> timeout = none, + const QString& token = {}); + + ~QueryKeysJob() override; + + // Result properties + + /// If any remote homeservers could not be reached, they are + /// recorded here. The names of the properties are the names of + /// the unreachable servers. /// - /// The server should include in the results any users who: + /// If the homeserver could be reached, but the user or device + /// was unknown, no failure is recorded. Instead, the corresponding + /// user or device is missing from the ``device_keys`` result. + const QHash<QString, QJsonObject>& failures() const; + /// Information on the queried devices. A map from user ID, to a + /// map from device ID to device information. For each device, + /// the information returned will be the same as uploaded via + /// ``/keys/upload``, with the addition of an ``unsigned`` + /// property. + const QHash<QString, QHash<QString, DeviceInformation>>& deviceKeys() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Claim one-time encryption keys. +/*! + * Claims one-time keys for use in pre-key messages. + */ +class ClaimKeysJob : public BaseJob +{ +public: + /*! Claim one-time encryption keys. + * \param oneTimeKeys + * The keys to be claimed. A map from user ID, to a map from + * device ID to algorithm name. + * \param timeout + * The time (in milliseconds) to wait when downloading keys from + * remote servers. 10 seconds is the recommended default. + */ + explicit ClaimKeysJob( + const QHash<QString, QHash<QString, QString>>& oneTimeKeys, + Omittable<int> timeout = none); + + ~ClaimKeysJob() override; + + // Result properties + + /// If any remote homeservers could not be reached, they are + /// recorded here. The names of the properties are the names of + /// the unreachable servers. /// - /// * currently share a room with the calling user (ie, both users have - /// membership state ``join``); *and* - /// * added new device identity keys or removed an existing device with - /// identity keys, between ``from`` and ``to``. - class GetKeysChangesJob : public BaseJob - { - public: - /*! Query users with recent device key updates. - * \param from - * The desired start point of the list. Should be the ``next_batch`` - * field from a response to an earlier call to |/sync|. Users who have - * not uploaded new device identity keys since this point, nor deleted - * existing devices with identity keys since then, will be excluded - * from the results. - * \param to - * The desired end point of the list. Should be the ``next_batch`` - * field from a recent call to |/sync| - typically the most recent - * such call. This may be used by the server as a hint to check its - * caches are up to date. - */ - explicit GetKeysChangesJob(const QString& from, const QString& to); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetKeysChangesJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& from, - const QString& to); - - ~GetKeysChangesJob() override; - - // Result properties - - /// The Matrix User IDs of all users who updated their device - /// identity keys. - const QStringList& changed() const; - /// The Matrix User IDs of all users who may have left all - /// the end-to-end encrypted rooms they previously shared - /// with the user. - const QStringList& left() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; + /// If the homeserver could be reached, but the user or device + /// was unknown, no failure is recorded. Instead, the corresponding + /// user or device is missing from the ``one_time_keys`` result. + const QHash<QString, QJsonObject>& failures() const; + /// One-time keys for the queried devices. A map from user ID, to a + /// map from devices to a map from ``<algorithm>:<key_id>`` to the key object. + const QHash<QString, QHash<QString, QVariant>>& oneTimeKeys() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Query users with recent device key updates. +/*! + * Gets a list of users who have updated their device identity keys since a + * previous sync token. + * + * The server should include in the results any users who: + * + * * currently share a room with the calling user (ie, both users have + * membership state ``join``); *and* + * * added new device identity keys or removed an existing device with + * identity keys, between ``from`` and ``to``. + */ +class GetKeysChangesJob : public BaseJob +{ +public: + /*! Query users with recent device key updates. + * \param from + * The desired start point of the list. Should be the ``next_batch`` field + * from a response to an earlier call to |/sync|. Users who have not + * uploaded new device identity keys since this point, nor deleted + * existing devices with identity keys since then, will be excluded + * from the results. + * \param to + * The desired end point of the list. Should be the ``next_batch`` + * field from a recent call to |/sync| - typically the most recent + * such call. This may be used by the server as a hint to check its + * caches are up to date. + */ + explicit GetKeysChangesJob(const QString& from, const QString& to); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetKeysChangesJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& from, + const QString& to); + + ~GetKeysChangesJob() override; + + // Result properties + + /// The Matrix User IDs of all users who updated their device + /// identity keys. + const QStringList& changed() const; + /// The Matrix User IDs of all users who may have left all + /// the end-to-end encrypted rooms they previously shared + /// with the user. + const QStringList& left() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + } // namespace QMatrixClient diff --git a/lib/csapi/kicking.h b/lib/csapi/kicking.h index d75b8df3..9566a9a4 100644 --- a/lib/csapi/kicking.h +++ b/lib/csapi/kicking.h @@ -6,32 +6,37 @@ #include "jobs/basejob.h" -namespace QMatrixClient { - // Operations +namespace QMatrixClient +{ + +// Operations + +/// Kick a user from the room. +/*! + * Kick a user from the room. + * + * The caller must have the required power level in order to perform this + * operation. + * + * Kicking a user adjusts the target member's membership state to be ``leave`` + * with an optional ``reason``. Like with other membership changes, a user can + * directly adjust the target member's state by making a request to + * ``/rooms/<room id>/state/m.room.member/<user id>``. + */ +class KickJob : public BaseJob +{ +public: + /*! Kick a user from the room. + * \param roomId + * The room identifier (not alias) from which the user should be kicked. + * \param userId + * The fully qualified user ID of the user being kicked. + * \param reason + * The reason the user has been kicked. This will be supplied as the + * ``reason`` on the target's updated `m.room.member`_ event. + */ + explicit KickJob(const QString& roomId, const QString& userId, + const QString& reason = {}); +}; - /// Kick a user from the room. - /// - /// Kick a user from the room. - /// - /// The caller must have the required power level in order to perform this - /// operation. - /// - /// Kicking a user adjusts the target member's membership state to be - /// ``leave`` with an optional ``reason``. Like with other membership - /// changes, a user can directly adjust the target member's state by making - /// a request to ``/rooms/<room id>/state/m.room.member/<user id>``. - class KickJob : public BaseJob - { - public: - /*! Kick a user from the room. - * \param roomId - * The room identifier (not alias) from which the user should be - * kicked. \param userId The fully qualified user ID of the user being - * kicked. \param reason The reason the user has been kicked. This will - * be supplied as the - * ``reason`` on the target's updated `m.room.member`_ event. - */ - explicit KickJob(const QString& roomId, const QString& userId, - const QString& reason = {}); - }; } // namespace QMatrixClient diff --git a/lib/csapi/leaving.cpp b/lib/csapi/leaving.cpp index c46567d7..325b1e04 100644 --- a/lib/csapi/leaving.cpp +++ b/lib/csapi/leaving.cpp @@ -23,8 +23,7 @@ static const auto LeaveRoomJobName = QStringLiteral("LeaveRoomJob"); LeaveRoomJob::LeaveRoomJob(const QString& roomId) : BaseJob(HttpVerb::Post, LeaveRoomJobName, basePath % "/rooms/" % roomId % "/leave") -{ -} +{} QUrl ForgetRoomJob::makeRequestUrl(QUrl baseUrl, const QString& roomId) { @@ -37,5 +36,4 @@ static const auto ForgetRoomJobName = QStringLiteral("ForgetRoomJob"); ForgetRoomJob::ForgetRoomJob(const QString& roomId) : BaseJob(HttpVerb::Post, ForgetRoomJobName, basePath % "/rooms/" % roomId % "/forget") -{ -} +{} diff --git a/lib/csapi/leaving.h b/lib/csapi/leaving.h index 374d27d4..2ed6c8e7 100644 --- a/lib/csapi/leaving.h +++ b/lib/csapi/leaving.h @@ -6,66 +6,71 @@ #include "jobs/basejob.h" -namespace QMatrixClient { - // Operations +namespace QMatrixClient +{ - /// Stop the requesting user participating in a particular room. - /// - /// This API stops a user participating in a particular room. - /// - /// If the user was already in the room, they will no longer be able to see - /// new events in the room. If the room requires an invite to join, they - /// will need to be re-invited before they can re-join. - /// - /// If the user was invited to the room, but had not joined, this call - /// serves to reject the invite. - /// - /// The user will still be allowed to retrieve history from the room which - /// they were previously allowed to see. - class LeaveRoomJob : public BaseJob - { - public: - /*! Stop the requesting user participating in a particular room. - * \param roomId - * The room identifier to leave. - */ - explicit LeaveRoomJob(const QString& roomId); +// Operations - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * LeaveRoomJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId); - }; +/// Stop the requesting user participating in a particular room. +/*! + * This API stops a user participating in a particular room. + * + * If the user was already in the room, they will no longer be able to see + * new events in the room. If the room requires an invite to join, they + * will need to be re-invited before they can re-join. + * + * If the user was invited to the room, but had not joined, this call + * serves to reject the invite. + * + * The user will still be allowed to retrieve history from the room which + * they were previously allowed to see. + */ +class LeaveRoomJob : public BaseJob +{ +public: + /*! Stop the requesting user participating in a particular room. + * \param roomId + * The room identifier to leave. + */ + explicit LeaveRoomJob(const QString& roomId); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * LeaveRoomJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId); +}; + +/// Stop the requesting user remembering about a particular room. +/*! + * This API stops a user remembering about a particular room. + * + * In general, history is a first class citizen in Matrix. After this API + * is called, however, a user will no longer be able to retrieve history + * for this room. If all users on a homeserver forget a room, the room is + * eligible for deletion from that homeserver. + * + * If the user is currently joined to the room, they must leave the room + * before calling this API. + */ +class ForgetRoomJob : public BaseJob +{ +public: + /*! Stop the requesting user remembering about a particular room. + * \param roomId + * The room identifier to forget. + */ + explicit ForgetRoomJob(const QString& roomId); - /// Stop the requesting user remembering about a particular room. - /// - /// This API stops a user remembering about a particular room. - /// - /// In general, history is a first class citizen in Matrix. After this API - /// is called, however, a user will no longer be able to retrieve history - /// for this room. If all users on a homeserver forget a room, the room is - /// eligible for deletion from that homeserver. - /// - /// If the user is currently joined to the room, they must leave the room - /// before calling this API. - class ForgetRoomJob : public BaseJob - { - public: - /*! Stop the requesting user remembering about a particular room. - * \param roomId - * The room identifier to forget. - */ - explicit ForgetRoomJob(const QString& roomId); + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * ForgetRoomJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId); +}; - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * ForgetRoomJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId); - }; } // namespace QMatrixClient diff --git a/lib/csapi/list_joined_rooms.cpp b/lib/csapi/list_joined_rooms.cpp index 145e91ad..43c948f7 100644 --- a/lib/csapi/list_joined_rooms.cpp +++ b/lib/csapi/list_joined_rooms.cpp @@ -14,7 +14,7 @@ static const auto basePath = QStringLiteral("/_matrix/client/r0"); class GetJoinedRoomsJob::Private { - public: +public: QStringList joinedRooms; }; @@ -27,10 +27,9 @@ QUrl GetJoinedRoomsJob::makeRequestUrl(QUrl baseUrl) static const auto GetJoinedRoomsJobName = QStringLiteral("GetJoinedRoomsJob"); GetJoinedRoomsJob::GetJoinedRoomsJob() - : BaseJob(HttpVerb::Get, GetJoinedRoomsJobName, basePath % "/joined_rooms"), - d(new Private) -{ -} + : BaseJob(HttpVerb::Get, GetJoinedRoomsJobName, basePath % "/joined_rooms") + , d(new Private) +{} GetJoinedRoomsJob::~GetJoinedRoomsJob() = default; @@ -43,8 +42,9 @@ BaseJob::Status GetJoinedRoomsJob::parseJson(const QJsonDocument& data) { auto json = data.object(); if (!json.contains("joined_rooms"_ls)) - return { JsonParseError, + return { IncorrectResponse, "The key 'joined_rooms' not found in the response" }; fromJson(json.value("joined_rooms"_ls), d->joinedRooms); + return Success; } diff --git a/lib/csapi/list_joined_rooms.h b/lib/csapi/list_joined_rooms.h index 6f4169e8..1b64a004 100644 --- a/lib/csapi/list_joined_rooms.h +++ b/lib/csapi/list_joined_rooms.h @@ -6,37 +6,41 @@ #include "jobs/basejob.h" -namespace QMatrixClient { - // Operations - - /// Lists the user's current rooms. - /// - /// This API returns a list of the user's current rooms. - class GetJoinedRoomsJob : public BaseJob - { - public: - explicit GetJoinedRoomsJob(); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetJoinedRoomsJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl); - - ~GetJoinedRoomsJob() override; - - // Result properties - - /// The ID of each room in which the user has ``joined`` membership. - const QStringList& joinedRooms() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; +namespace QMatrixClient +{ + +// Operations + +/// Lists the user's current rooms. +/*! + * This API returns a list of the user's current rooms. + */ +class GetJoinedRoomsJob : public BaseJob +{ +public: + explicit GetJoinedRoomsJob(); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetJoinedRoomsJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl); + + ~GetJoinedRoomsJob() override; + + // Result properties + + /// The ID of each room in which the user has ``joined`` membership. + const QStringList& joinedRooms() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + } // namespace QMatrixClient diff --git a/lib/csapi/list_public_rooms.cpp b/lib/csapi/list_public_rooms.cpp index 2649b9f8..4d96dac3 100644 --- a/lib/csapi/list_public_rooms.cpp +++ b/lib/csapi/list_public_rooms.cpp @@ -14,7 +14,7 @@ static const auto basePath = QStringLiteral("/_matrix/client/r0"); class GetRoomVisibilityOnDirectoryJob::Private { - public: +public: QString visibility; }; @@ -26,15 +26,14 @@ QUrl GetRoomVisibilityOnDirectoryJob::makeRequestUrl(QUrl baseUrl, } static const auto GetRoomVisibilityOnDirectoryJobName = - QStringLiteral("GetRoomVisibilityOnDirectoryJob"); + QStringLiteral("GetRoomVisibilityOnDirectoryJob"); GetRoomVisibilityOnDirectoryJob::GetRoomVisibilityOnDirectoryJob( - const QString& roomId) + const QString& roomId) : BaseJob(HttpVerb::Get, GetRoomVisibilityOnDirectoryJobName, - basePath % "/directory/list/room/" % roomId, false), - d(new Private) -{ -} + basePath % "/directory/list/room/" % roomId, false) + , d(new Private) +{} GetRoomVisibilityOnDirectoryJob::~GetRoomVisibilityOnDirectoryJob() = default; @@ -48,14 +47,15 @@ GetRoomVisibilityOnDirectoryJob::parseJson(const QJsonDocument& data) { auto json = data.object(); fromJson(json.value("visibility"_ls), d->visibility); + return Success; } static const auto SetRoomVisibilityOnDirectoryJobName = - QStringLiteral("SetRoomVisibilityOnDirectoryJob"); + QStringLiteral("SetRoomVisibilityOnDirectoryJob"); SetRoomVisibilityOnDirectoryJob::SetRoomVisibilityOnDirectoryJob( - const QString& roomId, const QString& visibility) + const QString& roomId, const QString& visibility) : BaseJob(HttpVerb::Put, SetRoomVisibilityOnDirectoryJobName, basePath % "/directory/list/room/" % roomId) { @@ -66,7 +66,7 @@ SetRoomVisibilityOnDirectoryJob::SetRoomVisibilityOnDirectoryJob( class GetPublicRoomsJob::Private { - public: +public: PublicRoomsResponse data; }; @@ -84,8 +84,7 @@ QUrl GetPublicRoomsJob::makeRequestUrl(QUrl baseUrl, Omittable<int> limit, const QString& since, const QString& server) { - return BaseJob::makeRequestUrl(std::move(baseUrl), - basePath % "/publicRooms", + return BaseJob::makeRequestUrl(std::move(baseUrl), basePath % "/publicRooms", queryToGetPublicRooms(limit, since, server)); } @@ -94,10 +93,9 @@ static const auto GetPublicRoomsJobName = QStringLiteral("GetPublicRoomsJob"); GetPublicRoomsJob::GetPublicRoomsJob(Omittable<int> limit, const QString& since, const QString& server) : BaseJob(HttpVerb::Get, GetPublicRoomsJobName, basePath % "/publicRooms", - queryToGetPublicRooms(limit, since, server), {}, false), - d(new Private) -{ -} + queryToGetPublicRooms(limit, since, server), {}, false) + , d(new Private) +{} GetPublicRoomsJob::~GetPublicRoomsJob() = default; @@ -109,22 +107,25 @@ BaseJob::Status GetPublicRoomsJob::parseJson(const QJsonDocument& data) return Success; } -namespace QMatrixClient { - // Converters - - template <> struct JsonObjectConverter<QueryPublicRoomsJob::Filter> { - static void dumpTo(QJsonObject& jo, - const QueryPublicRoomsJob::Filter& pod) - { - addParam<IfNotEmpty>(jo, QStringLiteral("generic_search_term"), - pod.genericSearchTerm); - } - }; +// Converters +namespace QMatrixClient +{ + +template <> +struct JsonObjectConverter<QueryPublicRoomsJob::Filter> +{ + static void dumpTo(QJsonObject& jo, const QueryPublicRoomsJob::Filter& pod) + { + addParam<IfNotEmpty>(jo, QStringLiteral("generic_search_term"), + pod.genericSearchTerm); + } +}; + } // namespace QMatrixClient class QueryPublicRoomsJob::Private { - public: +public: PublicRoomsResponse data; }; @@ -136,7 +137,7 @@ BaseJob::Query queryToQueryPublicRooms(const QString& server) } static const auto QueryPublicRoomsJobName = - QStringLiteral("QueryPublicRoomsJob"); + QStringLiteral("QueryPublicRoomsJob"); QueryPublicRoomsJob::QueryPublicRoomsJob(const QString& server, Omittable<int> limit, @@ -145,8 +146,8 @@ QueryPublicRoomsJob::QueryPublicRoomsJob(const QString& server, Omittable<bool> includeAllNetworks, const QString& thirdPartyInstanceId) : BaseJob(HttpVerb::Post, QueryPublicRoomsJobName, - basePath % "/publicRooms", queryToQueryPublicRooms(server)), - d(new Private) + basePath % "/publicRooms", queryToQueryPublicRooms(server)) + , d(new Private) { QJsonObject _data; addParam<IfNotEmpty>(_data, QStringLiteral("limit"), limit); diff --git a/lib/csapi/list_public_rooms.h b/lib/csapi/list_public_rooms.h index 1a0af880..da68416d 100644 --- a/lib/csapi/list_public_rooms.h +++ b/lib/csapi/list_public_rooms.h @@ -4,180 +4,189 @@ #pragma once -#include "jobs/basejob.h" - #include "converters.h" + #include "csapi/definitions/public_rooms_response.h" -namespace QMatrixClient { - // Operations +#include "jobs/basejob.h" - /// Gets the visibility of a room in the directory - /// - /// Gets the visibility of a given room on the server's public room - /// directory. - class GetRoomVisibilityOnDirectoryJob : public BaseJob - { - public: - /*! Gets the visibility of a room in the directory - * \param roomId - * The room ID. - */ - explicit GetRoomVisibilityOnDirectoryJob(const QString& roomId); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetRoomVisibilityOnDirectoryJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId); - - ~GetRoomVisibilityOnDirectoryJob() override; - - // Result properties - - /// The visibility of the room in the directory. - const QString& visibility() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; +namespace QMatrixClient +{ - /// Sets the visibility of a room in the room directory - /// - /// Sets the visibility of a given room in the server's public room - /// directory. - /// - /// Servers may choose to implement additional access control checks - /// here, for instance that room visibility can only be changed by - /// the room creator or a server administrator. - class SetRoomVisibilityOnDirectoryJob : public BaseJob - { - public: - /*! Sets the visibility of a room in the room directory - * \param roomId - * The room ID. - * \param visibility - * The new visibility setting for the room. - * Defaults to 'public'. - */ - explicit SetRoomVisibilityOnDirectoryJob( - const QString& roomId, const QString& visibility = {}); - }; +// Operations - /// Lists the public rooms on the server. - /// - /// Lists the public rooms on the server. - /// - /// This API returns paginated responses. The rooms are ordered by the - /// number of joined members, with the largest rooms first. - class GetPublicRoomsJob : public BaseJob - { - public: - /*! Lists the public rooms on the server. - * \param limit - * Limit the number of results returned. - * \param since - * A pagination token from a previous request, allowing clients to - * get the next (or previous) batch of rooms. - * The direction of pagination is specified solely by which token - * is supplied, rather than via an explicit flag. - * \param server - * The server to fetch the public room lists from. Defaults to the - * local server. - */ - explicit GetPublicRoomsJob(Omittable<int> limit = none, - const QString& since = {}, - const QString& server = {}); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetPublicRoomsJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, Omittable<int> limit = none, - const QString& since = {}, - const QString& server = {}); - - ~GetPublicRoomsJob() override; - - // Result properties - - /// A list of the rooms on the server. - const PublicRoomsResponse& data() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; +/// Gets the visibility of a room in the directory +/*! + * Gets the visibility of a given room on the server's public room directory. + */ +class GetRoomVisibilityOnDirectoryJob : public BaseJob +{ +public: + /*! Gets the visibility of a room in the directory + * \param roomId + * The room ID. + */ + explicit GetRoomVisibilityOnDirectoryJob(const QString& roomId); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetRoomVisibilityOnDirectoryJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId); + + ~GetRoomVisibilityOnDirectoryJob() override; + + // Result properties + + /// The visibility of the room in the directory. + const QString& visibility() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Sets the visibility of a room in the room directory +/*! + * Sets the visibility of a given room in the server's public room + * directory. + * + * Servers may choose to implement additional access control checks + * here, for instance that room visibility can only be changed by + * the room creator or a server administrator. + */ +class SetRoomVisibilityOnDirectoryJob : public BaseJob +{ +public: + /*! Sets the visibility of a room in the room directory + * \param roomId + * The room ID. + * \param visibility + * The new visibility setting for the room. + * Defaults to 'public'. + */ + explicit SetRoomVisibilityOnDirectoryJob(const QString& roomId, + const QString& visibility = {}); +}; + +/// Lists the public rooms on the server. +/*! + * Lists the public rooms on the server. + * + * This API returns paginated responses. The rooms are ordered by the number + * of joined members, with the largest rooms first. + */ +class GetPublicRoomsJob : public BaseJob +{ +public: + /*! Lists the public rooms on the server. + * \param limit + * Limit the number of results returned. + * \param since + * A pagination token from a previous request, allowing clients to + * get the next (or previous) batch of rooms. + * The direction of pagination is specified solely by which token + * is supplied, rather than via an explicit flag. + * \param server + * The server to fetch the public room lists from. Defaults to the + * local server. + */ + explicit GetPublicRoomsJob(Omittable<int> limit = none, + const QString& since = {}, + const QString& server = {}); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetPublicRoomsJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, Omittable<int> limit = none, + const QString& since = {}, + const QString& server = {}); + + ~GetPublicRoomsJob() override; + + // Result properties + + /// A list of the rooms on the server. + const PublicRoomsResponse& data() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Lists the public rooms on the server with optional filter. +/*! + * Lists the public rooms on the server, with optional filter. + * + * This API returns paginated responses. The rooms are ordered by the number + * of joined members, with the largest rooms first. + */ +class QueryPublicRoomsJob : public BaseJob +{ +public: + // Inner data structures - /// Lists the public rooms on the server with optional filter. - /// - /// Lists the public rooms on the server, with optional filter. - /// - /// This API returns paginated responses. The rooms are ordered by the - /// number of joined members, with the largest rooms first. - class QueryPublicRoomsJob : public BaseJob + /// Filter to apply to the results. + struct Filter { - public: - // Inner data structures - - /// Filter to apply to the results. - struct Filter { - /// A string to search for in the room metadata, e.g. name, - /// topic, canonical alias etc. (Optional). - QString genericSearchTerm; - }; - - // Construction/destruction - - /*! Lists the public rooms on the server with optional filter. - * \param server - * The server to fetch the public room lists from. Defaults to the - * local server. - * \param limit - * Limit the number of results returned. - * \param since - * A pagination token from a previous request, allowing clients - * to get the next (or previous) batch of rooms. The direction - * of pagination is specified solely by which token is supplied, - * rather than via an explicit flag. - * \param filter - * Filter to apply to the results. - * \param includeAllNetworks - * Whether or not to include all known networks/protocols from - * application services on the homeserver. Defaults to false. - * \param thirdPartyInstanceId - * The specific third party network/protocol to request from the - * homeserver. Can only be used if ``include_all_networks`` is false. - */ - explicit QueryPublicRoomsJob(const QString& server = {}, - Omittable<int> limit = none, - const QString& since = {}, - const Omittable<Filter>& filter = none, - Omittable<bool> includeAllNetworks = none, - const QString& thirdPartyInstanceId = {}); - ~QueryPublicRoomsJob() override; - - // Result properties - - /// A list of the rooms on the server. - const PublicRoomsResponse& data() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; + /// A string to search for in the room metadata, e.g. name,topic, + /// canonical alias etc. (Optional). + QString genericSearchTerm; }; + + // Construction/destruction + + /*! Lists the public rooms on the server with optional filter. + * \param server + * The server to fetch the public room lists from. Defaults to the + * local server. + * \param limit + * Limit the number of results returned. + * \param since + * A pagination token from a previous request, allowing clients + * to get the next (or previous) batch of rooms. The direction + * of pagination is specified solely by which token is supplied, + * rather than via an explicit flag. + * \param filter + * Filter to apply to the results. + * \param includeAllNetworks + * Whether or not to include all known networks/protocols from + * application services on the homeserver. Defaults to false. + * \param thirdPartyInstanceId + * The specific third party network/protocol to request from the + * homeserver. Can only be used if ``include_all_networks`` is false. + */ + explicit QueryPublicRoomsJob(const QString& server = {}, + Omittable<int> limit = none, + const QString& since = {}, + const Omittable<Filter>& filter = none, + Omittable<bool> includeAllNetworks = none, + const QString& thirdPartyInstanceId = {}); + + ~QueryPublicRoomsJob() override; + + // Result properties + + /// A list of the rooms on the server. + const PublicRoomsResponse& data() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + } // namespace QMatrixClient diff --git a/lib/csapi/login.cpp b/lib/csapi/login.cpp index 77652e64..29ee4ab5 100644 --- a/lib/csapi/login.cpp +++ b/lib/csapi/login.cpp @@ -12,21 +12,25 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); -namespace QMatrixClient { - // Converters - - template <> struct JsonObjectConverter<GetLoginFlowsJob::LoginFlow> { - static void fillFrom(const QJsonObject& jo, - GetLoginFlowsJob::LoginFlow& result) - { - fromJson(jo.value("type"_ls), result.type); - } - }; +// Converters +namespace QMatrixClient +{ + +template <> +struct JsonObjectConverter<GetLoginFlowsJob::LoginFlow> +{ + static void fillFrom(const QJsonObject& jo, + GetLoginFlowsJob::LoginFlow& result) + { + fromJson(jo.value("type"_ls), result.type); + } +}; + } // namespace QMatrixClient class GetLoginFlowsJob::Private { - public: +public: QVector<LoginFlow> flows; }; @@ -38,10 +42,9 @@ QUrl GetLoginFlowsJob::makeRequestUrl(QUrl baseUrl) static const auto GetLoginFlowsJobName = QStringLiteral("GetLoginFlowsJob"); GetLoginFlowsJob::GetLoginFlowsJob() - : BaseJob(HttpVerb::Get, GetLoginFlowsJobName, basePath % "/login", false), - d(new Private) -{ -} + : BaseJob(HttpVerb::Get, GetLoginFlowsJobName, basePath % "/login", false) + , d(new Private) +{} GetLoginFlowsJob::~GetLoginFlowsJob() = default; @@ -54,12 +57,13 @@ BaseJob::Status GetLoginFlowsJob::parseJson(const QJsonDocument& data) { auto json = data.object(); fromJson(json.value("flows"_ls), d->flows); + return Success; } class LoginJob::Private { - public: +public: QString userId; QString accessToken; QString homeServer; @@ -75,8 +79,8 @@ LoginJob::LoginJob(const QString& type, const QString& deviceId, const QString& initialDeviceDisplayName, const QString& user, const QString& medium, const QString& address) - : BaseJob(HttpVerb::Post, LoginJobName, basePath % "/login", false), - d(new Private) + : BaseJob(HttpVerb::Post, LoginJobName, basePath % "/login", false) + , d(new Private) { QJsonObject _data; addParam<>(_data, QStringLiteral("type"), type); @@ -115,5 +119,6 @@ BaseJob::Status LoginJob::parseJson(const QJsonDocument& data) fromJson(json.value("home_server"_ls), d->homeServer); fromJson(json.value("device_id"_ls), d->deviceId); fromJson(json.value("well_known"_ls), d->wellKnown); + return Success; } diff --git a/lib/csapi/login.h b/lib/csapi/login.h index 89c8ca79..3ab0648f 100644 --- a/lib/csapi/login.h +++ b/lib/csapi/login.h @@ -4,140 +4,143 @@ #pragma once -#include "jobs/basejob.h" - #include "converters.h" + #include "csapi/definitions/user_identifier.h" #include "csapi/definitions/wellknown/full.h" -#include <QtCore/QVector> - -namespace QMatrixClient { - // Operations - - /// Get the supported login types to authenticate users - /// - /// Gets the homeserver's supported login types to authenticate users. - /// Clients should pick one of these and supply it as the ``type`` when - /// logging in. - class GetLoginFlowsJob : public BaseJob - { - public: - // Inner data structures - - /// Gets the homeserver's supported login types to authenticate users. - /// Clients should pick one of these and supply it as the ``type`` when - /// logging in. - struct LoginFlow { - /// The login type. This is supplied as the ``type`` when - /// logging in. - QString type; - }; - - // Construction/destruction - - explicit GetLoginFlowsJob(); - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetLoginFlowsJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl); +#include "jobs/basejob.h" - ~GetLoginFlowsJob() override; +#include <QtCore/QVector> - // Result properties +namespace QMatrixClient +{ - /// The homeserver's supported login types - const QVector<LoginFlow>& flows() const; +// Operations - protected: - Status parseJson(const QJsonDocument& data) override; +/// Get the supported login types to authenticate users +/*! + * Gets the homeserver's supported login types to authenticate users. Clients + * should pick one of these and supply it as the ``type`` when logging in. + */ +class GetLoginFlowsJob : public BaseJob +{ +public: + // Inner data structures - private: - class Private; - QScopedPointer<Private> d; + /// Gets the homeserver's supported login types to authenticate users. + /// Clientsshould pick one of these and supply it as the ``type`` when + /// logging in. + struct LoginFlow + { + /// The login type. This is supplied as the ``type`` whenlogging in. + QString type; }; - /// Authenticates the user. - /// - /// Authenticates the user, and issues an access token they can - /// use to authorize themself in subsequent requests. - /// - /// If the client does not supply a ``device_id``, the server must - /// auto-generate one. + // Construction/destruction + + explicit GetLoginFlowsJob(); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetLoginFlowsJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl); + + ~GetLoginFlowsJob() override; + + // Result properties + + /// The homeserver's supported login types + const QVector<LoginFlow>& flows() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Authenticates the user. +/*! + * Authenticates the user, and issues an access token they can + * use to authorize themself in subsequent requests. + * + * If the client does not supply a ``device_id``, the server must + * auto-generate one. + * + * The returned access token must be associated with the ``device_id`` + * supplied by the client or generated by the server. The server may + * invalidate any access token previously associated with that device. See + * `Relationship between access tokens and devices`_. + */ +class LoginJob : public BaseJob +{ +public: + /*! Authenticates the user. + * \param type + * The login type being used. + * \param identifier + * Identification information for the user. + * \param password + * Required when ``type`` is ``m.login.password``. The user's + * password. + * \param token + * Required when ``type`` is ``m.login.token``. Part of `Token-based`_ + * login. \param deviceId ID of the client device. If this does not + * correspond to a known client device, a new device will be created. The + * server will auto-generate a device_id if this is not specified. \param + * initialDeviceDisplayName A display name to assign to the newly-created + * device. Ignored if ``device_id`` corresponds to a known device. \param + * user The fully qualified user ID or just local part of the user ID, to + * log in. Deprecated in favour of ``identifier``. \param medium When + * logging in using a third party identifier, the medium of the identifier. + * Must be 'email'. Deprecated in favour of ``identifier``. \param address + * Third party identifier for the user. Deprecated in favour of + * ``identifier``. + */ + explicit LoginJob(const QString& type, + const Omittable<UserIdentifier>& identifier = none, + const QString& password = {}, const QString& token = {}, + const QString& deviceId = {}, + const QString& initialDeviceDisplayName = {}, + const QString& user = {}, const QString& medium = {}, + const QString& address = {}); + + ~LoginJob() override; + + // Result properties + + /// The fully-qualified Matrix ID that has been registered. + const QString& userId() const; + /// An access token for the account. + /// This access token can then be used to authorize other requests. + const QString& accessToken() const; + /// The server_name of the homeserver on which the account has + /// been registered. /// - /// The returned access token must be associated with the ``device_id`` - /// supplied by the client or generated by the server. The server may - /// invalidate any access token previously associated with that device. See - /// `Relationship between access tokens and devices`_. - class LoginJob : public BaseJob - { - public: - /*! Authenticates the user. - * \param type - * The login type being used. - * \param identifier - * Identification information for the user. - * \param password - * Required when ``type`` is ``m.login.password``. The user's - * password. - * \param token - * Required when ``type`` is ``m.login.token``. Part of `Token-based`_ - * login. \param deviceId ID of the client device. If this does not - * correspond to a known client device, a new device will be created. - * The server will auto-generate a device_id if this is not specified. - * \param initialDeviceDisplayName - * A display name to assign to the newly-created device. Ignored - * if ``device_id`` corresponds to a known device. - * \param user - * The fully qualified user ID or just local part of the user ID, to - * log in. Deprecated in favour of ``identifier``. \param medium When - * logging in using a third party identifier, the medium of the - * identifier. Must be 'email'. Deprecated in favour of ``identifier``. - * \param address - * Third party identifier for the user. Deprecated in favour of - * ``identifier``. - */ - explicit LoginJob(const QString& type, - const Omittable<UserIdentifier>& identifier = none, - const QString& password = {}, - const QString& token = {}, - const QString& deviceId = {}, - const QString& initialDeviceDisplayName = {}, - const QString& user = {}, const QString& medium = {}, - const QString& address = {}); - ~LoginJob() override; - - // Result properties - - /// The fully-qualified Matrix ID that has been registered. - const QString& userId() const; - /// An access token for the account. - /// This access token can then be used to authorize other requests. - const QString& accessToken() const; - /// The server_name of the homeserver on which the account has - /// been registered. - /// - /// **Deprecated**. Clients should extract the server_name from - /// ``user_id`` (by splitting at the first colon) if they require - /// it. Note also that ``homeserver`` is not spelt this way. - const QString& homeServer() const; - /// ID of the logged-in device. Will be the same as the - /// corresponding parameter in the request, if one was specified. - const QString& deviceId() const; - /// Optional client configuration provided by the server. If present, - /// clients SHOULD use the provided object to reconfigure themselves, - /// optionally validating the URLs within. This object takes the same - /// form as the one returned from .well-known autodiscovery. - const Omittable<DiscoveryInformation>& wellKnown() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; + /// **Deprecated**. Clients should extract the server_name from + /// ``user_id`` (by splitting at the first colon) if they require + /// it. Note also that ``homeserver`` is not spelt this way. + const QString& homeServer() const; + /// ID of the logged-in device. Will be the same as the + /// corresponding parameter in the request, if one was specified. + const QString& deviceId() const; + /// Optional client configuration provided by the server. If present, + /// clients SHOULD use the provided object to reconfigure themselves, + /// optionally validating the URLs within. This object takes the same + /// form as the one returned from .well-known autodiscovery. + const Omittable<DiscoveryInformation>& wellKnown() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + } // namespace QMatrixClient diff --git a/lib/csapi/logout.cpp b/lib/csapi/logout.cpp index f2d2e130..d0bef20e 100644 --- a/lib/csapi/logout.cpp +++ b/lib/csapi/logout.cpp @@ -21,18 +21,15 @@ static const auto LogoutJobName = QStringLiteral("LogoutJob"); LogoutJob::LogoutJob() : BaseJob(HttpVerb::Post, LogoutJobName, basePath % "/logout") -{ -} +{} QUrl LogoutAllJob::makeRequestUrl(QUrl baseUrl) { - return BaseJob::makeRequestUrl(std::move(baseUrl), - basePath % "/logout/all"); + return BaseJob::makeRequestUrl(std::move(baseUrl), basePath % "/logout/all"); } static const auto LogoutAllJobName = QStringLiteral("LogoutAllJob"); LogoutAllJob::LogoutAllJob() : BaseJob(HttpVerb::Post, LogoutAllJobName, basePath % "/logout/all") -{ -} +{} diff --git a/lib/csapi/logout.h b/lib/csapi/logout.h index 4bbb8526..c03af180 100644 --- a/lib/csapi/logout.h +++ b/lib/csapi/logout.h @@ -6,50 +6,53 @@ #include "jobs/basejob.h" -namespace QMatrixClient { - // Operations - - /// Invalidates a user access token - /// - /// Invalidates an existing access token, so that it can no longer be used - /// for authorization. - class LogoutJob : public BaseJob - { - public: - explicit LogoutJob(); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * LogoutJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl); - }; - - /// Invalidates all access tokens for a user - /// - /// Invalidates all access tokens for a user, so that they can no longer be - /// used for authorization. This includes the access token that made this - /// request. - /// - /// This endpoint does not require UI authorization because UI authorization - /// is designed to protect against attacks where the someone gets hold of a - /// single access token then takes over the account. This endpoint - /// invalidates all access tokens for the user, including the token used in - /// the request, and therefore the attacker is unable to take over the - /// account in this way. - class LogoutAllJob : public BaseJob - { - public: - explicit LogoutAllJob(); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * LogoutAllJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl); - }; +namespace QMatrixClient +{ + +// Operations + +/// Invalidates a user access token +/*! + * Invalidates an existing access token, so that it can no longer be used for + * authorization. + */ +class LogoutJob : public BaseJob +{ +public: + explicit LogoutJob(); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * LogoutJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl); +}; + +/// Invalidates all access tokens for a user +/*! + * Invalidates all access tokens for a user, so that they can no longer be used + * for authorization. This includes the access token that made this request. + * + * This endpoint does not require UI authorization because UI authorization is + * designed to protect against attacks where the someone gets hold of a single + * access token then takes over the account. This endpoint invalidates all + * access tokens for the user, including the token used in the request, and + * therefore the attacker is unable to take over the account in this way. + */ +class LogoutAllJob : public BaseJob +{ +public: + explicit LogoutAllJob(); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * LogoutAllJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl); +}; + } // namespace QMatrixClient diff --git a/lib/csapi/message_pagination.cpp b/lib/csapi/message_pagination.cpp index 272c1c20..3f09bd85 100644 --- a/lib/csapi/message_pagination.cpp +++ b/lib/csapi/message_pagination.cpp @@ -14,7 +14,7 @@ static const auto basePath = QStringLiteral("/_matrix/client/r0"); class GetRoomEventsJob::Private { - public: +public: QString begin; QString end; RoomEvents chunk; @@ -39,8 +39,8 @@ QUrl GetRoomEventsJob::makeRequestUrl(QUrl baseUrl, const QString& roomId, const QString& filter) { return BaseJob::makeRequestUrl( - std::move(baseUrl), basePath % "/rooms/" % roomId % "/messages", - queryToGetRoomEvents(from, to, dir, limit, filter)); + std::move(baseUrl), basePath % "/rooms/" % roomId % "/messages", + queryToGetRoomEvents(from, to, dir, limit, filter)); } static const auto GetRoomEventsJobName = QStringLiteral("GetRoomEventsJob"); @@ -50,10 +50,9 @@ GetRoomEventsJob::GetRoomEventsJob(const QString& roomId, const QString& from, Omittable<int> limit, const QString& filter) : BaseJob(HttpVerb::Get, GetRoomEventsJobName, basePath % "/rooms/" % roomId % "/messages", - queryToGetRoomEvents(from, to, dir, limit, filter)), - d(new Private) -{ -} + queryToGetRoomEvents(from, to, dir, limit, filter)) + , d(new Private) +{} GetRoomEventsJob::~GetRoomEventsJob() = default; @@ -69,5 +68,6 @@ BaseJob::Status GetRoomEventsJob::parseJson(const QJsonDocument& data) fromJson(json.value("start"_ls), d->begin); fromJson(json.value("end"_ls), d->end); fromJson(json.value("chunk"_ls), d->chunk); + return Success; } diff --git a/lib/csapi/message_pagination.h b/lib/csapi/message_pagination.h index 8ce1962e..03b3d42a 100644 --- a/lib/csapi/message_pagination.h +++ b/lib/csapi/message_pagination.h @@ -4,71 +4,80 @@ #pragma once -#include "jobs/basejob.h" - #include "converters.h" + #include "events/eventloader.h" +#include "jobs/basejob.h" -namespace QMatrixClient { - // Operations +namespace QMatrixClient +{ + +// Operations + +/// Get a list of events for this room +/*! + * This API returns a list of message and state events for a room. It uses + * pagination query parameters to paginate history in the room. + */ +class GetRoomEventsJob : public BaseJob +{ +public: + /*! Get a list of events for this room + * \param roomId + * The room to get events from. + * \param from + * The token to start returning events from. This token can be obtained + * from a ``prev_batch`` token returned for each room by the sync API, + * or from a ``start`` or ``end`` token returned by a previous request + * to this endpoint. + * \param dir + * The direction to return events from. + * \param to + * The token to stop returning events at. This token can be obtained from + * a ``prev_batch`` token returned for each room by the sync endpoint, + * or from a ``start`` or ``end`` token returned by a previous request to + * this endpoint. + * \param limit + * The maximum number of events to return. Default: 10. + * \param filter + * A JSON RoomEventFilter to filter returned events with. + */ + explicit GetRoomEventsJob(const QString& roomId, const QString& from, + const QString& dir, const QString& to = {}, + Omittable<int> limit = none, + const QString& filter = {}); - /// Get a list of events for this room - /// - /// This API returns a list of message and state events for a room. It uses - /// pagination query parameters to paginate history in the room. - class GetRoomEventsJob : public BaseJob - { - public: - /*! Get a list of events for this room - * \param roomId - * The room to get events from. - * \param from - * The token to start returning events from. This token can be - * obtained from a ``prev_batch`` token returned for each room by the - * sync API, or from a ``start`` or ``end`` token returned by a previous - * request to this endpoint. \param dir The direction to return events - * from. \param to The token to stop returning events at. This token can - * be obtained from a ``prev_batch`` token returned for each room by the - * sync endpoint, or from a ``start`` or ``end`` token returned by a - * previous request to this endpoint. \param limit The maximum number of - * events to return. Default: 10. \param filter A JSON RoomEventFilter - * to filter returned events with. - */ - explicit GetRoomEventsJob(const QString& roomId, const QString& from, - const QString& dir, const QString& to = {}, - Omittable<int> limit = none, - const QString& filter = {}); + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetRoomEventsJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId, + const QString& from, const QString& dir, + const QString& to = {}, + Omittable<int> limit = none, + const QString& filter = {}); - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetRoomEventsJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId, - const QString& from, const QString& dir, - const QString& to = {}, - Omittable<int> limit = none, - const QString& filter = {}); + ~GetRoomEventsJob() override; - ~GetRoomEventsJob() override; + // Result properties - // Result properties + /// The token the pagination starts from. If ``dir=b`` this will be + /// the token supplied in ``from``. + const QString& begin() const; + /// The token the pagination ends at. If ``dir=b`` this token should + /// be used again to request even earlier events. + const QString& end() const; + /// A list of room events. + RoomEvents&& chunk(); - /// The token the pagination starts from. If ``dir=b`` this will be - /// the token supplied in ``from``. - const QString& begin() const; - /// The token the pagination ends at. If ``dir=b`` this token should - /// be used again to request even earlier events. - const QString& end() const; - /// A list of room events. - RoomEvents&& chunk(); +protected: + Status parseJson(const QJsonDocument& data) override; - protected: - Status parseJson(const QJsonDocument& data) override; +private: + class Private; + QScopedPointer<Private> d; +}; - private: - class Private; - QScopedPointer<Private> d; - }; } // namespace QMatrixClient diff --git a/lib/csapi/notifications.cpp b/lib/csapi/notifications.cpp index b7f252ac..3a05a0b2 100644 --- a/lib/csapi/notifications.cpp +++ b/lib/csapi/notifications.cpp @@ -12,33 +12,36 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); -namespace QMatrixClient { - // Converters - - template <> struct JsonObjectConverter<GetNotificationsJob::Notification> { - static void fillFrom(const QJsonObject& jo, - GetNotificationsJob::Notification& result) - { - fromJson(jo.value("actions"_ls), result.actions); - fromJson(jo.value("event"_ls), result.event); - fromJson(jo.value("profile_tag"_ls), result.profileTag); - fromJson(jo.value("read"_ls), result.read); - fromJson(jo.value("room_id"_ls), result.roomId); - fromJson(jo.value("ts"_ls), result.ts); - } - }; +// Converters +namespace QMatrixClient +{ + +template <> +struct JsonObjectConverter<GetNotificationsJob::Notification> +{ + static void fillFrom(const QJsonObject& jo, + GetNotificationsJob::Notification& result) + { + fromJson(jo.value("actions"_ls), result.actions); + fromJson(jo.value("event"_ls), result.event); + fromJson(jo.value("profile_tag"_ls), result.profileTag); + fromJson(jo.value("read"_ls), result.read); + fromJson(jo.value("room_id"_ls), result.roomId); + fromJson(jo.value("ts"_ls), result.ts); + } +}; + } // namespace QMatrixClient class GetNotificationsJob::Private { - public: +public: QString nextToken; std::vector<Notification> notifications; }; BaseJob::Query queryToGetNotifications(const QString& from, - Omittable<int> limit, - const QString& only) + Omittable<int> limit, const QString& only) { BaseJob::Query _q; addParam<IfNotEmpty>(_q, QStringLiteral("from"), from); @@ -57,17 +60,16 @@ QUrl GetNotificationsJob::makeRequestUrl(QUrl baseUrl, const QString& from, } static const auto GetNotificationsJobName = - QStringLiteral("GetNotificationsJob"); + QStringLiteral("GetNotificationsJob"); GetNotificationsJob::GetNotificationsJob(const QString& from, Omittable<int> limit, const QString& only) : BaseJob(HttpVerb::Get, GetNotificationsJobName, basePath % "/notifications", - queryToGetNotifications(from, limit, only)), - d(new Private) -{ -} + queryToGetNotifications(from, limit, only)) + , d(new Private) +{} GetNotificationsJob::~GetNotificationsJob() = default; @@ -84,8 +86,9 @@ BaseJob::Status GetNotificationsJob::parseJson(const QJsonDocument& data) auto json = data.object(); fromJson(json.value("next_token"_ls), d->nextToken); if (!json.contains("notifications"_ls)) - return { JsonParseError, + return { IncorrectResponse, "The key 'notifications' not found in the response" }; fromJson(json.value("notifications"_ls), d->notifications); + return Success; } diff --git a/lib/csapi/notifications.h b/lib/csapi/notifications.h index 49bc33e9..4170d539 100644 --- a/lib/csapi/notifications.h +++ b/lib/csapi/notifications.h @@ -4,88 +4,94 @@ #pragma once -#include "jobs/basejob.h" - #include "converters.h" + #include "events/eventloader.h" +#include "jobs/basejob.h" + #include <QtCore/QJsonObject> #include <QtCore/QVariant> #include <QtCore/QVector> -namespace QMatrixClient { - // Operations +namespace QMatrixClient +{ - /// Gets a list of events that the user has been notified about - /// - /// This API is used to paginate through the list of events that the - /// user has been, or would have been notified about. - class GetNotificationsJob : public BaseJob +// Operations + +/// Gets a list of events that the user has been notified about +/*! + * This API is used to paginate through the list of events that the + * user has been, or would have been notified about. + */ +class GetNotificationsJob : public BaseJob +{ +public: + // Inner data structures + + /// This API is used to paginate through the list of events that theuser has + /// been, or would have been notified about. + struct Notification { - public: - // Inner data structures - - /// This API is used to paginate through the list of events that the - /// user has been, or would have been notified about. - struct Notification { - /// The action(s) to perform when the conditions for this rule are - /// met. See `Push Rules: API`_. - QVector<QVariant> actions; - /// The Event object for the event that triggered the notification. - EventPtr event; - /// The profile tag of the rule that matched this event. - QString profileTag; - /// Indicates whether the user has sent a read receipt indicating - /// that they have read this message. - bool read; - /// The ID of the room in which the event was posted. - QString roomId; - /// The unix timestamp at which the event notification was sent, - /// in milliseconds. - int ts; - }; - - // Construction/destruction - - /*! Gets a list of events that the user has been notified about - * \param from - * Pagination token given to retrieve the next set of events. - * \param limit - * Limit on the number of events to return in this request. - * \param only - * Allows basic filtering of events returned. Supply ``highlight`` - * to return only events where the notification had the highlight - * tweak set. - */ - explicit GetNotificationsJob(const QString& from = {}, - Omittable<int> limit = none, - const QString& only = {}); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetNotificationsJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& from = {}, - Omittable<int> limit = none, - const QString& only = {}); - - ~GetNotificationsJob() override; - - // Result properties - - /// The token to supply in the ``from`` param of the next - /// ``/notifications`` request in order to request more - /// events. If this is absent, there are no more results. - const QString& nextToken() const; - /// The list of events that triggered notifications. - std::vector<Notification>&& notifications(); - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; + /// The action(s) to perform when the conditions for this rule are + /// met.See `Push Rules: API`_. + QVector<QVariant> actions; + /// The Event object for the event that triggered the notification. + EventPtr event; + /// The profile tag of the rule that matched this event. + QString profileTag; + /// Indicates whether the user has sent a read receipt indicatingthat + /// they have read this message. + bool read; + /// The ID of the room in which the event was posted. + QString roomId; + /// The unix timestamp at which the event notification was sent,in + /// milliseconds. + int ts; }; + + // Construction/destruction + + /*! Gets a list of events that the user has been notified about + * \param from + * Pagination token given to retrieve the next set of events. + * \param limit + * Limit on the number of events to return in this request. + * \param only + * Allows basic filtering of events returned. Supply ``highlight`` + * to return only events where the notification had the highlight + * tweak set. + */ + explicit GetNotificationsJob(const QString& from = {}, + Omittable<int> limit = none, + const QString& only = {}); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetNotificationsJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& from = {}, + Omittable<int> limit = none, + const QString& only = {}); + + ~GetNotificationsJob() override; + + // Result properties + + /// The token to supply in the ``from`` param of the next + /// ``/notifications`` request in order to request more + /// events. If this is absent, there are no more results. + const QString& nextToken() const; + /// The list of events that triggered notifications. + std::vector<Notification>&& notifications(); + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + } // namespace QMatrixClient diff --git a/lib/csapi/openid.cpp b/lib/csapi/openid.cpp index 82a3b055..39ba3b9e 100644 --- a/lib/csapi/openid.cpp +++ b/lib/csapi/openid.cpp @@ -14,7 +14,7 @@ static const auto basePath = QStringLiteral("/_matrix/client/r0"); class RequestOpenIdTokenJob::Private { - public: +public: QString accessToken; QString tokenType; QString matrixServerName; @@ -22,13 +22,13 @@ class RequestOpenIdTokenJob::Private }; static const auto RequestOpenIdTokenJobName = - QStringLiteral("RequestOpenIdTokenJob"); + QStringLiteral("RequestOpenIdTokenJob"); RequestOpenIdTokenJob::RequestOpenIdTokenJob(const QString& userId, const QJsonObject& body) : BaseJob(HttpVerb::Post, RequestOpenIdTokenJobName, - basePath % "/user/" % userId % "/openid/request_token"), - d(new Private) + basePath % "/user/" % userId % "/openid/request_token") + , d(new Private) { setRequestData(Data(toJson(body))); } @@ -53,20 +53,21 @@ BaseJob::Status RequestOpenIdTokenJob::parseJson(const QJsonDocument& data) { auto json = data.object(); if (!json.contains("access_token"_ls)) - return { JsonParseError, + return { IncorrectResponse, "The key 'access_token' not found in the response" }; fromJson(json.value("access_token"_ls), d->accessToken); if (!json.contains("token_type"_ls)) - return { JsonParseError, + return { IncorrectResponse, "The key 'token_type' not found in the response" }; fromJson(json.value("token_type"_ls), d->tokenType); if (!json.contains("matrix_server_name"_ls)) - return { JsonParseError, + return { IncorrectResponse, "The key 'matrix_server_name' not found in the response" }; fromJson(json.value("matrix_server_name"_ls), d->matrixServerName); if (!json.contains("expires_in"_ls)) - return { JsonParseError, + return { IncorrectResponse, "The key 'expires_in' not found in the response" }; fromJson(json.value("expires_in"_ls), d->expiresIn); + return Success; } diff --git a/lib/csapi/openid.h b/lib/csapi/openid.h index 6e3c744d..40f1bc40 100644 --- a/lib/csapi/openid.h +++ b/lib/csapi/openid.h @@ -4,58 +4,64 @@ #pragma once +#include "converters.h" + #include "jobs/basejob.h" -#include "converters.h" #include <QtCore/QJsonObject> -namespace QMatrixClient { - // Operations - - /// Get an OpenID token object to verify the requester's identity. - /// - /// Gets an OpenID token object that the requester may supply to another - /// service to verify their identity in Matrix. The generated token is only - /// valid for exchanging for user information from the federation API for - /// OpenID. - /// - /// The access token generated is only valid for the OpenID API. It cannot - /// be used to request another OpenID access token or call ``/sync``, for - /// example. - class RequestOpenIdTokenJob : public BaseJob - { - public: - /*! Get an OpenID token object to verify the requester's identity. - * \param userId - * The user to request and OpenID token for. Should be the user who - * is authenticated for the request. - * \param body - * An empty object. Reserved for future expansion. - */ - explicit RequestOpenIdTokenJob(const QString& userId, - const QJsonObject& body = {}); - ~RequestOpenIdTokenJob() override; - - // Result properties - - /// An access token the consumer may use to verify the identity of - /// the person who generated the token. This is given to the federation - /// API ``GET /openid/userinfo``. - const QString& accessToken() const; - /// The string ``Bearer``. - const QString& tokenType() const; - /// The homeserver domain the consumer should use when attempting to - /// verify the user's identity. - const QString& matrixServerName() const; - /// The number of seconds before this token expires and a new one must - /// be generated. - int expiresIn() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; +namespace QMatrixClient +{ + +// Operations + +/// Get an OpenID token object to verify the requester's identity. +/*! + * Gets an OpenID token object that the requester may supply to another + * service to verify their identity in Matrix. The generated token is only + * valid for exchanging for user information from the federation API for + * OpenID. + * + * The access token generated is only valid for the OpenID API. It cannot + * be used to request another OpenID access token or call ``/sync``, for + * example. + */ +class RequestOpenIdTokenJob : public BaseJob +{ +public: + /*! Get an OpenID token object to verify the requester's identity. + * \param userId + * The user to request and OpenID token for. Should be the user who + * is authenticated for the request. + * \param body + * An empty object. Reserved for future expansion. + */ + explicit RequestOpenIdTokenJob(const QString& userId, + const QJsonObject& body = {}); + + ~RequestOpenIdTokenJob() override; + + // Result properties + + /// An access token the consumer may use to verify the identity of + /// the person who generated the token. This is given to the federation + /// API ``GET /openid/userinfo``. + const QString& accessToken() const; + /// The string ``Bearer``. + const QString& tokenType() const; + /// The homeserver domain the consumer should use when attempting to + /// verify the user's identity. + const QString& matrixServerName() const; + /// The number of seconds before this token expires and a new one must + /// be generated. + int expiresIn() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + } // namespace QMatrixClient diff --git a/lib/csapi/peeking_events.cpp b/lib/csapi/peeking_events.cpp index d48eca3f..6962d363 100644 --- a/lib/csapi/peeking_events.cpp +++ b/lib/csapi/peeking_events.cpp @@ -14,7 +14,7 @@ static const auto basePath = QStringLiteral("/_matrix/client/r0"); class PeekEventsJob::Private { - public: +public: QString begin; QString end; RoomEvents chunk; @@ -31,8 +31,7 @@ BaseJob::Query queryToPeekEvents(const QString& from, Omittable<int> timeout, } QUrl PeekEventsJob::makeRequestUrl(QUrl baseUrl, const QString& from, - Omittable<int> timeout, - const QString& roomId) + Omittable<int> timeout, const QString& roomId) { return BaseJob::makeRequestUrl(std::move(baseUrl), basePath % "/events", queryToPeekEvents(from, timeout, roomId)); @@ -43,10 +42,9 @@ static const auto PeekEventsJobName = QStringLiteral("PeekEventsJob"); PeekEventsJob::PeekEventsJob(const QString& from, Omittable<int> timeout, const QString& roomId) : BaseJob(HttpVerb::Get, PeekEventsJobName, basePath % "/events", - queryToPeekEvents(from, timeout, roomId)), - d(new Private) -{ -} + queryToPeekEvents(from, timeout, roomId)) + , d(new Private) +{} PeekEventsJob::~PeekEventsJob() = default; @@ -62,5 +60,6 @@ BaseJob::Status PeekEventsJob::parseJson(const QJsonDocument& data) fromJson(json.value("start"_ls), d->begin); fromJson(json.value("end"_ls), d->end); fromJson(json.value("chunk"_ls), d->chunk); + return Success; } diff --git a/lib/csapi/peeking_events.h b/lib/csapi/peeking_events.h index 00552af0..1fe63c4d 100644 --- a/lib/csapi/peeking_events.h +++ b/lib/csapi/peeking_events.h @@ -4,70 +4,74 @@ #pragma once -#include "jobs/basejob.h" - #include "converters.h" + #include "events/eventloader.h" +#include "jobs/basejob.h" -namespace QMatrixClient { - // Operations +namespace QMatrixClient +{ + +// Operations + +/// Listen on the event stream. +/*! + * This will listen for new events related to a particular room and return + * them to the caller. This will block until an event is received, or until + * the ``timeout`` is reached. + * + * This API is the same as the normal ``/events`` endpoint, but can be + * called by users who have not joined the room. + * + * Note that the normal ``/events`` endpoint has been deprecated. This + * API will also be deprecated at some point, but its replacement is not + * yet known. + */ +class PeekEventsJob : public BaseJob +{ +public: + /*! Listen on the event stream. + * \param from + * The token to stream from. This token is either from a previous + * request to this API or from the initial sync API. + * \param timeout + * The maximum time in milliseconds to wait for an event. + * \param roomId + * The room ID for which events should be returned. + */ + explicit PeekEventsJob(const QString& from = {}, + Omittable<int> timeout = none, + const QString& roomId = {}); - /// Listen on the event stream. - /// - /// This will listen for new events related to a particular room and return - /// them to the caller. This will block until an event is received, or until - /// the ``timeout`` is reached. - /// - /// This API is the same as the normal ``/events`` endpoint, but can be - /// called by users who have not joined the room. - /// - /// Note that the normal ``/events`` endpoint has been deprecated. This - /// API will also be deprecated at some point, but its replacement is not - /// yet known. - class PeekEventsJob : public BaseJob - { - public: - /*! Listen on the event stream. - * \param from - * The token to stream from. This token is either from a previous - * request to this API or from the initial sync API. - * \param timeout - * The maximum time in milliseconds to wait for an event. - * \param roomId - * The room ID for which events should be returned. - */ - explicit PeekEventsJob(const QString& from = {}, + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * PeekEventsJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& from = {}, Omittable<int> timeout = none, const QString& roomId = {}); - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * PeekEventsJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& from = {}, - Omittable<int> timeout = none, - const QString& roomId = {}); + ~PeekEventsJob() override; - ~PeekEventsJob() override; + // Result properties - // Result properties + /// A token which correlates to the first value in ``chunk``. This + /// is usually the same token supplied to ``from=``. + const QString& begin() const; + /// A token which correlates to the last value in ``chunk``. This + /// token should be used in the next request to ``/events``. + const QString& end() const; + /// An array of events. + RoomEvents&& chunk(); - /// A token which correlates to the first value in ``chunk``. This - /// is usually the same token supplied to ``from=``. - const QString& begin() const; - /// A token which correlates to the last value in ``chunk``. This - /// token should be used in the next request to ``/events``. - const QString& end() const; - /// An array of events. - RoomEvents&& chunk(); +protected: + Status parseJson(const QJsonDocument& data) override; - protected: - Status parseJson(const QJsonDocument& data) override; +private: + class Private; + QScopedPointer<Private> d; +}; - private: - class Private; - QScopedPointer<Private> d; - }; } // namespace QMatrixClient diff --git a/lib/csapi/presence.cpp b/lib/csapi/presence.cpp index 4f9b9c78..b6e8caf2 100644 --- a/lib/csapi/presence.cpp +++ b/lib/csapi/presence.cpp @@ -27,7 +27,7 @@ SetPresenceJob::SetPresenceJob(const QString& userId, const QString& presence, class GetPresenceJob::Private { - public: +public: QString presence; Omittable<int> lastActiveAgo; QString statusMsg; @@ -36,18 +36,17 @@ class GetPresenceJob::Private QUrl GetPresenceJob::makeRequestUrl(QUrl baseUrl, const QString& userId) { - return BaseJob::makeRequestUrl( - std::move(baseUrl), basePath % "/presence/" % userId % "/status"); + return BaseJob::makeRequestUrl(std::move(baseUrl), + basePath % "/presence/" % userId % "/status"); } static const auto GetPresenceJobName = QStringLiteral("GetPresenceJob"); GetPresenceJob::GetPresenceJob(const QString& userId) : BaseJob(HttpVerb::Get, GetPresenceJobName, - basePath % "/presence/" % userId % "/status"), - d(new Private) -{ -} + basePath % "/presence/" % userId % "/status") + , d(new Private) +{} GetPresenceJob::~GetPresenceJob() = default; @@ -69,11 +68,12 @@ BaseJob::Status GetPresenceJob::parseJson(const QJsonDocument& data) { auto json = data.object(); if (!json.contains("presence"_ls)) - return { JsonParseError, + return { IncorrectResponse, "The key 'presence' not found in the response" }; fromJson(json.value("presence"_ls), d->presence); fromJson(json.value("last_active_ago"_ls), d->lastActiveAgo); fromJson(json.value("status_msg"_ls), d->statusMsg); fromJson(json.value("currently_active"_ls), d->currentlyActive); + return Success; } diff --git a/lib/csapi/presence.h b/lib/csapi/presence.h index 881d9d5e..82c3a300 100644 --- a/lib/csapi/presence.h +++ b/lib/csapi/presence.h @@ -4,73 +4,78 @@ #pragma once +#include "converters.h" + #include "jobs/basejob.h" -#include "converters.h" +namespace QMatrixClient +{ -namespace QMatrixClient { - // Operations +// Operations - /// Update this user's presence state. - /// - /// This API sets the given user's presence state. When setting the status, - /// the activity time is updated to reflect that activity; the client does - /// not need to specify the ``last_active_ago`` field. You cannot set the - /// presence state of another user. - class SetPresenceJob : public BaseJob - { - public: - /*! Update this user's presence state. - * \param userId - * The user whose presence state to update. - * \param presence - * The new presence state. - * \param statusMsg - * The status message to attach to this state. - */ - explicit SetPresenceJob(const QString& userId, const QString& presence, - const QString& statusMsg = {}); - }; +/// Update this user's presence state. +/*! + * This API sets the given user's presence state. When setting the status, + * the activity time is updated to reflect that activity; the client does + * not need to specify the ``last_active_ago`` field. You cannot set the + * presence state of another user. + */ +class SetPresenceJob : public BaseJob +{ +public: + /*! Update this user's presence state. + * \param userId + * The user whose presence state to update. + * \param presence + * The new presence state. + * \param statusMsg + * The status message to attach to this state. + */ + explicit SetPresenceJob(const QString& userId, const QString& presence, + const QString& statusMsg = {}); +}; + +/// Get this user's presence state. +/*! + * Get the given user's presence state. + */ +class GetPresenceJob : public BaseJob +{ +public: + /*! Get this user's presence state. + * \param userId + * The user whose presence state to get. + */ + explicit GetPresenceJob(const QString& userId); - /// Get this user's presence state. - /// - /// Get the given user's presence state. - class GetPresenceJob : public BaseJob - { - public: - /*! Get this user's presence state. - * \param userId - * The user whose presence state to get. - */ - explicit GetPresenceJob(const QString& userId); + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetPresenceJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& userId); - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetPresenceJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& userId); + ~GetPresenceJob() override; - ~GetPresenceJob() override; + // Result properties - // Result properties + /// This user's presence. + const QString& presence() const; + /// The length of time in milliseconds since an action was performed + /// by this user. + Omittable<int> lastActiveAgo() const; + /// The state message for this user if one was set. + const QString& statusMsg() const; + /// Whether the user is currently active + Omittable<bool> currentlyActive() const; - /// This user's presence. - const QString& presence() const; - /// The length of time in milliseconds since an action was performed - /// by this user. - Omittable<int> lastActiveAgo() const; - /// The state message for this user if one was set. - const QString& statusMsg() const; - /// Whether the user is currently active - Omittable<bool> currentlyActive() const; +protected: + Status parseJson(const QJsonDocument& data) override; - protected: - Status parseJson(const QJsonDocument& data) override; +private: + class Private; + QScopedPointer<Private> d; +}; - private: - class Private; - QScopedPointer<Private> d; - }; } // namespace QMatrixClient diff --git a/lib/csapi/profile.cpp b/lib/csapi/profile.cpp index fefc18f2..630452f6 100644 --- a/lib/csapi/profile.cpp +++ b/lib/csapi/profile.cpp @@ -26,25 +26,23 @@ SetDisplayNameJob::SetDisplayNameJob(const QString& userId, class GetDisplayNameJob::Private { - public: +public: QString displayname; }; QUrl GetDisplayNameJob::makeRequestUrl(QUrl baseUrl, const QString& userId) { - return BaseJob::makeRequestUrl(std::move(baseUrl), - basePath % "/profile/" % userId - % "/displayname"); + return BaseJob::makeRequestUrl( + std::move(baseUrl), basePath % "/profile/" % userId % "/displayname"); } static const auto GetDisplayNameJobName = QStringLiteral("GetDisplayNameJob"); GetDisplayNameJob::GetDisplayNameJob(const QString& userId) : BaseJob(HttpVerb::Get, GetDisplayNameJobName, - basePath % "/profile/" % userId % "/displayname", false), - d(new Private) -{ -} + basePath % "/profile/" % userId % "/displayname", false) + , d(new Private) +{} GetDisplayNameJob::~GetDisplayNameJob() = default; @@ -54,13 +52,13 @@ BaseJob::Status GetDisplayNameJob::parseJson(const QJsonDocument& data) { auto json = data.object(); fromJson(json.value("displayname"_ls), d->displayname); + return Success; } static const auto SetAvatarUrlJobName = QStringLiteral("SetAvatarUrlJob"); -SetAvatarUrlJob::SetAvatarUrlJob(const QString& userId, - const QString& avatarUrl) +SetAvatarUrlJob::SetAvatarUrlJob(const QString& userId, const QString& avatarUrl) : BaseJob(HttpVerb::Put, SetAvatarUrlJobName, basePath % "/profile/" % userId % "/avatar_url") { @@ -71,25 +69,23 @@ SetAvatarUrlJob::SetAvatarUrlJob(const QString& userId, class GetAvatarUrlJob::Private { - public: +public: QString avatarUrl; }; QUrl GetAvatarUrlJob::makeRequestUrl(QUrl baseUrl, const QString& userId) { - return BaseJob::makeRequestUrl(std::move(baseUrl), - basePath % "/profile/" % userId - % "/avatar_url"); + return BaseJob::makeRequestUrl( + std::move(baseUrl), basePath % "/profile/" % userId % "/avatar_url"); } static const auto GetAvatarUrlJobName = QStringLiteral("GetAvatarUrlJob"); GetAvatarUrlJob::GetAvatarUrlJob(const QString& userId) : BaseJob(HttpVerb::Get, GetAvatarUrlJobName, - basePath % "/profile/" % userId % "/avatar_url", false), - d(new Private) -{ -} + basePath % "/profile/" % userId % "/avatar_url", false) + , d(new Private) +{} GetAvatarUrlJob::~GetAvatarUrlJob() = default; @@ -99,12 +95,13 @@ BaseJob::Status GetAvatarUrlJob::parseJson(const QJsonDocument& data) { auto json = data.object(); fromJson(json.value("avatar_url"_ls), d->avatarUrl); + return Success; } class GetUserProfileJob::Private { - public: +public: QString avatarUrl; QString displayname; }; @@ -119,10 +116,9 @@ static const auto GetUserProfileJobName = QStringLiteral("GetUserProfileJob"); GetUserProfileJob::GetUserProfileJob(const QString& userId) : BaseJob(HttpVerb::Get, GetUserProfileJobName, - basePath % "/profile/" % userId, false), - d(new Private) -{ -} + basePath % "/profile/" % userId, false) + , d(new Private) +{} GetUserProfileJob::~GetUserProfileJob() = default; @@ -135,5 +131,6 @@ BaseJob::Status GetUserProfileJob::parseJson(const QJsonDocument& data) auto json = data.object(); fromJson(json.value("avatar_url"_ls), d->avatarUrl); fromJson(json.value("displayname"_ls), d->displayname); + return Success; } diff --git a/lib/csapi/profile.h b/lib/csapi/profile.h index 9a6ab56b..95d3ec97 100644 --- a/lib/csapi/profile.h +++ b/lib/csapi/profile.h @@ -6,156 +6,162 @@ #include "jobs/basejob.h" -namespace QMatrixClient { - // Operations - - /// Set the user's display name. - /// - /// This API sets the given user's display name. You must have permission to - /// set this user's display name, e.g. you need to have their - /// ``access_token``. - class SetDisplayNameJob : public BaseJob - { - public: - /*! Set the user's display name. - * \param userId - * The user whose display name to set. - * \param displayname - * The new display name for this user. - */ - explicit SetDisplayNameJob(const QString& userId, - const QString& displayname = {}); - }; - - /// Get the user's display name. - /// - /// Get the user's display name. This API may be used to fetch the user's - /// own displayname or to query the name of other users; either locally or - /// on remote homeservers. - class GetDisplayNameJob : public BaseJob - { - public: - /*! Get the user's display name. - * \param userId - * The user whose display name to get. - */ - explicit GetDisplayNameJob(const QString& userId); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetDisplayNameJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& userId); - - ~GetDisplayNameJob() override; - - // Result properties - - /// The user's display name if they have set one, otherwise not present. - const QString& displayname() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; - - /// Set the user's avatar URL. - /// - /// This API sets the given user's avatar URL. You must have permission to - /// set this user's avatar URL, e.g. you need to have their - /// ``access_token``. - class SetAvatarUrlJob : public BaseJob - { - public: - /*! Set the user's avatar URL. - * \param userId - * The user whose avatar URL to set. - * \param avatarUrl - * The new avatar URL for this user. - */ - explicit SetAvatarUrlJob(const QString& userId, - const QString& avatarUrl = {}); - }; - - /// Get the user's avatar URL. - /// - /// Get the user's avatar URL. This API may be used to fetch the user's - /// own avatar URL or to query the URL of other users; either locally or - /// on remote homeservers. - class GetAvatarUrlJob : public BaseJob - { - public: - /*! Get the user's avatar URL. - * \param userId - * The user whose avatar URL to get. - */ - explicit GetAvatarUrlJob(const QString& userId); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetAvatarUrlJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& userId); - - ~GetAvatarUrlJob() override; - - // Result properties - - /// The user's avatar URL if they have set one, otherwise not present. - const QString& avatarUrl() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; - - /// Get this user's profile information. - /// - /// Get the combined profile information for this user. This API may be used - /// to fetch the user's own profile information or other users; either - /// locally or on remote homeservers. This API may return keys which are not - /// limited to ``displayname`` or ``avatar_url``. - class GetUserProfileJob : public BaseJob - { - public: - /*! Get this user's profile information. - * \param userId - * The user whose profile information to get. - */ - explicit GetUserProfileJob(const QString& userId); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetUserProfileJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& userId); - - ~GetUserProfileJob() override; - - // Result properties - - /// The user's avatar URL if they have set one, otherwise not present. - const QString& avatarUrl() const; - /// The user's display name if they have set one, otherwise not present. - const QString& displayname() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; +namespace QMatrixClient +{ + +// Operations + +/// Set the user's display name. +/*! + * This API sets the given user's display name. You must have permission to + * set this user's display name, e.g. you need to have their ``access_token``. + */ +class SetDisplayNameJob : public BaseJob +{ +public: + /*! Set the user's display name. + * \param userId + * The user whose display name to set. + * \param displayname + * The new display name for this user. + */ + explicit SetDisplayNameJob(const QString& userId, + const QString& displayname = {}); +}; + +/// Get the user's display name. +/*! + * Get the user's display name. This API may be used to fetch the user's + * own displayname or to query the name of other users; either locally or + * on remote homeservers. + */ +class GetDisplayNameJob : public BaseJob +{ +public: + /*! Get the user's display name. + * \param userId + * The user whose display name to get. + */ + explicit GetDisplayNameJob(const QString& userId); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetDisplayNameJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& userId); + + ~GetDisplayNameJob() override; + + // Result properties + + /// The user's display name if they have set one, otherwise not present. + const QString& displayname() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Set the user's avatar URL. +/*! + * This API sets the given user's avatar URL. You must have permission to + * set this user's avatar URL, e.g. you need to have their ``access_token``. + */ +class SetAvatarUrlJob : public BaseJob +{ +public: + /*! Set the user's avatar URL. + * \param userId + * The user whose avatar URL to set. + * \param avatarUrl + * The new avatar URL for this user. + */ + explicit SetAvatarUrlJob(const QString& userId, + const QString& avatarUrl = {}); +}; + +/// Get the user's avatar URL. +/*! + * Get the user's avatar URL. This API may be used to fetch the user's + * own avatar URL or to query the URL of other users; either locally or + * on remote homeservers. + */ +class GetAvatarUrlJob : public BaseJob +{ +public: + /*! Get the user's avatar URL. + * \param userId + * The user whose avatar URL to get. + */ + explicit GetAvatarUrlJob(const QString& userId); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetAvatarUrlJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& userId); + + ~GetAvatarUrlJob() override; + + // Result properties + + /// The user's avatar URL if they have set one, otherwise not present. + const QString& avatarUrl() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Get this user's profile information. +/*! + * Get the combined profile information for this user. This API may be used + * to fetch the user's own profile information or other users; either + * locally or on remote homeservers. This API may return keys which are not + * limited to ``displayname`` or ``avatar_url``. + */ +class GetUserProfileJob : public BaseJob +{ +public: + /*! Get this user's profile information. + * \param userId + * The user whose profile information to get. + */ + explicit GetUserProfileJob(const QString& userId); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetUserProfileJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& userId); + + ~GetUserProfileJob() override; + + // Result properties + + /// The user's avatar URL if they have set one, otherwise not present. + const QString& avatarUrl() const; + /// The user's display name if they have set one, otherwise not present. + const QString& displayname() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + } // namespace QMatrixClient diff --git a/lib/csapi/pusher.cpp b/lib/csapi/pusher.cpp index 86b36c6d..41a0cffe 100644 --- a/lib/csapi/pusher.cpp +++ b/lib/csapi/pusher.cpp @@ -12,38 +12,42 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); -namespace QMatrixClient { - // Converters - - template <> struct JsonObjectConverter<GetPushersJob::PusherData> { - static void fillFrom(const QJsonObject& jo, - GetPushersJob::PusherData& result) - { - fromJson(jo.value("url"_ls), result.url); - fromJson(jo.value("format"_ls), result.format); - } - }; - - template <> struct JsonObjectConverter<GetPushersJob::Pusher> { - static void fillFrom(const QJsonObject& jo, - GetPushersJob::Pusher& result) - { - fromJson(jo.value("pushkey"_ls), result.pushkey); - fromJson(jo.value("kind"_ls), result.kind); - fromJson(jo.value("app_id"_ls), result.appId); - fromJson(jo.value("app_display_name"_ls), result.appDisplayName); - fromJson(jo.value("device_display_name"_ls), - result.deviceDisplayName); - fromJson(jo.value("profile_tag"_ls), result.profileTag); - fromJson(jo.value("lang"_ls), result.lang); - fromJson(jo.value("data"_ls), result.data); - } - }; +// Converters +namespace QMatrixClient +{ + +template <> +struct JsonObjectConverter<GetPushersJob::PusherData> +{ + static void fillFrom(const QJsonObject& jo, + GetPushersJob::PusherData& result) + { + fromJson(jo.value("url"_ls), result.url); + fromJson(jo.value("format"_ls), result.format); + } +}; + +template <> +struct JsonObjectConverter<GetPushersJob::Pusher> +{ + static void fillFrom(const QJsonObject& jo, GetPushersJob::Pusher& result) + { + fromJson(jo.value("pushkey"_ls), result.pushkey); + fromJson(jo.value("kind"_ls), result.kind); + fromJson(jo.value("app_id"_ls), result.appId); + fromJson(jo.value("app_display_name"_ls), result.appDisplayName); + fromJson(jo.value("device_display_name"_ls), result.deviceDisplayName); + fromJson(jo.value("profile_tag"_ls), result.profileTag); + fromJson(jo.value("lang"_ls), result.lang); + fromJson(jo.value("data"_ls), result.data); + } +}; + } // namespace QMatrixClient class GetPushersJob::Private { - public: +public: QVector<Pusher> pushers; }; @@ -55,10 +59,9 @@ QUrl GetPushersJob::makeRequestUrl(QUrl baseUrl) static const auto GetPushersJobName = QStringLiteral("GetPushersJob"); GetPushersJob::GetPushersJob() - : BaseJob(HttpVerb::Get, GetPushersJobName, basePath % "/pushers"), - d(new Private) -{ -} + : BaseJob(HttpVerb::Get, GetPushersJobName, basePath % "/pushers") + , d(new Private) +{} GetPushersJob::~GetPushersJob() = default; @@ -71,27 +74,30 @@ BaseJob::Status GetPushersJob::parseJson(const QJsonDocument& data) { auto json = data.object(); fromJson(json.value("pushers"_ls), d->pushers); + return Success; } -namespace QMatrixClient { - // Converters - - template <> struct JsonObjectConverter<PostPusherJob::PusherData> { - static void dumpTo(QJsonObject& jo, - const PostPusherJob::PusherData& pod) - { - addParam<IfNotEmpty>(jo, QStringLiteral("url"), pod.url); - addParam<IfNotEmpty>(jo, QStringLiteral("format"), pod.format); - } - }; +// Converters +namespace QMatrixClient +{ + +template <> +struct JsonObjectConverter<PostPusherJob::PusherData> +{ + static void dumpTo(QJsonObject& jo, const PostPusherJob::PusherData& pod) + { + addParam<IfNotEmpty>(jo, QStringLiteral("url"), pod.url); + addParam<IfNotEmpty>(jo, QStringLiteral("format"), pod.format); + } +}; + } // namespace QMatrixClient static const auto PostPusherJobName = QStringLiteral("PostPusherJob"); PostPusherJob::PostPusherJob(const QString& pushkey, const QString& kind, - const QString& appId, - const QString& appDisplayName, + const QString& appId, const QString& appDisplayName, const QString& deviceDisplayName, const QString& lang, const PusherData& data, const QString& profileTag, Omittable<bool> append) diff --git a/lib/csapi/pusher.h b/lib/csapi/pusher.h index 947d7fc8..a909b9a0 100644 --- a/lib/csapi/pusher.h +++ b/lib/csapi/pusher.h @@ -4,168 +4,169 @@ #pragma once +#include "converters.h" + #include "jobs/basejob.h" -#include "converters.h" #include <QtCore/QVector> -namespace QMatrixClient { - // Operations +namespace QMatrixClient +{ + +// Operations + +/// Gets the current pushers for the authenticated user +/*! + * Gets all currently active pushers for the authenticated user. + */ +class GetPushersJob : public BaseJob +{ +public: + // Inner data structures + + /// A dictionary of information for the pusher implementationitself. + struct PusherData + { + /// Required if ``kind`` is ``http``. The URL to use to + /// sendnotifications to. + QString url; + /// The format to use when sending notifications to the PushGateway. + QString format; + }; - /// Gets the current pushers for the authenticated user - /// /// Gets all currently active pushers for the authenticated user. - class GetPushersJob : public BaseJob + struct Pusher { - public: - // Inner data structures - - /// A dictionary of information for the pusher implementation - /// itself. - struct PusherData { - /// Required if ``kind`` is ``http``. The URL to use to send - /// notifications to. - QString url; - /// The format to use when sending notifications to the Push - /// Gateway. - QString format; - }; - - /// Gets all currently active pushers for the authenticated user. - struct Pusher { - /// This is a unique identifier for this pusher. See ``/set`` for - /// more detail. - /// Max length, 512 bytes. - QString pushkey; - /// The kind of pusher. ``"http"`` is a pusher that - /// sends HTTP pokes. - QString kind; - /// This is a reverse-DNS style identifier for the application. - /// Max length, 64 chars. - QString appId; - /// A string that will allow the user to identify what application - /// owns this pusher. - QString appDisplayName; - /// A string that will allow the user to identify what device owns - /// this pusher. - QString deviceDisplayName; - /// This string determines which set of device specific rules this - /// pusher executes. - QString profileTag; - /// The preferred language for receiving notifications (e.g. 'en' - /// or 'en-US') - QString lang; - /// A dictionary of information for the pusher implementation - /// itself. - PusherData data; - }; - - // Construction/destruction - - explicit GetPushersJob(); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetPushersJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl); - - ~GetPushersJob() override; - - // Result properties - - /// An array containing the current pushers for the user - const QVector<Pusher>& pushers() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; + /// This is a unique identifier for this pusher. See ``/set`` formore + /// detail.Max length, 512 bytes. + QString pushkey; + /// The kind of pusher. ``"http"`` is a pusher thatsends HTTP pokes. + QString kind; + /// This is a reverse-DNS style identifier for the application.Max + /// length, 64 chars. + QString appId; + /// A string that will allow the user to identify what applicationowns + /// this pusher. + QString appDisplayName; + /// A string that will allow the user to identify what device ownsthis + /// pusher. + QString deviceDisplayName; + /// This string determines which set of device specific rules thispusher + /// executes. + QString profileTag; + /// The preferred language for receiving notifications (e.g. 'en'or + /// 'en-US') + QString lang; + /// A dictionary of information for the pusher implementationitself. + PusherData data; }; - /// Modify a pusher for this user on the homeserver. - /// - /// This endpoint allows the creation, modification and deletion of - /// `pushers`_ for this user ID. The behaviour of this endpoint varies - /// depending on the values in the JSON body. - class PostPusherJob : public BaseJob + // Construction/destruction + + explicit GetPushersJob(); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetPushersJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl); + + ~GetPushersJob() override; + + // Result properties + + /// An array containing the current pushers for the user + const QVector<Pusher>& pushers() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Modify a pusher for this user on the homeserver. +/*! + * This endpoint allows the creation, modification and deletion of `pushers`_ + * for this user ID. The behaviour of this endpoint varies depending on the + * values in the JSON body. + */ +class PostPusherJob : public BaseJob +{ +public: + // Inner data structures + + /// A dictionary of information for the pusher implementationitself. If + /// ``kind`` is ``http``, this should contain ``url``which is the URL to use + /// to send notifications to. + struct PusherData { - public: - // Inner data structures - - /// A dictionary of information for the pusher implementation - /// itself. If ``kind`` is ``http``, this should contain ``url`` - /// which is the URL to use to send notifications to. - struct PusherData { - /// Required if ``kind`` is ``http``. The URL to use to send - /// notifications to. MUST be an HTTPS URL with a path of - /// ``/_matrix/push/v1/notify``. - QString url; - /// The format to send notifications in to Push Gateways if the - /// ``kind`` is ``http``. The details about what fields the - /// homeserver should send to the push gateway are defined in the - /// `Push Gateway Specification`_. Currently the only format - /// available is 'event_id_only'. - QString format; - }; - - // Construction/destruction - - /*! Modify a pusher for this user on the homeserver. - * \param pushkey - * This is a unique identifier for this pusher. The value you - * should use for this is the routing or destination address - * information for the notification, for example, the APNS token - * for APNS or the Registration ID for GCM. If your notification - * client has no such concept, use any unique identifier. - * Max length, 512 bytes. - * - * If the ``kind`` is ``"email"``, this is the email address to - * send notifications to. - * \param kind - * The kind of pusher to configure. ``"http"`` makes a pusher that - * sends HTTP pokes. ``"email"`` makes a pusher that emails the - * user with unread notifications. ``null`` deletes the pusher. - * \param appId - * This is a reverse-DNS style identifier for the application. - * It is recommended that this end with the platform, such that - * different platform versions get different app identifiers. - * Max length, 64 chars. - * - * If the ``kind`` is ``"email"``, this is ``"m.email"``. - * \param appDisplayName - * A string that will allow the user to identify what application - * owns this pusher. - * \param deviceDisplayName - * A string that will allow the user to identify what device owns - * this pusher. - * \param lang - * The preferred language for receiving notifications (e.g. 'en' - * or 'en-US'). - * \param data - * A dictionary of information for the pusher implementation - * itself. If ``kind`` is ``http``, this should contain ``url`` - * which is the URL to use to send notifications to. - * \param profileTag - * This string determines which set of device specific rules this - * pusher executes. - * \param append - * If true, the homeserver should add another pusher with the - * given pushkey and App ID in addition to any others with - * different user IDs. Otherwise, the homeserver must remove any - * other pushers with the same App ID and pushkey for different - * users. The default is ``false``. - */ - explicit PostPusherJob(const QString& pushkey, const QString& kind, - const QString& appId, - const QString& appDisplayName, - const QString& deviceDisplayName, - const QString& lang, const PusherData& data, - const QString& profileTag = {}, - Omittable<bool> append = none); + /// Required if ``kind`` is ``http``. The URL to use to sendnotifications + /// to. MUST be an HTTPS URL with a path of ``/_matrix/push/v1/notify``. + QString url; + /// The format to send notifications in to Push Gateways if the``kind`` + /// is ``http``. The details about what fields thehomeserver should send + /// to the push gateway are defined in the`Push Gateway Specification`_. + /// Currently the only formatavailable is 'event_id_only'. + QString format; }; + + // Construction/destruction + + /*! Modify a pusher for this user on the homeserver. + * \param pushkey + * This is a unique identifier for this pusher. The value you + * should use for this is the routing or destination address + * information for the notification, for example, the APNS token + * for APNS or the Registration ID for GCM. If your notification + * client has no such concept, use any unique identifier. + * Max length, 512 bytes. + * + * If the ``kind`` is ``"email"``, this is the email address to + * send notifications to. + * \param kind + * The kind of pusher to configure. ``"http"`` makes a pusher that + * sends HTTP pokes. ``"email"`` makes a pusher that emails the + * user with unread notifications. ``null`` deletes the pusher. + * \param appId + * This is a reverse-DNS style identifier for the application. + * It is recommended that this end with the platform, such that + * different platform versions get different app identifiers. + * Max length, 64 chars. + * + * If the ``kind`` is ``"email"``, this is ``"m.email"``. + * \param appDisplayName + * A string that will allow the user to identify what application + * owns this pusher. + * \param deviceDisplayName + * A string that will allow the user to identify what device owns + * this pusher. + * \param lang + * The preferred language for receiving notifications (e.g. 'en' + * or 'en-US'). + * \param data + * A dictionary of information for the pusher implementation + * itself. If ``kind`` is ``http``, this should contain ``url`` + * which is the URL to use to send notifications to. + * \param profileTag + * This string determines which set of device specific rules this + * pusher executes. + * \param append + * If true, the homeserver should add another pusher with the + * given pushkey and App ID in addition to any others with + * different user IDs. Otherwise, the homeserver must remove any + * other pushers with the same App ID and pushkey for different + * users. The default is ``false``. + */ + explicit PostPusherJob(const QString& pushkey, const QString& kind, + const QString& appId, const QString& appDisplayName, + const QString& deviceDisplayName, + const QString& lang, const PusherData& data, + const QString& profileTag = {}, + Omittable<bool> append = none); +}; + } // namespace QMatrixClient diff --git a/lib/csapi/pushrules.cpp b/lib/csapi/pushrules.cpp index e70cbbde..5842369f 100644 --- a/lib/csapi/pushrules.cpp +++ b/lib/csapi/pushrules.cpp @@ -14,7 +14,7 @@ static const auto basePath = QStringLiteral("/_matrix/client/r0"); class GetPushRulesJob::Private { - public: +public: PushRuleset global; }; @@ -26,10 +26,9 @@ QUrl GetPushRulesJob::makeRequestUrl(QUrl baseUrl) static const auto GetPushRulesJobName = QStringLiteral("GetPushRulesJob"); GetPushRulesJob::GetPushRulesJob() - : BaseJob(HttpVerb::Get, GetPushRulesJobName, basePath % "/pushrules"), - d(new Private) -{ -} + : BaseJob(HttpVerb::Get, GetPushRulesJobName, basePath % "/pushrules") + , d(new Private) +{} GetPushRulesJob::~GetPushRulesJob() = default; @@ -39,23 +38,25 @@ BaseJob::Status GetPushRulesJob::parseJson(const QJsonDocument& data) { auto json = data.object(); if (!json.contains("global"_ls)) - return { JsonParseError, "The key 'global' not found in the response" }; + return { IncorrectResponse, + "The key 'global' not found in the response" }; fromJson(json.value("global"_ls), d->global); + return Success; } class GetPushRuleJob::Private { - public: +public: PushRule data; }; QUrl GetPushRuleJob::makeRequestUrl(QUrl baseUrl, const QString& scope, const QString& kind, const QString& ruleId) { - return BaseJob::makeRequestUrl(std::move(baseUrl), - basePath % "/pushrules/" % scope % "/" % kind - % "/" % ruleId); + return BaseJob::makeRequestUrl(std::move(baseUrl), basePath % "/pushrules/" + % scope % "/" % kind + % "/" % ruleId); } static const auto GetPushRuleJobName = QStringLiteral("GetPushRuleJob"); @@ -63,10 +64,9 @@ static const auto GetPushRuleJobName = QStringLiteral("GetPushRuleJob"); GetPushRuleJob::GetPushRuleJob(const QString& scope, const QString& kind, const QString& ruleId) : BaseJob(HttpVerb::Get, GetPushRuleJobName, - basePath % "/pushrules/" % scope % "/" % kind % "/" % ruleId), - d(new Private) -{ -} + basePath % "/pushrules/" % scope % "/" % kind % "/" % ruleId) + , d(new Private) +{} GetPushRuleJob::~GetPushRuleJob() = default; @@ -82,9 +82,9 @@ QUrl DeletePushRuleJob::makeRequestUrl(QUrl baseUrl, const QString& scope, const QString& kind, const QString& ruleId) { - return BaseJob::makeRequestUrl(std::move(baseUrl), - basePath % "/pushrules/" % scope % "/" % kind - % "/" % ruleId); + return BaseJob::makeRequestUrl(std::move(baseUrl), basePath % "/pushrules/" + % scope % "/" % kind + % "/" % ruleId); } static const auto DeletePushRuleJobName = QStringLiteral("DeletePushRuleJob"); @@ -93,8 +93,7 @@ DeletePushRuleJob::DeletePushRuleJob(const QString& scope, const QString& kind, const QString& ruleId) : BaseJob(HttpVerb::Delete, DeletePushRuleJobName, basePath % "/pushrules/" % scope % "/" % kind % "/" % ruleId) -{ -} +{} BaseJob::Query queryToSetPushRule(const QString& before, const QString& after) { @@ -107,8 +106,7 @@ BaseJob::Query queryToSetPushRule(const QString& before, const QString& after) static const auto SetPushRuleJobName = QStringLiteral("SetPushRuleJob"); SetPushRuleJob::SetPushRuleJob(const QString& scope, const QString& kind, - const QString& ruleId, - const QStringList& actions, + const QString& ruleId, const QStringList& actions, const QString& before, const QString& after, const QVector<PushCondition>& conditions, const QString& pattern) @@ -125,7 +123,7 @@ SetPushRuleJob::SetPushRuleJob(const QString& scope, const QString& kind, class IsPushRuleEnabledJob::Private { - public: +public: bool enabled; }; @@ -135,21 +133,20 @@ QUrl IsPushRuleEnabledJob::makeRequestUrl(QUrl baseUrl, const QString& scope, { return BaseJob::makeRequestUrl(std::move(baseUrl), basePath % "/pushrules/" % scope % "/" % kind - % "/" % ruleId % "/enabled"); + % "/" % ruleId % "/enabled"); } static const auto IsPushRuleEnabledJobName = - QStringLiteral("IsPushRuleEnabledJob"); + QStringLiteral("IsPushRuleEnabledJob"); IsPushRuleEnabledJob::IsPushRuleEnabledJob(const QString& scope, const QString& kind, const QString& ruleId) : BaseJob(HttpVerb::Get, IsPushRuleEnabledJobName, basePath % "/pushrules/" % scope % "/" % kind % "/" % ruleId - % "/enabled"), - d(new Private) -{ -} + % "/enabled") + , d(new Private) +{} IsPushRuleEnabledJob::~IsPushRuleEnabledJob() = default; @@ -159,22 +156,22 @@ BaseJob::Status IsPushRuleEnabledJob::parseJson(const QJsonDocument& data) { auto json = data.object(); if (!json.contains("enabled"_ls)) - return { JsonParseError, + return { IncorrectResponse, "The key 'enabled' not found in the response" }; fromJson(json.value("enabled"_ls), d->enabled); + return Success; } static const auto SetPushRuleEnabledJobName = - QStringLiteral("SetPushRuleEnabledJob"); + QStringLiteral("SetPushRuleEnabledJob"); SetPushRuleEnabledJob::SetPushRuleEnabledJob(const QString& scope, const QString& kind, - const QString& ruleId, - bool enabled) + const QString& ruleId, bool enabled) : BaseJob(HttpVerb::Put, SetPushRuleEnabledJobName, basePath % "/pushrules/" % scope % "/" % kind % "/" % ruleId - % "/enabled") + % "/enabled") { QJsonObject _data; addParam<>(_data, QStringLiteral("enabled"), enabled); @@ -183,7 +180,7 @@ SetPushRuleEnabledJob::SetPushRuleEnabledJob(const QString& scope, class GetPushRuleActionsJob::Private { - public: +public: QStringList actions; }; @@ -193,21 +190,20 @@ QUrl GetPushRuleActionsJob::makeRequestUrl(QUrl baseUrl, const QString& scope, { return BaseJob::makeRequestUrl(std::move(baseUrl), basePath % "/pushrules/" % scope % "/" % kind - % "/" % ruleId % "/actions"); + % "/" % ruleId % "/actions"); } static const auto GetPushRuleActionsJobName = - QStringLiteral("GetPushRuleActionsJob"); + QStringLiteral("GetPushRuleActionsJob"); GetPushRuleActionsJob::GetPushRuleActionsJob(const QString& scope, const QString& kind, const QString& ruleId) : BaseJob(HttpVerb::Get, GetPushRuleActionsJobName, basePath % "/pushrules/" % scope % "/" % kind % "/" % ruleId - % "/actions"), - d(new Private) -{ -} + % "/actions") + , d(new Private) +{} GetPushRuleActionsJob::~GetPushRuleActionsJob() = default; @@ -217,14 +213,15 @@ BaseJob::Status GetPushRuleActionsJob::parseJson(const QJsonDocument& data) { auto json = data.object(); if (!json.contains("actions"_ls)) - return { JsonParseError, + return { IncorrectResponse, "The key 'actions' not found in the response" }; fromJson(json.value("actions"_ls), d->actions); + return Success; } static const auto SetPushRuleActionsJobName = - QStringLiteral("SetPushRuleActionsJob"); + QStringLiteral("SetPushRuleActionsJob"); SetPushRuleActionsJob::SetPushRuleActionsJob(const QString& scope, const QString& kind, @@ -232,7 +229,7 @@ SetPushRuleActionsJob::SetPushRuleActionsJob(const QString& scope, const QStringList& actions) : BaseJob(HttpVerb::Put, SetPushRuleActionsJobName, basePath % "/pushrules/" % scope % "/" % kind % "/" % ruleId - % "/actions") + % "/actions") { QJsonObject _data; addParam<>(_data, QStringLiteral("actions"), actions); diff --git a/lib/csapi/pushrules.h b/lib/csapi/pushrules.h index 5191d129..9074addb 100644 --- a/lib/csapi/pushrules.h +++ b/lib/csapi/pushrules.h @@ -4,287 +4,297 @@ #pragma once -#include "jobs/basejob.h" - #include "converters.h" + #include "csapi/definitions/push_condition.h" #include "csapi/definitions/push_rule.h" #include "csapi/definitions/push_ruleset.h" + +#include "jobs/basejob.h" + #include <QtCore/QVector> -namespace QMatrixClient { - // Operations - - /// Retrieve all push rulesets. - /// - /// Retrieve all push rulesets for this user. Clients can "drill-down" on - /// the rulesets by suffixing a ``scope`` to this path e.g. - /// ``/pushrules/global/``. This will return a subset of this data under the - /// specified key e.g. the ``global`` key. - class GetPushRulesJob : public BaseJob - { - public: - explicit GetPushRulesJob(); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetPushRulesJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl); - - ~GetPushRulesJob() override; - - // Result properties - - /// The global ruleset. - const PushRuleset& global() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; - - /// Retrieve a push rule. - /// - /// Retrieve a single specified push rule. - class GetPushRuleJob : public BaseJob - { - public: - /*! Retrieve a push rule. - * \param scope - * ``global`` to specify global rules. - * \param kind - * The kind of rule - * \param ruleId - * The identifier for the rule. - */ - explicit GetPushRuleJob(const QString& scope, const QString& kind, - const QString& ruleId); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetPushRuleJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& scope, - const QString& kind, const QString& ruleId); - - ~GetPushRuleJob() override; - - // Result properties - - /// The push rule. - const PushRule& data() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; - - /// Delete a push rule. - /// - /// This endpoint removes the push rule defined in the path. - class DeletePushRuleJob : public BaseJob - { - public: - /*! Delete a push rule. - * \param scope - * ``global`` to specify global rules. - * \param kind - * The kind of rule - * \param ruleId - * The identifier for the rule. - */ - explicit DeletePushRuleJob(const QString& scope, const QString& kind, +namespace QMatrixClient +{ + +// Operations + +/// Retrieve all push rulesets. +/*! + * Retrieve all push rulesets for this user. Clients can "drill-down" on + * the rulesets by suffixing a ``scope`` to this path e.g. + * ``/pushrules/global/``. This will return a subset of this data under the + * specified key e.g. the ``global`` key. + */ +class GetPushRulesJob : public BaseJob +{ +public: + explicit GetPushRulesJob(); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetPushRulesJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl); + + ~GetPushRulesJob() override; + + // Result properties + + /// The global ruleset. + const PushRuleset& global() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Retrieve a push rule. +/*! + * Retrieve a single specified push rule. + */ +class GetPushRuleJob : public BaseJob +{ +public: + /*! Retrieve a push rule. + * \param scope + * ``global`` to specify global rules. + * \param kind + * The kind of rule + * \param ruleId + * The identifier for the rule. + */ + explicit GetPushRuleJob(const QString& scope, const QString& kind, + const QString& ruleId); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetPushRuleJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& scope, + const QString& kind, const QString& ruleId); + + ~GetPushRuleJob() override; + + // Result properties + + /// The push rule. + const PushRule& data() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Delete a push rule. +/*! + * This endpoint removes the push rule defined in the path. + */ +class DeletePushRuleJob : public BaseJob +{ +public: + /*! Delete a push rule. + * \param scope + * ``global`` to specify global rules. + * \param kind + * The kind of rule + * \param ruleId + * The identifier for the rule. + */ + explicit DeletePushRuleJob(const QString& scope, const QString& kind, + const QString& ruleId); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * DeletePushRuleJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& scope, + const QString& kind, const QString& ruleId); +}; + +/// Add or change a push rule. +/*! + * This endpoint allows the creation, modification and deletion of pushers + * for this user ID. The behaviour of this endpoint varies depending on the + * values in the JSON body. + * + * When creating push rules, they MUST be enabled by default. + */ +class SetPushRuleJob : public BaseJob +{ +public: + /*! Add or change a push rule. + * \param scope + * ``global`` to specify global rules. + * \param kind + * The kind of rule + * \param ruleId + * The identifier for the rule. + * \param actions + * The action(s) to perform when the conditions for this rule are met. + * \param before + * Use 'before' with a ``rule_id`` as its value to make the new rule the + * next-most important rule with respect to the given user defined rule. + * It is not possible to add a rule relative to a predefined server rule. + * \param after + * This makes the new rule the next-less important rule relative to the + * given user defined rule. It is not possible to add a rule relative + * to a predefined server rule. + * \param conditions + * The conditions that must hold true for an event in order for a + * rule to be applied to an event. A rule with no conditions + * always matches. Only applicable to ``underride`` and ``override`` + * rules. \param pattern Only applicable to ``content`` rules. The + * glob-style pattern to match against. + */ + explicit SetPushRuleJob(const QString& scope, const QString& kind, + const QString& ruleId, const QStringList& actions, + const QString& before = {}, + const QString& after = {}, + const QVector<PushCondition>& conditions = {}, + const QString& pattern = {}); +}; + +/// Get whether a push rule is enabled +/*! + * This endpoint gets whether the specified push rule is enabled. + */ +class IsPushRuleEnabledJob : public BaseJob +{ +public: + /*! Get whether a push rule is enabled + * \param scope + * Either ``global`` or ``device/<profile_tag>`` to specify global + * rules or device rules for the given ``profile_tag``. + * \param kind + * The kind of rule + * \param ruleId + * The identifier for the rule. + */ + explicit IsPushRuleEnabledJob(const QString& scope, const QString& kind, + const QString& ruleId); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * IsPushRuleEnabledJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& scope, + const QString& kind, const QString& ruleId); + + ~IsPushRuleEnabledJob() override; + + // Result properties + + /// Whether the push rule is enabled or not. + bool enabled() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Enable or disable a push rule. +/*! + * This endpoint allows clients to enable or disable the specified push rule. + */ +class SetPushRuleEnabledJob : public BaseJob +{ +public: + /*! Enable or disable a push rule. + * \param scope + * ``global`` to specify global rules. + * \param kind + * The kind of rule + * \param ruleId + * The identifier for the rule. + * \param enabled + * Whether the push rule is enabled or not. + */ + explicit SetPushRuleEnabledJob(const QString& scope, const QString& kind, + const QString& ruleId, bool enabled); +}; + +/// The actions for a push rule +/*! + * This endpoint get the actions for the specified push rule. + */ +class GetPushRuleActionsJob : public BaseJob +{ +public: + /*! The actions for a push rule + * \param scope + * Either ``global`` or ``device/<profile_tag>`` to specify global + * rules or device rules for the given ``profile_tag``. + * \param kind + * The kind of rule + * \param ruleId + * The identifier for the rule. + */ + explicit GetPushRuleActionsJob(const QString& scope, const QString& kind, const QString& ruleId); - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * DeletePushRuleJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& scope, - const QString& kind, const QString& ruleId); - }; - - /// Add or change a push rule. - /// - /// This endpoint allows the creation, modification and deletion of pushers - /// for this user ID. The behaviour of this endpoint varies depending on the - /// values in the JSON body. - /// - /// When creating push rules, they MUST be enabled by default. - class SetPushRuleJob : public BaseJob - { - public: - /*! Add or change a push rule. - * \param scope - * ``global`` to specify global rules. - * \param kind - * The kind of rule - * \param ruleId - * The identifier for the rule. - * \param actions - * The action(s) to perform when the conditions for this rule are met. - * \param before - * Use 'before' with a ``rule_id`` as its value to make the new rule - * the next-most important rule with respect to the given user defined - * rule. It is not possible to add a rule relative to a predefined - * server rule. \param after This makes the new rule the next-less - * important rule relative to the given user defined rule. It is not - * possible to add a rule relative to a predefined server rule. \param - * conditions The conditions that must hold true for an event in order - * for a rule to be applied to an event. A rule with no conditions - * always matches. Only applicable to ``underride`` and ``override`` - * rules. \param pattern Only applicable to ``content`` rules. The - * glob-style pattern to match against. - */ - explicit SetPushRuleJob(const QString& scope, const QString& kind, - const QString& ruleId, - const QStringList& actions, - const QString& before = {}, - const QString& after = {}, - const QVector<PushCondition>& conditions = {}, - const QString& pattern = {}); - }; - - /// Get whether a push rule is enabled - /// - /// This endpoint gets whether the specified push rule is enabled. - class IsPushRuleEnabledJob : public BaseJob - { - public: - /*! Get whether a push rule is enabled - * \param scope - * Either ``global`` or ``device/<profile_tag>`` to specify global - * rules or device rules for the given ``profile_tag``. - * \param kind - * The kind of rule - * \param ruleId - * The identifier for the rule. - */ - explicit IsPushRuleEnabledJob(const QString& scope, const QString& kind, - const QString& ruleId); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * IsPushRuleEnabledJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& scope, - const QString& kind, const QString& ruleId); - - ~IsPushRuleEnabledJob() override; - - // Result properties - - /// Whether the push rule is enabled or not. - bool enabled() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; - - /// Enable or disable a push rule. - /// - /// This endpoint allows clients to enable or disable the specified push - /// rule. - class SetPushRuleEnabledJob : public BaseJob - { - public: - /*! Enable or disable a push rule. - * \param scope - * ``global`` to specify global rules. - * \param kind - * The kind of rule - * \param ruleId - * The identifier for the rule. - * \param enabled - * Whether the push rule is enabled or not. - */ - explicit SetPushRuleEnabledJob(const QString& scope, - const QString& kind, - const QString& ruleId, bool enabled); - }; - - /// The actions for a push rule - /// - /// This endpoint get the actions for the specified push rule. - class GetPushRuleActionsJob : public BaseJob - { - public: - /*! The actions for a push rule - * \param scope - * Either ``global`` or ``device/<profile_tag>`` to specify global - * rules or device rules for the given ``profile_tag``. - * \param kind - * The kind of rule - * \param ruleId - * The identifier for the rule. - */ - explicit GetPushRuleActionsJob(const QString& scope, - const QString& kind, - const QString& ruleId); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetPushRuleActionsJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& scope, - const QString& kind, const QString& ruleId); - - ~GetPushRuleActionsJob() override; - - // Result properties - - /// The action(s) to perform for this rule. - const QStringList& actions() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; - - /// Set the actions for a push rule. - /// - /// This endpoint allows clients to change the actions of a push rule. - /// This can be used to change the actions of builtin rules. - class SetPushRuleActionsJob : public BaseJob - { - public: - /*! Set the actions for a push rule. - * \param scope - * ``global`` to specify global rules. - * \param kind - * The kind of rule - * \param ruleId - * The identifier for the rule. - * \param actions - * The action(s) to perform for this rule. - */ - explicit SetPushRuleActionsJob(const QString& scope, - const QString& kind, - const QString& ruleId, - const QStringList& actions); - }; + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetPushRuleActionsJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& scope, + const QString& kind, const QString& ruleId); + + ~GetPushRuleActionsJob() override; + + // Result properties + + /// The action(s) to perform for this rule. + const QStringList& actions() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Set the actions for a push rule. +/*! + * This endpoint allows clients to change the actions of a push rule. + * This can be used to change the actions of builtin rules. + */ +class SetPushRuleActionsJob : public BaseJob +{ +public: + /*! Set the actions for a push rule. + * \param scope + * ``global`` to specify global rules. + * \param kind + * The kind of rule + * \param ruleId + * The identifier for the rule. + * \param actions + * The action(s) to perform for this rule. + */ + explicit SetPushRuleActionsJob(const QString& scope, const QString& kind, + const QString& ruleId, + const QStringList& actions); +}; + } // namespace QMatrixClient diff --git a/lib/csapi/read_markers.h b/lib/csapi/read_markers.h index 6afa5572..e1fbc263 100644 --- a/lib/csapi/read_markers.h +++ b/lib/csapi/read_markers.h @@ -6,29 +6,32 @@ #include "jobs/basejob.h" -namespace QMatrixClient { - // Operations +namespace QMatrixClient +{ + +// Operations + +/// Set the position of the read marker for a room. +/*! + * Sets the position of the read marker for a given room, and optionally + * the read receipt's location. + */ +class SetReadMarkerJob : public BaseJob +{ +public: + /*! Set the position of the read marker for a room. + * \param roomId + * The room ID to set the read marker in for the user. + * \param mFullyRead + * The event ID the read marker should be located at. The + * event MUST belong to the room. + * \param mRead + * The event ID to set the read receipt location at. This is + * equivalent to calling ``/receipt/m.read/$elsewhere:example.org`` + * and is provided here to save that extra call. + */ + explicit SetReadMarkerJob(const QString& roomId, const QString& mFullyRead, + const QString& mRead = {}); +}; - /// Set the position of the read marker for a room. - /// - /// Sets the position of the read marker for a given room, and optionally - /// the read receipt's location. - class SetReadMarkerJob : public BaseJob - { - public: - /*! Set the position of the read marker for a room. - * \param roomId - * The room ID to set the read marker in for the user. - * \param mFullyRead - * The event ID the read marker should be located at. The - * event MUST belong to the room. - * \param mRead - * The event ID to set the read receipt location at. This is - * equivalent to calling ``/receipt/m.read/$elsewhere:example.org`` - * and is provided here to save that extra call. - */ - explicit SetReadMarkerJob(const QString& roomId, - const QString& mFullyRead, - const QString& mRead = {}); - }; } // namespace QMatrixClient diff --git a/lib/csapi/receipts.cpp b/lib/csapi/receipts.cpp index 25d0dd8e..28d7032f 100644 --- a/lib/csapi/receipts.cpp +++ b/lib/csapi/receipts.cpp @@ -14,13 +14,12 @@ static const auto basePath = QStringLiteral("/_matrix/client/r0"); static const auto PostReceiptJobName = QStringLiteral("PostReceiptJob"); -PostReceiptJob::PostReceiptJob(const QString& roomId, - const QString& receiptType, +PostReceiptJob::PostReceiptJob(const QString& roomId, const QString& receiptType, const QString& eventId, const QJsonObject& receipt) : BaseJob(HttpVerb::Post, PostReceiptJobName, basePath % "/rooms/" % roomId % "/receipt/" % receiptType % "/" - % eventId) + % eventId) { setRequestData(Data(toJson(receipt))); } diff --git a/lib/csapi/receipts.h b/lib/csapi/receipts.h index 4e40188a..bb037c08 100644 --- a/lib/csapi/receipts.h +++ b/lib/csapi/receipts.h @@ -8,30 +8,33 @@ #include <QtCore/QJsonObject> -namespace QMatrixClient { - // Operations +namespace QMatrixClient +{ + +// Operations + +/// Send a receipt for the given event ID. +/*! + * This API updates the marker for the given receipt type to the event ID + * specified. + */ +class PostReceiptJob : public BaseJob +{ +public: + /*! Send a receipt for the given event ID. + * \param roomId + * The room in which to send the event. + * \param receiptType + * The type of receipt to send. + * \param eventId + * The event ID to acknowledge up to. + * \param receipt + * Extra receipt information to attach to ``content`` if any. The + * server will automatically set the ``ts`` field. + */ + explicit PostReceiptJob(const QString& roomId, const QString& receiptType, + const QString& eventId, + const QJsonObject& receipt = {}); +}; - /// Send a receipt for the given event ID. - /// - /// This API updates the marker for the given receipt type to the event ID - /// specified. - class PostReceiptJob : public BaseJob - { - public: - /*! Send a receipt for the given event ID. - * \param roomId - * The room in which to send the event. - * \param receiptType - * The type of receipt to send. - * \param eventId - * The event ID to acknowledge up to. - * \param receipt - * Extra receipt information to attach to ``content`` if any. The - * server will automatically set the ``ts`` field. - */ - explicit PostReceiptJob(const QString& roomId, - const QString& receiptType, - const QString& eventId, - const QJsonObject& receipt = {}); - }; } // namespace QMatrixClient diff --git a/lib/csapi/redaction.cpp b/lib/csapi/redaction.cpp index 713c5102..f944cdd4 100644 --- a/lib/csapi/redaction.cpp +++ b/lib/csapi/redaction.cpp @@ -14,7 +14,7 @@ static const auto basePath = QStringLiteral("/_matrix/client/r0"); class RedactEventJob::Private { - public: +public: QString eventId; }; @@ -23,9 +23,8 @@ static const auto RedactEventJobName = QStringLiteral("RedactEventJob"); RedactEventJob::RedactEventJob(const QString& roomId, const QString& eventId, const QString& txnId, const QString& reason) : BaseJob(HttpVerb::Put, RedactEventJobName, - basePath % "/rooms/" % roomId % "/redact/" % eventId % "/" - % txnId), - d(new Private) + basePath % "/rooms/" % roomId % "/redact/" % eventId % "/" % txnId) + , d(new Private) { QJsonObject _data; addParam<IfNotEmpty>(_data, QStringLiteral("reason"), reason); @@ -40,5 +39,6 @@ BaseJob::Status RedactEventJob::parseJson(const QJsonDocument& data) { auto json = data.object(); fromJson(json.value("event_id"_ls), d->eventId); + return Success; } diff --git a/lib/csapi/redaction.h b/lib/csapi/redaction.h index ab235b31..c75421cb 100644 --- a/lib/csapi/redaction.h +++ b/lib/csapi/redaction.h @@ -6,47 +6,51 @@ #include "jobs/basejob.h" -namespace QMatrixClient { - // Operations - - /// Strips all non-integrity-critical information out of an event. - /// - /// Strips all information out of an event which isn't critical to the - /// integrity of the server-side representation of the room. - /// - /// This cannot be undone. - /// - /// Users may redact their own events, and any user with a power level - /// greater than or equal to the `redact` power level of the room may - /// redact events there. - class RedactEventJob : public BaseJob - { - public: - /*! Strips all non-integrity-critical information out of an event. - * \param roomId - * The room from which to redact the event. - * \param eventId - * The ID of the event to redact - * \param txnId - * The transaction ID for this event. Clients should generate a - * unique ID; it will be used by the server to ensure idempotency of - * requests. \param reason The reason for the event being redacted. - */ - explicit RedactEventJob(const QString& roomId, const QString& eventId, - const QString& txnId, - const QString& reason = {}); - ~RedactEventJob() override; - - // Result properties - - /// A unique identifier for the event. - const QString& eventId() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; +namespace QMatrixClient +{ + +// Operations + +/// Strips all non-integrity-critical information out of an event. +/*! + * Strips all information out of an event which isn't critical to the + * integrity of the server-side representation of the room. + * + * This cannot be undone. + * + * Users may redact their own events, and any user with a power level + * greater than or equal to the `redact` power level of the room may + * redact events there. + */ +class RedactEventJob : public BaseJob +{ +public: + /*! Strips all non-integrity-critical information out of an event. + * \param roomId + * The room from which to redact the event. + * \param eventId + * The ID of the event to redact + * \param txnId + * The transaction ID for this event. Clients should generate a + * unique ID; it will be used by the server to ensure idempotency of + * requests. \param reason The reason for the event being redacted. + */ + explicit RedactEventJob(const QString& roomId, const QString& eventId, + const QString& txnId, const QString& reason = {}); + + ~RedactEventJob() override; + + // Result properties + + /// A unique identifier for the event. + const QString& eventId() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + } // namespace QMatrixClient diff --git a/lib/csapi/registration.cpp b/lib/csapi/registration.cpp index b5e7d985..52b4098d 100644 --- a/lib/csapi/registration.cpp +++ b/lib/csapi/registration.cpp @@ -14,7 +14,7 @@ static const auto basePath = QStringLiteral("/_matrix/client/r0"); class RegisterJob::Private { - public: +public: QString userId; QString accessToken; QString homeServer; @@ -37,8 +37,8 @@ RegisterJob::RegisterJob(const QString& kind, const QString& initialDeviceDisplayName, Omittable<bool> inhibitLogin) : BaseJob(HttpVerb::Post, RegisterJobName, basePath % "/register", - queryToRegister(kind), {}, false), - d(new Private) + queryToRegister(kind), {}, false) + , d(new Private) { QJsonObject _data; addParam<IfNotEmpty>(_data, QStringLiteral("auth"), auth); @@ -66,30 +66,31 @@ BaseJob::Status RegisterJob::parseJson(const QJsonDocument& data) { auto json = data.object(); if (!json.contains("user_id"_ls)) - return { JsonParseError, + return { IncorrectResponse, "The key 'user_id' not found in the response" }; fromJson(json.value("user_id"_ls), d->userId); fromJson(json.value("access_token"_ls), d->accessToken); fromJson(json.value("home_server"_ls), d->homeServer); fromJson(json.value("device_id"_ls), d->deviceId); + return Success; } class RequestTokenToRegisterEmailJob::Private { - public: +public: Sid data; }; static const auto RequestTokenToRegisterEmailJobName = - QStringLiteral("RequestTokenToRegisterEmailJob"); + QStringLiteral("RequestTokenToRegisterEmailJob"); RequestTokenToRegisterEmailJob::RequestTokenToRegisterEmailJob( - const QString& clientSecret, const QString& email, int sendAttempt, - const QString& idServer, const QString& nextLink) + const QString& clientSecret, const QString& email, int sendAttempt, + const QString& idServer, const QString& nextLink) : BaseJob(HttpVerb::Post, RequestTokenToRegisterEmailJobName, - basePath % "/register/email/requestToken", false), - d(new Private) + basePath % "/register/email/requestToken", false) + , d(new Private) { QJsonObject _data; addParam<>(_data, QStringLiteral("client_secret"), clientSecret); @@ -113,20 +114,20 @@ RequestTokenToRegisterEmailJob::parseJson(const QJsonDocument& data) class RequestTokenToRegisterMSISDNJob::Private { - public: +public: Sid data; }; static const auto RequestTokenToRegisterMSISDNJobName = - QStringLiteral("RequestTokenToRegisterMSISDNJob"); + QStringLiteral("RequestTokenToRegisterMSISDNJob"); RequestTokenToRegisterMSISDNJob::RequestTokenToRegisterMSISDNJob( - const QString& clientSecret, const QString& country, - const QString& phoneNumber, int sendAttempt, const QString& idServer, - const QString& nextLink) + const QString& clientSecret, const QString& country, + const QString& phoneNumber, int sendAttempt, const QString& idServer, + const QString& nextLink) : BaseJob(HttpVerb::Post, RequestTokenToRegisterMSISDNJobName, - basePath % "/register/msisdn/requestToken", false), - d(new Private) + basePath % "/register/msisdn/requestToken", false) + , d(new Private) { QJsonObject _data; addParam<>(_data, QStringLiteral("client_secret"), clientSecret); @@ -164,19 +165,19 @@ ChangePasswordJob::ChangePasswordJob(const QString& newPassword, class RequestTokenToResetPasswordEmailJob::Private { - public: +public: Sid data; }; static const auto RequestTokenToResetPasswordEmailJobName = - QStringLiteral("RequestTokenToResetPasswordEmailJob"); + QStringLiteral("RequestTokenToResetPasswordEmailJob"); RequestTokenToResetPasswordEmailJob::RequestTokenToResetPasswordEmailJob( - const QString& clientSecret, const QString& email, int sendAttempt, - const QString& idServer, const QString& nextLink) + const QString& clientSecret, const QString& email, int sendAttempt, + const QString& idServer, const QString& nextLink) : BaseJob(HttpVerb::Post, RequestTokenToResetPasswordEmailJobName, - basePath % "/account/password/email/requestToken", false), - d(new Private) + basePath % "/account/password/email/requestToken", false) + , d(new Private) { QJsonObject _data; addParam<>(_data, QStringLiteral("client_secret"), clientSecret); @@ -188,7 +189,7 @@ RequestTokenToResetPasswordEmailJob::RequestTokenToResetPasswordEmailJob( } RequestTokenToResetPasswordEmailJob::~RequestTokenToResetPasswordEmailJob() = - default; + default; const Sid& RequestTokenToResetPasswordEmailJob::data() const { return d->data; } @@ -201,20 +202,20 @@ RequestTokenToResetPasswordEmailJob::parseJson(const QJsonDocument& data) class RequestTokenToResetPasswordMSISDNJob::Private { - public: +public: Sid data; }; static const auto RequestTokenToResetPasswordMSISDNJobName = - QStringLiteral("RequestTokenToResetPasswordMSISDNJob"); + QStringLiteral("RequestTokenToResetPasswordMSISDNJob"); RequestTokenToResetPasswordMSISDNJob::RequestTokenToResetPasswordMSISDNJob( - const QString& clientSecret, const QString& country, - const QString& phoneNumber, int sendAttempt, const QString& idServer, - const QString& nextLink) + const QString& clientSecret, const QString& country, + const QString& phoneNumber, int sendAttempt, const QString& idServer, + const QString& nextLink) : BaseJob(HttpVerb::Post, RequestTokenToResetPasswordMSISDNJobName, - basePath % "/account/password/msisdn/requestToken", false), - d(new Private) + basePath % "/account/password/msisdn/requestToken", false) + , d(new Private) { QJsonObject _data; addParam<>(_data, QStringLiteral("client_secret"), clientSecret); @@ -227,7 +228,7 @@ RequestTokenToResetPasswordMSISDNJob::RequestTokenToResetPasswordMSISDNJob( } RequestTokenToResetPasswordMSISDNJob::~RequestTokenToResetPasswordMSISDNJob() = - default; + default; const Sid& RequestTokenToResetPasswordMSISDNJob::data() const { @@ -242,10 +243,10 @@ RequestTokenToResetPasswordMSISDNJob::parseJson(const QJsonDocument& data) } static const auto DeactivateAccountJobName = - QStringLiteral("DeactivateAccountJob"); + QStringLiteral("DeactivateAccountJob"); DeactivateAccountJob::DeactivateAccountJob( - const Omittable<AuthenticationData>& auth) + const Omittable<AuthenticationData>& auth) : BaseJob(HttpVerb::Post, DeactivateAccountJobName, basePath % "/account/deactivate") { @@ -256,7 +257,7 @@ DeactivateAccountJob::DeactivateAccountJob( class CheckUsernameAvailabilityJob::Private { - public: +public: Omittable<bool> available; }; @@ -276,16 +277,14 @@ QUrl CheckUsernameAvailabilityJob::makeRequestUrl(QUrl baseUrl, } static const auto CheckUsernameAvailabilityJobName = - QStringLiteral("CheckUsernameAvailabilityJob"); + QStringLiteral("CheckUsernameAvailabilityJob"); -CheckUsernameAvailabilityJob::CheckUsernameAvailabilityJob( - const QString& username) +CheckUsernameAvailabilityJob::CheckUsernameAvailabilityJob(const QString& username) : BaseJob(HttpVerb::Get, CheckUsernameAvailabilityJobName, basePath % "/register/available", - queryToCheckUsernameAvailability(username), {}, false), - d(new Private) -{ -} + queryToCheckUsernameAvailability(username), {}, false) + , d(new Private) +{} CheckUsernameAvailabilityJob::~CheckUsernameAvailabilityJob() = default; @@ -294,10 +293,10 @@ Omittable<bool> CheckUsernameAvailabilityJob::available() const return d->available; } -BaseJob::Status -CheckUsernameAvailabilityJob::parseJson(const QJsonDocument& data) +BaseJob::Status CheckUsernameAvailabilityJob::parseJson(const QJsonDocument& data) { auto json = data.object(); fromJson(json.value("available"_ls), d->available); + return Success; } diff --git a/lib/csapi/registration.h b/lib/csapi/registration.h index 02f4ddaf..40f1caa6 100644 --- a/lib/csapi/registration.h +++ b/lib/csapi/registration.h @@ -4,463 +4,480 @@ #pragma once -#include "jobs/basejob.h" - #include "converters.h" + #include "csapi/../identity/definitions/sid.h" #include "csapi/definitions/auth_data.h" -namespace QMatrixClient { - // Operations +#include "jobs/basejob.h" - /// Register for an account on this homeserver. - /// - /// This API endpoint uses the `User-Interactive Authentication API`_. - /// - /// Register for an account on this homeserver. - /// - /// There are two kinds of user account: - /// - /// - `user` accounts. These accounts may use the full API described in this - /// specification. - /// - /// - `guest` accounts. These accounts may have limited permissions and may - /// not be supported by all servers. - /// - /// If registration is successful, this endpoint will issue an access token - /// the client can use to authorize itself in subsequent requests. - /// - /// If the client does not supply a ``device_id``, the server must - /// auto-generate one. - /// - /// The server SHOULD register an account with a User ID based on the - /// ``username`` provided, if any. Note that the grammar of Matrix User ID - /// localparts is restricted, so the server MUST either map the provided - /// ``username`` onto a ``user_id`` in a logical manner, or reject - /// ``username``\s which do not comply to the grammar, with - /// ``M_INVALID_USERNAME``. - /// - /// Matrix clients MUST NOT assume that localpart of the registered - /// ``user_id`` matches the provided ``username``. - /// - /// The returned access token must be associated with the ``device_id`` - /// supplied by the client or generated by the server. The server may - /// invalidate any access token previously associated with that device. See - /// `Relationship between access tokens and devices`_. - class RegisterJob : public BaseJob - { - public: - /*! Register for an account on this homeserver. - * \param kind - * The kind of account to register. Defaults to `user`. - * \param auth - * Additional authentication information for the - * user-interactive authentication API. Note that this - * information is *not* used to define how the registered user - * should be authenticated, but is instead used to - * authenticate the ``register`` call itself. It should be - * left empty, or omitted, unless an earlier call returned an - * response with status code 401. - * \param bindEmail - * If true, the server binds the email used for authentication to - * the Matrix ID with the identity server. - * \param username - * The basis for the localpart of the desired Matrix ID. If omitted, - * the homeserver MUST generate a Matrix ID local part. - * \param password - * The desired password for the account. - * \param deviceId - * ID of the client device. If this does not correspond to a - * known client device, a new device will be created. The server - * will auto-generate a device_id if this is not specified. - * \param initialDeviceDisplayName - * A display name to assign to the newly-created device. Ignored - * if ``device_id`` corresponds to a known device. - * \param inhibitLogin - * If true, an ``access_token`` and ``device_id`` should not be - * returned from this call, therefore preventing an automatic - * login. Defaults to false. - */ - explicit RegisterJob(const QString& kind = QStringLiteral("user"), - const Omittable<AuthenticationData>& auth = none, - Omittable<bool> bindEmail = none, - const QString& username = {}, - const QString& password = {}, - const QString& deviceId = {}, - const QString& initialDeviceDisplayName = {}, - Omittable<bool> inhibitLogin = none); - ~RegisterJob() override; - - // Result properties - - /// The fully-qualified Matrix user ID (MXID) that has been registered. - /// - /// Any user ID returned by this API must conform to the grammar given - /// in the `Matrix specification - /// <https://matrix.org/docs/spec/appendices.html#user-identifiers>`_. - const QString& userId() const; - /// An access token for the account. - /// This access token can then be used to authorize other requests. - /// Required if the ``inhibit_login`` option is false. - const QString& accessToken() const; - /// The server_name of the homeserver on which the account has - /// been registered. - /// - /// **Deprecated**. Clients should extract the server_name from - /// ``user_id`` (by splitting at the first colon) if they require - /// it. Note also that ``homeserver`` is not spelt this way. - const QString& homeServer() const; - /// ID of the registered device. Will be the same as the - /// corresponding parameter in the request, if one was specified. - /// Required if the ``inhibit_login`` option is false. - const QString& deviceId() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; - - /// Begins the validation process for an email to be used during - /// registration. +namespace QMatrixClient +{ + +// Operations + +/// Register for an account on this homeserver. +/*! + * This API endpoint uses the `User-Interactive Authentication API`_. + * + * Register for an account on this homeserver. + * + * There are two kinds of user account: + * + * - `user` accounts. These accounts may use the full API described in this + * specification. + * + * - `guest` accounts. These accounts may have limited permissions and may not + * be supported by all servers. + * + * If registration is successful, this endpoint will issue an access token + * the client can use to authorize itself in subsequent requests. + * + * If the client does not supply a ``device_id``, the server must + * auto-generate one. + * + * The server SHOULD register an account with a User ID based on the + * ``username`` provided, if any. Note that the grammar of Matrix User ID + * localparts is restricted, so the server MUST either map the provided + * ``username`` onto a ``user_id`` in a logical manner, or reject + * ``username``\s which do not comply to the grammar, with + * ``M_INVALID_USERNAME``. + * + * Matrix clients MUST NOT assume that localpart of the registered + * ``user_id`` matches the provided ``username``. + * + * The returned access token must be associated with the ``device_id`` + * supplied by the client or generated by the server. The server may + * invalidate any access token previously associated with that device. See + * `Relationship between access tokens and devices`_. + */ +class RegisterJob : public BaseJob +{ +public: + /*! Register for an account on this homeserver. + * \param kind + * The kind of account to register. Defaults to `user`. + * \param auth + * Additional authentication information for the + * user-interactive authentication API. Note that this + * information is *not* used to define how the registered user + * should be authenticated, but is instead used to + * authenticate the ``register`` call itself. It should be + * left empty, or omitted, unless an earlier call returned an + * response with status code 401. + * \param bindEmail + * If true, the server binds the email used for authentication to + * the Matrix ID with the identity server. + * \param username + * The basis for the localpart of the desired Matrix ID. If omitted, + * the homeserver MUST generate a Matrix ID local part. + * \param password + * The desired password for the account. + * \param deviceId + * ID of the client device. If this does not correspond to a + * known client device, a new device will be created. The server + * will auto-generate a device_id if this is not specified. + * \param initialDeviceDisplayName + * A display name to assign to the newly-created device. Ignored + * if ``device_id`` corresponds to a known device. + * \param inhibitLogin + * If true, an ``access_token`` and ``device_id`` should not be + * returned from this call, therefore preventing an automatic + * login. Defaults to false. + */ + explicit RegisterJob(const QString& kind = QStringLiteral("user"), + const Omittable<AuthenticationData>& auth = none, + Omittable<bool> bindEmail = none, + const QString& username = {}, + const QString& password = {}, + const QString& deviceId = {}, + const QString& initialDeviceDisplayName = {}, + Omittable<bool> inhibitLogin = none); + + ~RegisterJob() override; + + // Result properties + + /// The fully-qualified Matrix user ID (MXID) that has been registered. /// - /// Proxies the Identity Service API ``validate/email/requestToken``, but - /// first checks that the given email address is not already associated - /// with an account on this homeserver. See the Identity Service API for - /// further information. - class RequestTokenToRegisterEmailJob : public BaseJob - { - public: - /*! Begins the validation process for an email to be used during registration. - * \param clientSecret - * A unique string generated by the client, and used to identify the - * validation attempt. It must be a string consisting of the - * characters - * ``[0-9a-zA-Z.=_-]``. Its length must not exceed 255 characters and - * it must not be empty. \param email The email address to validate. - * \param sendAttempt - * The server will only send an email if the ``send_attempt`` - * is a number greater than the most recent one which it has seen, - * scoped to that ``email`` + ``client_secret`` pair. This is to - * avoid repeatedly sending the same email in the case of request - * retries between the POSTing user and the identity server. - * The client should increment this value if they desire a new - * email (e.g. a reminder) to be sent. - * \param idServer - * The hostname of the identity server to communicate with. May - * optionally include a port. - * \param nextLink - * Optional. When the validation is completed, the identity - * server will redirect the user to this URL. - */ - explicit RequestTokenToRegisterEmailJob(const QString& clientSecret, - const QString& email, - int sendAttempt, - const QString& idServer, - const QString& nextLink = {}); - ~RequestTokenToRegisterEmailJob() override; - - // Result properties - - /// An email has been sent to the specified address. - /// Note that this may be an email containing the validation token or it - /// may be informing the user of an error. - const Sid& data() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; - - /// Requests a validation token be sent to the given phone number for the - /// purpose of registering an account + /// Any user ID returned by this API must conform to the grammar given in + /// the `Matrix specification + /// <https://matrix.org/docs/spec/appendices.html#user-identifiers>`_. + const QString& userId() const; + /// An access token for the account. + /// This access token can then be used to authorize other requests. + /// Required if the ``inhibit_login`` option is false. + const QString& accessToken() const; + /// The server_name of the homeserver on which the account has + /// been registered. /// - /// Proxies the Identity Service API ``validate/msisdn/requestToken``, but - /// first checks that the given phone number is not already associated - /// with an account on this homeserver. See the Identity Service API for - /// further information. - class RequestTokenToRegisterMSISDNJob : public BaseJob - { - public: - /*! Requests a validation token be sent to the given phone number for the purpose of registering an account - * \param clientSecret - * A unique string generated by the client, and used to identify the - * validation attempt. It must be a string consisting of the - * characters - * ``[0-9a-zA-Z.=_-]``. Its length must not exceed 255 characters and - * it must not be empty. \param country The two-letter uppercase ISO - * country code that the number in - * ``phone_number`` should be parsed as if it were dialled from. - * \param phoneNumber - * The phone number to validate. - * \param sendAttempt - * The server will only send an SMS if the ``send_attempt`` is a - * number greater than the most recent one which it has seen, - * scoped to that ``country`` + ``phone_number`` + ``client_secret`` - * triple. This is to avoid repeatedly sending the same SMS in - * the case of request retries between the POSTing user and the - * identity server. The client should increment this value if - * they desire a new SMS (e.g. a reminder) to be sent. - * \param idServer - * The hostname of the identity server to communicate with. May - * optionally include a port. - * \param nextLink - * Optional. When the validation is completed, the identity - * server will redirect the user to this URL. - */ - explicit RequestTokenToRegisterMSISDNJob(const QString& clientSecret, - const QString& country, - const QString& phoneNumber, + /// **Deprecated**. Clients should extract the server_name from + /// ``user_id`` (by splitting at the first colon) if they require + /// it. Note also that ``homeserver`` is not spelt this way. + const QString& homeServer() const; + /// ID of the registered device. Will be the same as the + /// corresponding parameter in the request, if one was specified. + /// Required if the ``inhibit_login`` option is false. + const QString& deviceId() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Begins the validation process for an email to be used during registration. +/*! + * Proxies the Identity Service API ``validate/email/requestToken``, but + * first checks that the given email address is not already associated + * with an account on this homeserver. See the Identity Service API for + * further information. + */ +class RequestTokenToRegisterEmailJob : public BaseJob +{ +public: + /*! Begins the validation process for an email to be used during + * registration. \param clientSecret A unique string generated by the + * client, and used to identify the validation attempt. It must be a string + * consisting of the characters + * ``[0-9a-zA-Z.=_-]``. Its length must not exceed 255 characters and it + * must not be empty. + * \param email + * The email address to validate. + * \param sendAttempt + * The server will only send an email if the ``send_attempt`` + * is a number greater than the most recent one which it has seen, + * scoped to that ``email`` + ``client_secret`` pair. This is to + * avoid repeatedly sending the same email in the case of request + * retries between the POSTing user and the identity server. + * The client should increment this value if they desire a new + * email (e.g. a reminder) to be sent. + * \param idServer + * The hostname of the identity server to communicate with. May + * optionally include a port. + * \param nextLink + * Optional. When the validation is completed, the identity + * server will redirect the user to this URL. + */ + explicit RequestTokenToRegisterEmailJob(const QString& clientSecret, + const QString& email, + int sendAttempt, + const QString& idServer, + const QString& nextLink = {}); + + ~RequestTokenToRegisterEmailJob() override; + + // Result properties + + /// An email has been sent to the specified address. + /// Note that this may be an email containing the validation token or it may + /// be informing the user of an error. + const Sid& data() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Requests a validation token be sent to the given phone number for the +/// purpose of registering an account +/*! + * Proxies the Identity Service API ``validate/msisdn/requestToken``, but + * first checks that the given phone number is not already associated + * with an account on this homeserver. See the Identity Service API for + * further information. + */ +class RequestTokenToRegisterMSISDNJob : public BaseJob +{ +public: + /*! Requests a validation token be sent to the given phone number for the + * purpose of registering an account \param clientSecret A unique string + * generated by the client, and used to identify the validation attempt. It + * must be a string consisting of the characters + * ``[0-9a-zA-Z.=_-]``. Its length must not exceed 255 characters and it + * must not be empty. + * \param country + * The two-letter uppercase ISO country code that the number in + * ``phone_number`` should be parsed as if it were dialled from. + * \param phoneNumber + * The phone number to validate. + * \param sendAttempt + * The server will only send an SMS if the ``send_attempt`` is a + * number greater than the most recent one which it has seen, + * scoped to that ``country`` + ``phone_number`` + ``client_secret`` + * triple. This is to avoid repeatedly sending the same SMS in + * the case of request retries between the POSTing user and the + * identity server. The client should increment this value if + * they desire a new SMS (e.g. a reminder) to be sent. + * \param idServer + * The hostname of the identity server to communicate with. May + * optionally include a port. + * \param nextLink + * Optional. When the validation is completed, the identity + * server will redirect the user to this URL. + */ + explicit RequestTokenToRegisterMSISDNJob(const QString& clientSecret, + const QString& country, + const QString& phoneNumber, + int sendAttempt, + const QString& idServer, + const QString& nextLink = {}); + + ~RequestTokenToRegisterMSISDNJob() override; + + // Result properties + + /// An SMS message has been sent to the specified phone number. + /// Note that this may be an SMS message containing the validation token or + /// it may be informing the user of an error. + const Sid& data() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Changes a user's password. +/*! + * Changes the password for an account on this homeserver. + * + * This API endpoint uses the `User-Interactive Authentication API`_. + * + * An access token should be submitted to this endpoint if the client has + * an active session. + * + * The homeserver may change the flows available depending on whether a + * valid access token is provided. + */ +class ChangePasswordJob : public BaseJob +{ +public: + /*! Changes a user's password. + * \param newPassword + * The new password for the account. + * \param auth + * Additional authentication information for the user-interactive + * authentication API. + */ + explicit ChangePasswordJob(const QString& newPassword, + const Omittable<AuthenticationData>& auth = none); +}; + +/// Requests a validation token be sent to the given email address for the +/// purpose of resetting a user's password +/*! + * Proxies the Identity Service API ``validate/email/requestToken``, but + * first checks that the given email address **is** associated with an account + * on this homeserver. This API should be used to request + * validation tokens when authenticating for the + * `account/password` endpoint. This API's parameters and response are + * identical to that of the HS API |/register/email/requestToken|_ except that + * `M_THREEPID_NOT_FOUND` may be returned if no account matching the + * given email address could be found. The server may instead send an + * email to the given address prompting the user to create an account. + * `M_THREEPID_IN_USE` may not be returned. + * + * .. |/register/email/requestToken| replace:: ``/register/email/requestToken`` + * + * .. _/register/email/requestToken: + * #post-matrix-client-r0-register-email-requesttoken + */ +class RequestTokenToResetPasswordEmailJob : public BaseJob +{ +public: + /*! Requests a validation token be sent to the given email address for the + * purpose of resetting a user's password \param clientSecret A unique + * string generated by the client, and used to identify the validation + * attempt. It must be a string consisting of the characters + * ``[0-9a-zA-Z.=_-]``. Its length must not exceed 255 characters and it + * must not be empty. + * \param email + * The email address to validate. + * \param sendAttempt + * The server will only send an email if the ``send_attempt`` + * is a number greater than the most recent one which it has seen, + * scoped to that ``email`` + ``client_secret`` pair. This is to + * avoid repeatedly sending the same email in the case of request + * retries between the POSTing user and the identity server. + * The client should increment this value if they desire a new + * email (e.g. a reminder) to be sent. + * \param idServer + * The hostname of the identity server to communicate with. May + * optionally include a port. + * \param nextLink + * Optional. When the validation is completed, the identity + * server will redirect the user to this URL. + */ + explicit RequestTokenToResetPasswordEmailJob(const QString& clientSecret, + const QString& email, int sendAttempt, const QString& idServer, const QString& nextLink = {}); - ~RequestTokenToRegisterMSISDNJob() override; - - // Result properties - - /// An SMS message has been sent to the specified phone number. - /// Note that this may be an SMS message containing the validation token - /// or it may be informing the user of an error. - const Sid& data() const; - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; + ~RequestTokenToResetPasswordEmailJob() override; + + // Result properties + + /// An email was sent to the given address. + const Sid& data() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Requests a validation token be sent to the given phone number for the +/// purpose of resetting a user's password. +/*! + * Proxies the Identity Service API ``validate/msisdn/requestToken``, but + * first checks that the given phone number **is** associated with an account + * on this homeserver. This API should be used to request + * validation tokens when authenticating for the + * `account/password` endpoint. This API's parameters and response are + * identical to that of the HS API |/register/msisdn/requestToken|_ except that + * `M_THREEPID_NOT_FOUND` may be returned if no account matching the + * given phone number could be found. The server may instead send an + * SMS message to the given address prompting the user to create an account. + * `M_THREEPID_IN_USE` may not be returned. + * + * .. |/register/msisdn/requestToken| replace:: ``/register/msisdn/requestToken`` + * + * .. _/register/msisdn/requestToken: + * #post-matrix-client-r0-register-email-requesttoken + */ +class RequestTokenToResetPasswordMSISDNJob : public BaseJob +{ +public: + /*! Requests a validation token be sent to the given phone number for the + * purpose of resetting a user's password. \param clientSecret A unique + * string generated by the client, and used to identify the validation + * attempt. It must be a string consisting of the characters + * ``[0-9a-zA-Z.=_-]``. Its length must not exceed 255 characters and it + * must not be empty. + * \param country + * The two-letter uppercase ISO country code that the number in + * ``phone_number`` should be parsed as if it were dialled from. + * \param phoneNumber + * The phone number to validate. + * \param sendAttempt + * The server will only send an SMS if the ``send_attempt`` is a + * number greater than the most recent one which it has seen, + * scoped to that ``country`` + ``phone_number`` + ``client_secret`` + * triple. This is to avoid repeatedly sending the same SMS in + * the case of request retries between the POSTing user and the + * identity server. The client should increment this value if + * they desire a new SMS (e.g. a reminder) to be sent. + * \param idServer + * The hostname of the identity server to communicate with. May + * optionally include a port. + * \param nextLink + * Optional. When the validation is completed, the identity + * server will redirect the user to this URL. + */ + explicit RequestTokenToResetPasswordMSISDNJob(const QString& clientSecret, + const QString& country, + const QString& phoneNumber, + int sendAttempt, + const QString& idServer, + const QString& nextLink = {}); + + ~RequestTokenToResetPasswordMSISDNJob() override; + + // Result properties + + /// An SMS message was sent to the given phone number. + const Sid& data() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Deactivate a user's account. +/*! + * Deactivate the user's account, removing all ability for the user to + * login again. + * + * This API endpoint uses the `User-Interactive Authentication API`_. + * + * An access token should be submitted to this endpoint if the client has + * an active session. + * + * The homeserver may change the flows available depending on whether a + * valid access token is provided. + */ +class DeactivateAccountJob : public BaseJob +{ +public: + /*! Deactivate a user's account. + * \param auth + * Additional authentication information for the user-interactive + * authentication API. + */ + explicit DeactivateAccountJob( + const Omittable<AuthenticationData>& auth = none); +}; + +/// Checks to see if a username is available on the server. +/*! + * Checks to see if a username is available, and valid, for the server. + * + * The server should check to ensure that, at the time of the request, the + * username requested is available for use. This includes verifying that an + * application service has not claimed the username and that the username + * fits the server's desired requirements (for example, a server could dictate + * that it does not permit usernames with underscores). + * + * Matrix clients may wish to use this API prior to attempting registration, + * however the clients must also be aware that using this API does not normally + * reserve the username. This can mean that the username becomes unavailable + * between checking its availability and attempting to register it. + */ +class CheckUsernameAvailabilityJob : public BaseJob +{ +public: + /*! Checks to see if a username is available on the server. + * \param username + * The username to check the availability of. + */ + explicit CheckUsernameAvailabilityJob(const QString& username); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * CheckUsernameAvailabilityJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& username); + + ~CheckUsernameAvailabilityJob() override; + + // Result properties + + /// A flag to indicate that the username is available. This should always + /// be ``true`` when the server replies with 200 OK. + Omittable<bool> available() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; - /// Changes a user's password. - /// - /// Changes the password for an account on this homeserver. - /// - /// This API endpoint uses the `User-Interactive Authentication API`_. - /// - /// An access token should be submitted to this endpoint if the client has - /// an active session. - /// - /// The homeserver may change the flows available depending on whether a - /// valid access token is provided. - class ChangePasswordJob : public BaseJob - { - public: - /*! Changes a user's password. - * \param newPassword - * The new password for the account. - * \param auth - * Additional authentication information for the user-interactive - * authentication API. - */ - explicit ChangePasswordJob( - const QString& newPassword, - const Omittable<AuthenticationData>& auth = none); - }; - - /// Requests a validation token be sent to the given email address for the - /// purpose of resetting a user's password - /// - /// Proxies the Identity Service API ``validate/email/requestToken``, but - /// first checks that the given email address **is** associated with an - /// account on this homeserver. This API should be used to request - /// validation tokens when authenticating for the - /// `account/password` endpoint. This API's parameters and response are - /// identical to that of the HS API |/register/email/requestToken|_ except - /// that `M_THREEPID_NOT_FOUND` may be returned if no account matching the - /// given email address could be found. The server may instead send an - /// email to the given address prompting the user to create an account. - /// `M_THREEPID_IN_USE` may not be returned. - /// - /// .. |/register/email/requestToken| replace:: - /// ``/register/email/requestToken`` - /// - /// .. _/register/email/requestToken: - /// #post-matrix-client-r0-register-email-requesttoken - class RequestTokenToResetPasswordEmailJob : public BaseJob - { - public: - /*! Requests a validation token be sent to the given email address for the purpose of resetting a user's password - * \param clientSecret - * A unique string generated by the client, and used to identify the - * validation attempt. It must be a string consisting of the - * characters - * ``[0-9a-zA-Z.=_-]``. Its length must not exceed 255 characters and - * it must not be empty. \param email The email address to validate. - * \param sendAttempt - * The server will only send an email if the ``send_attempt`` - * is a number greater than the most recent one which it has seen, - * scoped to that ``email`` + ``client_secret`` pair. This is to - * avoid repeatedly sending the same email in the case of request - * retries between the POSTing user and the identity server. - * The client should increment this value if they desire a new - * email (e.g. a reminder) to be sent. - * \param idServer - * The hostname of the identity server to communicate with. May - * optionally include a port. - * \param nextLink - * Optional. When the validation is completed, the identity - * server will redirect the user to this URL. - */ - explicit RequestTokenToResetPasswordEmailJob( - const QString& clientSecret, const QString& email, - int sendAttempt, const QString& idServer, - const QString& nextLink = {}); - ~RequestTokenToResetPasswordEmailJob() override; - - // Result properties - - /// An email was sent to the given address. - const Sid& data() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; - - /// Requests a validation token be sent to the given phone number for the - /// purpose of resetting a user's password. - /// - /// Proxies the Identity Service API ``validate/msisdn/requestToken``, but - /// first checks that the given phone number **is** associated with an - /// account on this homeserver. This API should be used to request - /// validation tokens when authenticating for the - /// `account/password` endpoint. This API's parameters and response are - /// identical to that of the HS API |/register/msisdn/requestToken|_ except - /// that `M_THREEPID_NOT_FOUND` may be returned if no account matching the - /// given phone number could be found. The server may instead send an - /// SMS message to the given address prompting the user to create an - /// account. `M_THREEPID_IN_USE` may not be returned. - /// - /// .. |/register/msisdn/requestToken| replace:: - /// ``/register/msisdn/requestToken`` - /// - /// .. _/register/msisdn/requestToken: - /// #post-matrix-client-r0-register-email-requesttoken - class RequestTokenToResetPasswordMSISDNJob : public BaseJob - { - public: - /*! Requests a validation token be sent to the given phone number for the purpose of resetting a user's password. - * \param clientSecret - * A unique string generated by the client, and used to identify the - * validation attempt. It must be a string consisting of the - * characters - * ``[0-9a-zA-Z.=_-]``. Its length must not exceed 255 characters and - * it must not be empty. \param country The two-letter uppercase ISO - * country code that the number in - * ``phone_number`` should be parsed as if it were dialled from. - * \param phoneNumber - * The phone number to validate. - * \param sendAttempt - * The server will only send an SMS if the ``send_attempt`` is a - * number greater than the most recent one which it has seen, - * scoped to that ``country`` + ``phone_number`` + ``client_secret`` - * triple. This is to avoid repeatedly sending the same SMS in - * the case of request retries between the POSTing user and the - * identity server. The client should increment this value if - * they desire a new SMS (e.g. a reminder) to be sent. - * \param idServer - * The hostname of the identity server to communicate with. May - * optionally include a port. - * \param nextLink - * Optional. When the validation is completed, the identity - * server will redirect the user to this URL. - */ - explicit RequestTokenToResetPasswordMSISDNJob( - const QString& clientSecret, const QString& country, - const QString& phoneNumber, int sendAttempt, - const QString& idServer, const QString& nextLink = {}); - ~RequestTokenToResetPasswordMSISDNJob() override; - - // Result properties - - /// An SMS message was sent to the given phone number. - const Sid& data() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; - - /// Deactivate a user's account. - /// - /// Deactivate the user's account, removing all ability for the user to - /// login again. - /// - /// This API endpoint uses the `User-Interactive Authentication API`_. - /// - /// An access token should be submitted to this endpoint if the client has - /// an active session. - /// - /// The homeserver may change the flows available depending on whether a - /// valid access token is provided. - class DeactivateAccountJob : public BaseJob - { - public: - /*! Deactivate a user's account. - * \param auth - * Additional authentication information for the user-interactive - * authentication API. - */ - explicit DeactivateAccountJob( - const Omittable<AuthenticationData>& auth = none); - }; - - /// Checks to see if a username is available on the server. - /// - /// Checks to see if a username is available, and valid, for the server. - /// - /// The server should check to ensure that, at the time of the request, the - /// username requested is available for use. This includes verifying that an - /// application service has not claimed the username and that the username - /// fits the server's desired requirements (for example, a server could - /// dictate that it does not permit usernames with underscores). - /// - /// Matrix clients may wish to use this API prior to attempting - /// registration, however the clients must also be aware that using this API - /// does not normally reserve the username. This can mean that the username - /// becomes unavailable between checking its availability and attempting to - /// register it. - class CheckUsernameAvailabilityJob : public BaseJob - { - public: - /*! Checks to see if a username is available on the server. - * \param username - * The username to check the availability of. - */ - explicit CheckUsernameAvailabilityJob(const QString& username); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * CheckUsernameAvailabilityJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& username); - - ~CheckUsernameAvailabilityJob() override; - - // Result properties - - /// A flag to indicate that the username is available. This should - /// always be ``true`` when the server replies with 200 OK. - Omittable<bool> available() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; } // namespace QMatrixClient diff --git a/lib/csapi/report_content.cpp b/lib/csapi/report_content.cpp index f7b74834..eb62cd12 100644 --- a/lib/csapi/report_content.cpp +++ b/lib/csapi/report_content.cpp @@ -14,9 +14,8 @@ static const auto basePath = QStringLiteral("/_matrix/client/r0"); static const auto ReportContentJobName = QStringLiteral("ReportContentJob"); -ReportContentJob::ReportContentJob(const QString& roomId, - const QString& eventId, int score, - const QString& reason) +ReportContentJob::ReportContentJob(const QString& roomId, const QString& eventId, + int score, const QString& reason) : BaseJob(HttpVerb::Post, ReportContentJobName, basePath % "/rooms/" % roomId % "/report/" % eventId) { diff --git a/lib/csapi/report_content.h b/lib/csapi/report_content.h index aca5b30b..c545d800 100644 --- a/lib/csapi/report_content.h +++ b/lib/csapi/report_content.h @@ -4,32 +4,36 @@ #pragma once +#include "converters.h" + #include "jobs/basejob.h" -#include "converters.h" +namespace QMatrixClient +{ -namespace QMatrixClient { - // Operations +// Operations + +/// Reports an event as inappropriate. +/*! + * Reports an event as inappropriate to the server, which may then notify + * the appropriate people. + */ +class ReportContentJob : public BaseJob +{ +public: + /*! Reports an event as inappropriate. + * \param roomId + * The room in which the event being reported is located. + * \param eventId + * The event to report. + * \param score + * The score to rate this content as where -100 is most offensive + * and 0 is inoffensive. + * \param reason + * The reason the content is being reported. May be blank. + */ + explicit ReportContentJob(const QString& roomId, const QString& eventId, + int score, const QString& reason); +}; - /// Reports an event as inappropriate. - /// - /// Reports an event as inappropriate to the server, which may then notify - /// the appropriate people. - class ReportContentJob : public BaseJob - { - public: - /*! Reports an event as inappropriate. - * \param roomId - * The room in which the event being reported is located. - * \param eventId - * The event to report. - * \param score - * The score to rate this content as where -100 is most offensive - * and 0 is inoffensive. - * \param reason - * The reason the content is being reported. May be blank. - */ - explicit ReportContentJob(const QString& roomId, const QString& eventId, - int score, const QString& reason); - }; } // namespace QMatrixClient diff --git a/lib/csapi/room_send.cpp b/lib/csapi/room_send.cpp index 2bf42522..a29dd99a 100644 --- a/lib/csapi/room_send.cpp +++ b/lib/csapi/room_send.cpp @@ -14,7 +14,7 @@ static const auto basePath = QStringLiteral("/_matrix/client/r0"); class SendMessageJob::Private { - public: +public: QString eventId; }; @@ -23,9 +23,8 @@ static const auto SendMessageJobName = QStringLiteral("SendMessageJob"); SendMessageJob::SendMessageJob(const QString& roomId, const QString& eventType, const QString& txnId, const QJsonObject& body) : BaseJob(HttpVerb::Put, SendMessageJobName, - basePath % "/rooms/" % roomId % "/send/" % eventType % "/" - % txnId), - d(new Private) + basePath % "/rooms/" % roomId % "/send/" % eventType % "/" % txnId) + , d(new Private) { setRequestData(Data(toJson(body))); } @@ -38,5 +37,6 @@ BaseJob::Status SendMessageJob::parseJson(const QJsonDocument& data) { auto json = data.object(); fromJson(json.value("event_id"_ls), d->eventId); + return Success; } diff --git a/lib/csapi/room_send.h b/lib/csapi/room_send.h index 38e246e1..aa2efd79 100644 --- a/lib/csapi/room_send.h +++ b/lib/csapi/room_send.h @@ -8,54 +8,58 @@ #include <QtCore/QJsonObject> -namespace QMatrixClient { - // Operations - - /// Send a message event to the given room. - /// - /// This endpoint is used to send a message event to a room. Message events - /// allow access to historical events and pagination, making them suited - /// for "once-off" activity in a room. - /// - /// The body of the request should be the content object of the event; the - /// fields in this object will vary depending on the type of event. See - /// `Room Events`_ for the m. event specification. - class SendMessageJob : public BaseJob - { - public: - /*! Send a message event to the given room. - * \param roomId - * The room to send the event to. - * \param eventType - * The type of event to send. - * \param txnId - * The transaction ID for this event. Clients should generate an - * ID unique across requests with the same access token; it will be - * used by the server to ensure idempotency of requests. - * \param body - * This endpoint is used to send a message event to a room. Message - * events allow access to historical events and pagination, making them - * suited for "once-off" activity in a room. - * - * The body of the request should be the content object of the event; - * the fields in this object will vary depending on the type of event. - * See `Room Events`_ for the m. event specification. - */ - explicit SendMessageJob(const QString& roomId, const QString& eventType, - const QString& txnId, - const QJsonObject& body = {}); - ~SendMessageJob() override; - - // Result properties - - /// A unique identifier for the event. - const QString& eventId() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; +namespace QMatrixClient +{ + +// Operations + +/// Send a message event to the given room. +/*! + * This endpoint is used to send a message event to a room. Message events + * allow access to historical events and pagination, making them suited + * for "once-off" activity in a room. + * + * The body of the request should be the content object of the event; the + * fields in this object will vary depending on the type of event. See + * `Room Events`_ for the m. event specification. + */ +class SendMessageJob : public BaseJob +{ +public: + /*! Send a message event to the given room. + * \param roomId + * The room to send the event to. + * \param eventType + * The type of event to send. + * \param txnId + * The transaction ID for this event. Clients should generate an + * ID unique across requests with the same access token; it will be + * used by the server to ensure idempotency of requests. + * \param body + * This endpoint is used to send a message event to a room. Message events + * allow access to historical events and pagination, making them suited + * for "once-off" activity in a room. + * + * The body of the request should be the content object of the event; the + * fields in this object will vary depending on the type of event. See + * `Room Events`_ for the m. event specification. + */ + explicit SendMessageJob(const QString& roomId, const QString& eventType, + const QString& txnId, const QJsonObject& body = {}); + + ~SendMessageJob() override; + + // Result properties + + /// A unique identifier for the event. + const QString& eventId() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + } // namespace QMatrixClient diff --git a/lib/csapi/room_state.cpp b/lib/csapi/room_state.cpp index 668a2931..ef4afcd0 100644 --- a/lib/csapi/room_state.cpp +++ b/lib/csapi/room_state.cpp @@ -14,12 +14,12 @@ static const auto basePath = QStringLiteral("/_matrix/client/r0"); class SetRoomStateWithKeyJob::Private { - public: +public: QString eventId; }; static const auto SetRoomStateWithKeyJobName = - QStringLiteral("SetRoomStateWithKeyJob"); + QStringLiteral("SetRoomStateWithKeyJob"); SetRoomStateWithKeyJob::SetRoomStateWithKeyJob(const QString& roomId, const QString& eventType, @@ -27,8 +27,8 @@ SetRoomStateWithKeyJob::SetRoomStateWithKeyJob(const QString& roomId, const QJsonObject& body) : BaseJob(HttpVerb::Put, SetRoomStateWithKeyJobName, basePath % "/rooms/" % roomId % "/state/" % eventType % "/" - % stateKey), - d(new Private) + % stateKey) + , d(new Private) { setRequestData(Data(toJson(body))); } @@ -41,23 +41,23 @@ BaseJob::Status SetRoomStateWithKeyJob::parseJson(const QJsonDocument& data) { auto json = data.object(); fromJson(json.value("event_id"_ls), d->eventId); + return Success; } class SetRoomStateJob::Private { - public: +public: QString eventId; }; static const auto SetRoomStateJobName = QStringLiteral("SetRoomStateJob"); -SetRoomStateJob::SetRoomStateJob(const QString& roomId, - const QString& eventType, +SetRoomStateJob::SetRoomStateJob(const QString& roomId, const QString& eventType, const QJsonObject& body) : BaseJob(HttpVerb::Put, SetRoomStateJobName, - basePath % "/rooms/" % roomId % "/state/" % eventType), - d(new Private) + basePath % "/rooms/" % roomId % "/state/" % eventType) + , d(new Private) { setRequestData(Data(toJson(body))); } @@ -70,5 +70,6 @@ BaseJob::Status SetRoomStateJob::parseJson(const QJsonDocument& data) { auto json = data.object(); fromJson(json.value("event_id"_ls), d->eventId); + return Success; } diff --git a/lib/csapi/room_state.h b/lib/csapi/room_state.h index 07407af2..6ddd5594 100644 --- a/lib/csapi/room_state.h +++ b/lib/csapi/room_state.h @@ -8,120 +8,122 @@ #include <QtCore/QJsonObject> -namespace QMatrixClient { - // Operations - - /// Send a state event to the given room. - /// - /// State events can be sent using this endpoint. These events will be - /// overwritten if ``<room id>``, ``<event type>`` and ``<state key>`` all - /// match. - /// - /// Requests to this endpoint **cannot use transaction IDs** - /// like other ``PUT`` paths because they cannot be differentiated from the - /// ``state_key``. Furthermore, ``POST`` is unsupported on state paths. - /// - /// The body of the request should be the content object of the event; the - /// fields in this object will vary depending on the type of event. See - /// `Room Events`_ for the ``m.`` event specification. - class SetRoomStateWithKeyJob : public BaseJob - { - public: - /*! Send a state event to the given room. - * \param roomId - * The room to set the state in - * \param eventType - * The type of event to send. - * \param stateKey - * The state_key for the state to send. Defaults to the empty string. - * \param body - * State events can be sent using this endpoint. These events will be - * overwritten if ``<room id>``, ``<event type>`` and ``<state key>`` - * all match. - * - * Requests to this endpoint **cannot use transaction IDs** - * like other ``PUT`` paths because they cannot be differentiated from - * the - * ``state_key``. Furthermore, ``POST`` is unsupported on state paths. - * - * The body of the request should be the content object of the event; - * the fields in this object will vary depending on the type of event. - * See `Room Events`_ for the ``m.`` event specification. - */ - explicit SetRoomStateWithKeyJob(const QString& roomId, - const QString& eventType, - const QString& stateKey, - const QJsonObject& body = {}); - ~SetRoomStateWithKeyJob() override; - - // Result properties - - /// A unique identifier for the event. - const QString& eventId() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; - - /// Send a state event to the given room. - /// - /// State events can be sent using this endpoint. This endpoint is - /// equivalent to calling `/rooms/{roomId}/state/{eventType}/{stateKey}` - /// with an empty `stateKey`. Previous state events with matching - /// `<roomId>` and `<eventType>`, and empty `<stateKey>`, will be - /// overwritten. - /// - /// Requests to this endpoint **cannot use transaction IDs** - /// like other ``PUT`` paths because they cannot be differentiated from the - /// ``state_key``. Furthermore, ``POST`` is unsupported on state paths. - /// - /// The body of the request should be the content object of the event; the - /// fields in this object will vary depending on the type of event. See - /// `Room Events`_ for the ``m.`` event specification. - class SetRoomStateJob : public BaseJob - { - public: - /*! Send a state event to the given room. - * \param roomId - * The room to set the state in - * \param eventType - * The type of event to send. - * \param body - * State events can be sent using this endpoint. This endpoint is - * equivalent to calling - * `/rooms/{roomId}/state/{eventType}/{stateKey}` with an empty - * `stateKey`. Previous state events with matching - * `<roomId>` and `<eventType>`, and empty `<stateKey>`, will be - * overwritten. - * - * Requests to this endpoint **cannot use transaction IDs** - * like other ``PUT`` paths because they cannot be differentiated from - * the - * ``state_key``. Furthermore, ``POST`` is unsupported on state paths. - * - * The body of the request should be the content object of the event; - * the fields in this object will vary depending on the type of event. - * See `Room Events`_ for the ``m.`` event specification. - */ - explicit SetRoomStateJob(const QString& roomId, - const QString& eventType, - const QJsonObject& body = {}); - ~SetRoomStateJob() override; - - // Result properties - - /// A unique identifier for the event. - const QString& eventId() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; +namespace QMatrixClient +{ + +// Operations + +/// Send a state event to the given room. +/*! + * State events can be sent using this endpoint. These events will be + * overwritten if ``<room id>``, ``<event type>`` and ``<state key>`` all + * match. + * + * Requests to this endpoint **cannot use transaction IDs** + * like other ``PUT`` paths because they cannot be differentiated from the + * ``state_key``. Furthermore, ``POST`` is unsupported on state paths. + * + * The body of the request should be the content object of the event; the + * fields in this object will vary depending on the type of event. See + * `Room Events`_ for the ``m.`` event specification. + */ +class SetRoomStateWithKeyJob : public BaseJob +{ +public: + /*! Send a state event to the given room. + * \param roomId + * The room to set the state in + * \param eventType + * The type of event to send. + * \param stateKey + * The state_key for the state to send. Defaults to the empty string. + * \param body + * State events can be sent using this endpoint. These events will be + * overwritten if ``<room id>``, ``<event type>`` and ``<state key>`` all + * match. + * + * Requests to this endpoint **cannot use transaction IDs** + * like other ``PUT`` paths because they cannot be differentiated from the + * ``state_key``. Furthermore, ``POST`` is unsupported on state paths. + * + * The body of the request should be the content object of the event; the + * fields in this object will vary depending on the type of event. See + * `Room Events`_ for the ``m.`` event specification. + */ + explicit SetRoomStateWithKeyJob(const QString& roomId, + const QString& eventType, + const QString& stateKey, + const QJsonObject& body = {}); + + ~SetRoomStateWithKeyJob() override; + + // Result properties + + /// A unique identifier for the event. + const QString& eventId() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Send a state event to the given room. +/*! + * State events can be sent using this endpoint. This endpoint is + * equivalent to calling `/rooms/{roomId}/state/{eventType}/{stateKey}` + * with an empty `stateKey`. Previous state events with matching + * `<roomId>` and `<eventType>`, and empty `<stateKey>`, will be overwritten. + * + * Requests to this endpoint **cannot use transaction IDs** + * like other ``PUT`` paths because they cannot be differentiated from the + * ``state_key``. Furthermore, ``POST`` is unsupported on state paths. + * + * The body of the request should be the content object of the event; the + * fields in this object will vary depending on the type of event. See + * `Room Events`_ for the ``m.`` event specification. + */ +class SetRoomStateJob : public BaseJob +{ +public: + /*! Send a state event to the given room. + * \param roomId + * The room to set the state in + * \param eventType + * The type of event to send. + * \param body + * State events can be sent using this endpoint. This endpoint is + * equivalent to calling `/rooms/{roomId}/state/{eventType}/{stateKey}` + * with an empty `stateKey`. Previous state events with matching + * `<roomId>` and `<eventType>`, and empty `<stateKey>`, will be + * overwritten. + * + * Requests to this endpoint **cannot use transaction IDs** + * like other ``PUT`` paths because they cannot be differentiated from the + * ``state_key``. Furthermore, ``POST`` is unsupported on state paths. + * + * The body of the request should be the content object of the event; the + * fields in this object will vary depending on the type of event. See + * `Room Events`_ for the ``m.`` event specification. + */ + explicit SetRoomStateJob(const QString& roomId, const QString& eventType, + const QJsonObject& body = {}); + + ~SetRoomStateJob() override; + + // Result properties + + /// A unique identifier for the event. + const QString& eventId() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + } // namespace QMatrixClient diff --git a/lib/csapi/room_upgrades.cpp b/lib/csapi/room_upgrades.cpp index b9f285e8..a72304d1 100644 --- a/lib/csapi/room_upgrades.cpp +++ b/lib/csapi/room_upgrades.cpp @@ -14,7 +14,7 @@ static const auto basePath = QStringLiteral("/_matrix/client/r0"); class UpgradeRoomJob::Private { - public: +public: QString replacementRoom; }; @@ -22,8 +22,8 @@ static const auto UpgradeRoomJobName = QStringLiteral("UpgradeRoomJob"); UpgradeRoomJob::UpgradeRoomJob(const QString& roomId, const QString& newVersion) : BaseJob(HttpVerb::Post, UpgradeRoomJobName, - basePath % "/rooms/" % roomId % "/upgrade"), - d(new Private) + basePath % "/rooms/" % roomId % "/upgrade") + , d(new Private) { QJsonObject _data; addParam<>(_data, QStringLiteral("new_version"), newVersion); @@ -41,8 +41,9 @@ BaseJob::Status UpgradeRoomJob::parseJson(const QJsonDocument& data) { auto json = data.object(); if (!json.contains("replacement_room"_ls)) - return { JsonParseError, + return { IncorrectResponse, "The key 'replacement_room' not found in the response" }; fromJson(json.value("replacement_room"_ls), d->replacementRoom); + return Success; } diff --git a/lib/csapi/room_upgrades.h b/lib/csapi/room_upgrades.h index df30a562..94520aca 100644 --- a/lib/csapi/room_upgrades.h +++ b/lib/csapi/room_upgrades.h @@ -6,37 +6,39 @@ #include "jobs/basejob.h" -namespace QMatrixClient { - // Operations - - /// Upgrades a room to a new room version. - /// - /// Upgrades the given room to a particular room version, migrating as much - /// data as possible over to the new room. See the `room_upgrades - /// <#room-upgrades>`_ module for more information on what this entails. - class UpgradeRoomJob : public BaseJob - { - public: - /*! Upgrades a room to a new room version. - * \param roomId - * The ID of the room to upgrade. - * \param newVersion - * The new version for the room. - */ - explicit UpgradeRoomJob(const QString& roomId, - const QString& newVersion); - ~UpgradeRoomJob() override; - - // Result properties - - /// The ID of the new room. - const QString& replacementRoom() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; +namespace QMatrixClient +{ + +// Operations + +/// Upgrades a room to a new room version. +/*! + * Upgrades the given room to a particular room version. + */ +class UpgradeRoomJob : public BaseJob +{ +public: + /*! Upgrades a room to a new room version. + * \param roomId + * The ID of the room to upgrade. + * \param newVersion + * The new version for the room. + */ + explicit UpgradeRoomJob(const QString& roomId, const QString& newVersion); + + ~UpgradeRoomJob() override; + + // Result properties + + /// The ID of the new room. + const QString& replacementRoom() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + } // namespace QMatrixClient diff --git a/lib/csapi/rooms.cpp b/lib/csapi/rooms.cpp index b9de276c..280e8d59 100644 --- a/lib/csapi/rooms.cpp +++ b/lib/csapi/rooms.cpp @@ -14,16 +14,16 @@ static const auto basePath = QStringLiteral("/_matrix/client/r0"); class GetOneRoomEventJob::Private { - public: +public: EventPtr data; }; QUrl GetOneRoomEventJob::makeRequestUrl(QUrl baseUrl, const QString& roomId, const QString& eventId) { - return BaseJob::makeRequestUrl(std::move(baseUrl), - basePath % "/rooms/" % roomId % "/event/" - % eventId); + return BaseJob::makeRequestUrl(std::move(baseUrl), basePath % "/rooms/" + % roomId % "/event/" + % eventId); } static const auto GetOneRoomEventJobName = QStringLiteral("GetOneRoomEventJob"); @@ -31,10 +31,9 @@ static const auto GetOneRoomEventJobName = QStringLiteral("GetOneRoomEventJob"); GetOneRoomEventJob::GetOneRoomEventJob(const QString& roomId, const QString& eventId) : BaseJob(HttpVerb::Get, GetOneRoomEventJobName, - basePath % "/rooms/" % roomId % "/event/" % eventId), - d(new Private) -{ -} + basePath % "/rooms/" % roomId % "/event/" % eventId) + , d(new Private) +{} GetOneRoomEventJob::~GetOneRoomEventJob() = default; @@ -52,42 +51,40 @@ QUrl GetRoomStateWithKeyJob::makeRequestUrl(QUrl baseUrl, const QString& roomId, { return BaseJob::makeRequestUrl(std::move(baseUrl), basePath % "/rooms/" % roomId % "/state/" - % eventType % "/" % stateKey); + % eventType % "/" % stateKey); } static const auto GetRoomStateWithKeyJobName = - QStringLiteral("GetRoomStateWithKeyJob"); + QStringLiteral("GetRoomStateWithKeyJob"); GetRoomStateWithKeyJob::GetRoomStateWithKeyJob(const QString& roomId, const QString& eventType, const QString& stateKey) : BaseJob(HttpVerb::Get, GetRoomStateWithKeyJobName, basePath % "/rooms/" % roomId % "/state/" % eventType % "/" - % stateKey) -{ -} + % stateKey) +{} QUrl GetRoomStateByTypeJob::makeRequestUrl(QUrl baseUrl, const QString& roomId, const QString& eventType) { - return BaseJob::makeRequestUrl(std::move(baseUrl), - basePath % "/rooms/" % roomId % "/state/" - % eventType); + return BaseJob::makeRequestUrl(std::move(baseUrl), basePath % "/rooms/" + % roomId % "/state/" + % eventType); } static const auto GetRoomStateByTypeJobName = - QStringLiteral("GetRoomStateByTypeJob"); + QStringLiteral("GetRoomStateByTypeJob"); GetRoomStateByTypeJob::GetRoomStateByTypeJob(const QString& roomId, const QString& eventType) : BaseJob(HttpVerb::Get, GetRoomStateByTypeJobName, basePath % "/rooms/" % roomId % "/state/" % eventType) -{ -} +{} class GetRoomStateJob::Private { - public: +public: StateEvents data; }; @@ -101,10 +98,9 @@ static const auto GetRoomStateJobName = QStringLiteral("GetRoomStateJob"); GetRoomStateJob::GetRoomStateJob(const QString& roomId) : BaseJob(HttpVerb::Get, GetRoomStateJobName, - basePath % "/rooms/" % roomId % "/state"), - d(new Private) -{ -} + basePath % "/rooms/" % roomId % "/state") + , d(new Private) +{} GetRoomStateJob::~GetRoomStateJob() = default; @@ -118,7 +114,7 @@ BaseJob::Status GetRoomStateJob::parseJson(const QJsonDocument& data) class GetMembersByRoomJob::Private { - public: +public: EventsArray<RoomMemberEvent> chunk; }; @@ -139,12 +135,12 @@ QUrl GetMembersByRoomJob::makeRequestUrl(QUrl baseUrl, const QString& roomId, const QString& notMembership) { return BaseJob::makeRequestUrl( - std::move(baseUrl), basePath % "/rooms/" % roomId % "/members", - queryToGetMembersByRoom(at, membership, notMembership)); + std::move(baseUrl), basePath % "/rooms/" % roomId % "/members", + queryToGetMembersByRoom(at, membership, notMembership)); } static const auto GetMembersByRoomJobName = - QStringLiteral("GetMembersByRoomJob"); + QStringLiteral("GetMembersByRoomJob"); GetMembersByRoomJob::GetMembersByRoomJob(const QString& roomId, const QString& at, @@ -152,10 +148,9 @@ GetMembersByRoomJob::GetMembersByRoomJob(const QString& roomId, const QString& notMembership) : BaseJob(HttpVerb::Get, GetMembersByRoomJobName, basePath % "/rooms/" % roomId % "/members", - queryToGetMembersByRoom(at, membership, notMembership)), - d(new Private) -{ -} + queryToGetMembersByRoom(at, membership, notMembership)) + , d(new Private) +{} GetMembersByRoomJob::~GetMembersByRoomJob() = default; @@ -168,46 +163,48 @@ BaseJob::Status GetMembersByRoomJob::parseJson(const QJsonDocument& data) { auto json = data.object(); fromJson(json.value("chunk"_ls), d->chunk); + return Success; } -namespace QMatrixClient { - // Converters - - template <> - struct JsonObjectConverter<GetJoinedMembersByRoomJob::RoomMember> { - static void fillFrom(const QJsonObject& jo, - GetJoinedMembersByRoomJob::RoomMember& result) - { - fromJson(jo.value("display_name"_ls), result.displayName); - fromJson(jo.value("avatar_url"_ls), result.avatarUrl); - } - }; +// Converters +namespace QMatrixClient +{ + +template <> +struct JsonObjectConverter<GetJoinedMembersByRoomJob::RoomMember> +{ + static void fillFrom(const QJsonObject& jo, + GetJoinedMembersByRoomJob::RoomMember& result) + { + fromJson(jo.value("display_name"_ls), result.displayName); + fromJson(jo.value("avatar_url"_ls), result.avatarUrl); + } +}; + } // namespace QMatrixClient class GetJoinedMembersByRoomJob::Private { - public: +public: QHash<QString, RoomMember> joined; }; QUrl GetJoinedMembersByRoomJob::makeRequestUrl(QUrl baseUrl, const QString& roomId) { - return BaseJob::makeRequestUrl(std::move(baseUrl), - basePath % "/rooms/" % roomId - % "/joined_members"); + return BaseJob::makeRequestUrl( + std::move(baseUrl), basePath % "/rooms/" % roomId % "/joined_members"); } static const auto GetJoinedMembersByRoomJobName = - QStringLiteral("GetJoinedMembersByRoomJob"); + QStringLiteral("GetJoinedMembersByRoomJob"); GetJoinedMembersByRoomJob::GetJoinedMembersByRoomJob(const QString& roomId) : BaseJob(HttpVerb::Get, GetJoinedMembersByRoomJobName, - basePath % "/rooms/" % roomId % "/joined_members"), - d(new Private) -{ -} + basePath % "/rooms/" % roomId % "/joined_members") + , d(new Private) +{} GetJoinedMembersByRoomJob::~GetJoinedMembersByRoomJob() = default; @@ -221,5 +218,6 @@ BaseJob::Status GetJoinedMembersByRoomJob::parseJson(const QJsonDocument& data) { auto json = data.object(); fromJson(json.value("joined"_ls), d->joined); + return Success; } diff --git a/lib/csapi/rooms.h b/lib/csapi/rooms.h index 20bdd20e..29d7808e 100644 --- a/lib/csapi/rooms.h +++ b/lib/csapi/rooms.h @@ -4,261 +4,269 @@ #pragma once -#include "jobs/basejob.h" - #include "converters.h" + #include "events/eventloader.h" #include "events/roommemberevent.h" -#include <QtCore/QHash> +#include "jobs/basejob.h" -namespace QMatrixClient { - // Operations +#include <QtCore/QHash> - /// Get a single event by event ID. - /// - /// Get a single event based on ``roomId/eventId``. You must have permission - /// to retrieve this event e.g. by being a member in the room for this - /// event. - class GetOneRoomEventJob : public BaseJob - { - public: - /*! Get a single event by event ID. - * \param roomId - * The ID of the room the event is in. - * \param eventId - * The event ID to get. - */ - explicit GetOneRoomEventJob(const QString& roomId, - const QString& eventId); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetOneRoomEventJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId, - const QString& eventId); - - ~GetOneRoomEventJob() override; - - // Result properties - - /// The full event. - EventPtr&& data(); - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; +namespace QMatrixClient +{ - /// Get the state identified by the type and key. - /// - /// Looks up the contents of a state event in a room. If the user is - /// joined to the room then the state is taken from the current - /// state of the room. If the user has left the room then the state is - /// taken from the state of the room when they left. - class GetRoomStateWithKeyJob : public BaseJob - { - public: - /*! Get the state identified by the type and key. - * \param roomId - * The room to look up the state in. - * \param eventType - * The type of state to look up. - * \param stateKey - * The key of the state to look up. - */ - explicit GetRoomStateWithKeyJob(const QString& roomId, - const QString& eventType, - const QString& stateKey); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetRoomStateWithKeyJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId, - const QString& eventType, - const QString& stateKey); - }; +// Operations - /// Get the state identified by the type, with the empty state key. - /// - /// Looks up the contents of a state event in a room. If the user is - /// joined to the room then the state is taken from the current - /// state of the room. If the user has left the room then the state is - /// taken from the state of the room when they left. - /// - /// This looks up the state event with the empty state key. - class GetRoomStateByTypeJob : public BaseJob - { - public: - /*! Get the state identified by the type, with the empty state key. - * \param roomId - * The room to look up the state in. - * \param eventType - * The type of state to look up. - */ - explicit GetRoomStateByTypeJob(const QString& roomId, - const QString& eventType); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetRoomStateByTypeJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId, +/// Get a single event by event ID. +/*! + * Get a single event based on ``roomId/eventId``. You must have permission to + * retrieve this event e.g. by being a member in the room for this event. + */ +class GetOneRoomEventJob : public BaseJob +{ +public: + /*! Get a single event by event ID. + * \param roomId + * The ID of the room the event is in. + * \param eventId + * The event ID to get. + */ + explicit GetOneRoomEventJob(const QString& roomId, const QString& eventId); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetOneRoomEventJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId, + const QString& eventId); + + ~GetOneRoomEventJob() override; + + // Result properties + + /// The full event. + EventPtr&& data(); + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Get the state identified by the type and key. +/*! + * Looks up the contents of a state event in a room. If the user is + * joined to the room then the state is taken from the current + * state of the room. If the user has left the room then the state is + * taken from the state of the room when they left. + */ +class GetRoomStateWithKeyJob : public BaseJob +{ +public: + /*! Get the state identified by the type and key. + * \param roomId + * The room to look up the state in. + * \param eventType + * The type of state to look up. + * \param stateKey + * The key of the state to look up. + */ + explicit GetRoomStateWithKeyJob(const QString& roomId, + const QString& eventType, + const QString& stateKey); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetRoomStateWithKeyJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId, + const QString& eventType, + const QString& stateKey); +}; + +/// Get the state identified by the type, with the empty state key. +/*! + * Looks up the contents of a state event in a room. If the user is + * joined to the room then the state is taken from the current + * state of the room. If the user has left the room then the state is + * taken from the state of the room when they left. + * + * This looks up the state event with the empty state key. + */ +class GetRoomStateByTypeJob : public BaseJob +{ +public: + /*! Get the state identified by the type, with the empty state key. + * \param roomId + * The room to look up the state in. + * \param eventType + * The type of state to look up. + */ + explicit GetRoomStateByTypeJob(const QString& roomId, const QString& eventType); - }; - /// Get all state events in the current state of a room. - /// - /// Get the state events for the current state of a room. - class GetRoomStateJob : public BaseJob - { - public: - /*! Get all state events in the current state of a room. - * \param roomId - * The room to look up the state for. - */ - explicit GetRoomStateJob(const QString& roomId); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetRoomStateJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId); - - ~GetRoomStateJob() override; - - // Result properties - - /// If the user is a member of the room this will be the - /// current state of the room as a list of events. If the user - /// has left the room then this will be the state of the room - /// when they left as a list of events. - StateEvents&& data(); - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetRoomStateByTypeJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId, + const QString& eventType); +}; + +/// Get all state events in the current state of a room. +/*! + * Get the state events for the current state of a room. + */ +class GetRoomStateJob : public BaseJob +{ +public: + /*! Get all state events in the current state of a room. + * \param roomId + * The room to look up the state for. + */ + explicit GetRoomStateJob(const QString& roomId); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetRoomStateJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId); + + ~GetRoomStateJob() override; + + // Result properties + + /// If the user is a member of the room this will be the + /// current state of the room as a list of events. If the user + /// has left the room then this will be the state of the room + /// when they left as a list of events. + StateEvents&& data(); + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Get the m.room.member events for the room. +/*! + * Get the list of members for this room. + */ +class GetMembersByRoomJob : public BaseJob +{ +public: + /*! Get the m.room.member events for the room. + * \param roomId + * The room to get the member events for. + * \param at + * The token defining the timeline position as-of which to return + * the list of members. This token can be obtained from a batch token + * returned for each room by the sync API, or from + * a ``start``/``end`` token returned by a ``/messages`` request. + * \param membership + * Only return users with the specified membership + * \param notMembership + * Only return users with membership state other than specified + */ + explicit GetMembersByRoomJob(const QString& roomId, const QString& at = {}, + const QString& membership = {}, + const QString& notMembership = {}); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetMembersByRoomJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId, + const QString& at = {}, + const QString& membership = {}, + const QString& notMembership = {}); + + ~GetMembersByRoomJob() override; + + // Result properties - /// Get the m.room.member events for the room. - /// /// Get the list of members for this room. - class GetMembersByRoomJob : public BaseJob - { - public: - /*! Get the m.room.member events for the room. - * \param roomId - * The room to get the member events for. - * \param at - * The token defining the timeline position as-of which to return - * the list of members. This token can be obtained from a batch token - * returned for each room by the sync API, or from - * a ``start``/``end`` token returned by a ``/messages`` request. - * \param membership - * Only return users with the specified membership - * \param notMembership - * Only return users with membership state other than specified - */ - explicit GetMembersByRoomJob(const QString& roomId, - const QString& at = {}, - const QString& membership = {}, - const QString& notMembership = {}); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetMembersByRoomJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId, - const QString& at = {}, - const QString& membership = {}, - const QString& notMembership = {}); - - ~GetMembersByRoomJob() override; - - // Result properties - - /// Get the list of members for this room. - EventsArray<RoomMemberEvent>&& chunk(); - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; + EventsArray<RoomMemberEvent>&& chunk(); + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Gets the list of currently joined users and their profile data. +/*! + * This API returns a map of MXIDs to member info objects for members of the + * room. The current user must be in the room for it to work, unless it is an + * Application Service in which case any of the AS's users must be in the room. + * This API is primarily for Application Services and should be faster to + * respond than ``/members`` as it can be implemented more efficiently on the + * server. + */ +class GetJoinedMembersByRoomJob : public BaseJob +{ +public: + // Inner data structures - /// Gets the list of currently joined users and their profile data. - /// /// This API returns a map of MXIDs to member info objects for members of /// the room. The current user must be in the room for it to work, unless it /// is an Application Service in which case any of the AS's users must be in /// the room. This API is primarily for Application Services and should be /// faster to respond than ``/members`` as it can be implemented more /// efficiently on the server. - class GetJoinedMembersByRoomJob : public BaseJob + struct RoomMember { - public: - // Inner data structures - - /// This API returns a map of MXIDs to member info objects for members - /// of the room. The current user must be in the room for it to work, - /// unless it is an Application Service in which case any of the AS's - /// users must be in the room. This API is primarily for Application - /// Services and should be faster to respond than ``/members`` as it can - /// be implemented more efficiently on the server. - struct RoomMember { - /// The display name of the user this object is representing. - QString displayName; - /// The mxc avatar url of the user this object is representing. - QString avatarUrl; - }; - - // Construction/destruction - - /*! Gets the list of currently joined users and their profile data. - * \param roomId - * The room to get the members of. - */ - explicit GetJoinedMembersByRoomJob(const QString& roomId); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetJoinedMembersByRoomJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId); - - ~GetJoinedMembersByRoomJob() override; - - // Result properties - - /// A map from user ID to a RoomMember object. - const QHash<QString, RoomMember>& joined() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; + /// The display name of the user this object is representing. + QString displayName; + /// The mxc avatar url of the user this object is representing. + QString avatarUrl; }; + + // Construction/destruction + + /*! Gets the list of currently joined users and their profile data. + * \param roomId + * The room to get the members of. + */ + explicit GetJoinedMembersByRoomJob(const QString& roomId); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetJoinedMembersByRoomJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& roomId); + + ~GetJoinedMembersByRoomJob() override; + + // Result properties + + /// A map from user ID to a RoomMember object. + const QHash<QString, RoomMember>& joined() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + } // namespace QMatrixClient diff --git a/lib/csapi/search.cpp b/lib/csapi/search.cpp index 22aaf616..ee1fa70c 100644 --- a/lib/csapi/search.cpp +++ b/lib/csapi/search.cpp @@ -12,126 +12,143 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); -namespace QMatrixClient { - // Converters - - template <> struct JsonObjectConverter<SearchJob::IncludeEventContext> { - static void dumpTo(QJsonObject& jo, - const SearchJob::IncludeEventContext& pod) - { - addParam<IfNotEmpty>(jo, QStringLiteral("before_limit"), - pod.beforeLimit); - addParam<IfNotEmpty>(jo, QStringLiteral("after_limit"), - pod.afterLimit); - addParam<IfNotEmpty>(jo, QStringLiteral("include_profile"), - pod.includeProfile); - } - }; - - template <> struct JsonObjectConverter<SearchJob::Group> { - static void dumpTo(QJsonObject& jo, const SearchJob::Group& pod) - { - addParam<IfNotEmpty>(jo, QStringLiteral("key"), pod.key); - } - }; - - template <> struct JsonObjectConverter<SearchJob::Groupings> { - static void dumpTo(QJsonObject& jo, const SearchJob::Groupings& pod) - { - addParam<IfNotEmpty>(jo, QStringLiteral("group_by"), pod.groupBy); - } - }; - - template <> struct JsonObjectConverter<SearchJob::RoomEventsCriteria> { - static void dumpTo(QJsonObject& jo, - const SearchJob::RoomEventsCriteria& pod) - { - addParam<>(jo, QStringLiteral("search_term"), pod.searchTerm); - addParam<IfNotEmpty>(jo, QStringLiteral("keys"), pod.keys); - addParam<IfNotEmpty>(jo, QStringLiteral("filter"), pod.filter); - addParam<IfNotEmpty>(jo, QStringLiteral("order_by"), pod.orderBy); - addParam<IfNotEmpty>(jo, QStringLiteral("event_context"), - pod.eventContext); - addParam<IfNotEmpty>(jo, QStringLiteral("include_state"), - pod.includeState); - addParam<IfNotEmpty>(jo, QStringLiteral("groupings"), - pod.groupings); - } - }; - - template <> struct JsonObjectConverter<SearchJob::Categories> { - static void dumpTo(QJsonObject& jo, const SearchJob::Categories& pod) - { - addParam<IfNotEmpty>(jo, QStringLiteral("room_events"), - pod.roomEvents); - } - }; - - template <> struct JsonObjectConverter<SearchJob::UserProfile> { - static void fillFrom(const QJsonObject& jo, - SearchJob::UserProfile& result) - { - fromJson(jo.value("displayname"_ls), result.displayname); - fromJson(jo.value("avatar_url"_ls), result.avatarUrl); - } - }; - - template <> struct JsonObjectConverter<SearchJob::EventContext> { - static void fillFrom(const QJsonObject& jo, - SearchJob::EventContext& result) - { - fromJson(jo.value("start"_ls), result.begin); - fromJson(jo.value("end"_ls), result.end); - fromJson(jo.value("profile_info"_ls), result.profileInfo); - fromJson(jo.value("events_before"_ls), result.eventsBefore); - fromJson(jo.value("events_after"_ls), result.eventsAfter); - } - }; - - template <> struct JsonObjectConverter<SearchJob::Result> { - static void fillFrom(const QJsonObject& jo, SearchJob::Result& result) - { - fromJson(jo.value("rank"_ls), result.rank); - fromJson(jo.value("result"_ls), result.result); - fromJson(jo.value("context"_ls), result.context); - } - }; - - template <> struct JsonObjectConverter<SearchJob::GroupValue> { - static void fillFrom(const QJsonObject& jo, - SearchJob::GroupValue& result) - { - fromJson(jo.value("next_batch"_ls), result.nextBatch); - fromJson(jo.value("order"_ls), result.order); - fromJson(jo.value("results"_ls), result.results); - } - }; - - template <> struct JsonObjectConverter<SearchJob::ResultRoomEvents> { - static void fillFrom(const QJsonObject& jo, - SearchJob::ResultRoomEvents& result) - { - fromJson(jo.value("count"_ls), result.count); - fromJson(jo.value("highlights"_ls), result.highlights); - fromJson(jo.value("results"_ls), result.results); - fromJson(jo.value("state"_ls), result.state); - fromJson(jo.value("groups"_ls), result.groups); - fromJson(jo.value("next_batch"_ls), result.nextBatch); - } - }; - - template <> struct JsonObjectConverter<SearchJob::ResultCategories> { - static void fillFrom(const QJsonObject& jo, - SearchJob::ResultCategories& result) - { - fromJson(jo.value("room_events"_ls), result.roomEvents); - } - }; +// Converters +namespace QMatrixClient +{ + +template <> +struct JsonObjectConverter<SearchJob::IncludeEventContext> +{ + static void dumpTo(QJsonObject& jo, + const SearchJob::IncludeEventContext& pod) + { + addParam<IfNotEmpty>(jo, QStringLiteral("before_limit"), + pod.beforeLimit); + addParam<IfNotEmpty>(jo, QStringLiteral("after_limit"), pod.afterLimit); + addParam<IfNotEmpty>(jo, QStringLiteral("include_profile"), + pod.includeProfile); + } +}; + +template <> +struct JsonObjectConverter<SearchJob::Group> +{ + static void dumpTo(QJsonObject& jo, const SearchJob::Group& pod) + { + addParam<IfNotEmpty>(jo, QStringLiteral("key"), pod.key); + } +}; + +template <> +struct JsonObjectConverter<SearchJob::Groupings> +{ + static void dumpTo(QJsonObject& jo, const SearchJob::Groupings& pod) + { + addParam<IfNotEmpty>(jo, QStringLiteral("group_by"), pod.groupBy); + } +}; + +template <> +struct JsonObjectConverter<SearchJob::RoomEventsCriteria> +{ + static void dumpTo(QJsonObject& jo, const SearchJob::RoomEventsCriteria& pod) + { + addParam<>(jo, QStringLiteral("search_term"), pod.searchTerm); + addParam<IfNotEmpty>(jo, QStringLiteral("keys"), pod.keys); + addParam<IfNotEmpty>(jo, QStringLiteral("filter"), pod.filter); + addParam<IfNotEmpty>(jo, QStringLiteral("order_by"), pod.orderBy); + addParam<IfNotEmpty>(jo, QStringLiteral("event_context"), + pod.eventContext); + addParam<IfNotEmpty>(jo, QStringLiteral("include_state"), + pod.includeState); + addParam<IfNotEmpty>(jo, QStringLiteral("groupings"), pod.groupings); + } +}; + +template <> +struct JsonObjectConverter<SearchJob::Categories> +{ + static void dumpTo(QJsonObject& jo, const SearchJob::Categories& pod) + { + addParam<IfNotEmpty>(jo, QStringLiteral("room_events"), pod.roomEvents); + } +}; + +template <> +struct JsonObjectConverter<SearchJob::UserProfile> +{ + static void fillFrom(const QJsonObject& jo, SearchJob::UserProfile& result) + { + fromJson(jo.value("displayname"_ls), result.displayname); + fromJson(jo.value("avatar_url"_ls), result.avatarUrl); + } +}; + +template <> +struct JsonObjectConverter<SearchJob::EventContext> +{ + static void fillFrom(const QJsonObject& jo, SearchJob::EventContext& result) + { + fromJson(jo.value("start"_ls), result.begin); + fromJson(jo.value("end"_ls), result.end); + fromJson(jo.value("profile_info"_ls), result.profileInfo); + fromJson(jo.value("events_before"_ls), result.eventsBefore); + fromJson(jo.value("events_after"_ls), result.eventsAfter); + } +}; + +template <> +struct JsonObjectConverter<SearchJob::Result> +{ + static void fillFrom(const QJsonObject& jo, SearchJob::Result& result) + { + fromJson(jo.value("rank"_ls), result.rank); + fromJson(jo.value("result"_ls), result.result); + fromJson(jo.value("context"_ls), result.context); + } +}; + +template <> +struct JsonObjectConverter<SearchJob::GroupValue> +{ + static void fillFrom(const QJsonObject& jo, SearchJob::GroupValue& result) + { + fromJson(jo.value("next_batch"_ls), result.nextBatch); + fromJson(jo.value("order"_ls), result.order); + fromJson(jo.value("results"_ls), result.results); + } +}; + +template <> +struct JsonObjectConverter<SearchJob::ResultRoomEvents> +{ + static void fillFrom(const QJsonObject& jo, + SearchJob::ResultRoomEvents& result) + { + fromJson(jo.value("count"_ls), result.count); + fromJson(jo.value("highlights"_ls), result.highlights); + fromJson(jo.value("results"_ls), result.results); + fromJson(jo.value("state"_ls), result.state); + fromJson(jo.value("groups"_ls), result.groups); + fromJson(jo.value("next_batch"_ls), result.nextBatch); + } +}; + +template <> +struct JsonObjectConverter<SearchJob::ResultCategories> +{ + static void fillFrom(const QJsonObject& jo, + SearchJob::ResultCategories& result) + { + fromJson(jo.value("room_events"_ls), result.roomEvents); + } +}; + } // namespace QMatrixClient class SearchJob::Private { - public: +public: ResultCategories searchCategories; }; @@ -147,8 +164,8 @@ static const auto SearchJobName = QStringLiteral("SearchJob"); SearchJob::SearchJob(const Categories& searchCategories, const QString& nextBatch) : BaseJob(HttpVerb::Post, SearchJobName, basePath % "/search", - queryToSearch(nextBatch)), - d(new Private) + queryToSearch(nextBatch)) + , d(new Private) { QJsonObject _data; addParam<>(_data, QStringLiteral("search_categories"), searchCategories); @@ -166,8 +183,9 @@ BaseJob::Status SearchJob::parseJson(const QJsonDocument& data) { auto json = data.object(); if (!json.contains("search_categories"_ls)) - return { JsonParseError, + return { IncorrectResponse, "The key 'search_categories' not found in the response" }; fromJson(json.value("search_categories"_ls), d->searchCategories); + return Success; } diff --git a/lib/csapi/search.h b/lib/csapi/search.h index 41761030..f965a72a 100644 --- a/lib/csapi/search.h +++ b/lib/csapi/search.h @@ -4,193 +4,200 @@ #pragma once -#include "jobs/basejob.h" - #include "converters.h" + #include "csapi/definitions/room_event_filter.h" + #include "events/eventloader.h" +#include "jobs/basejob.h" + #include <QtCore/QHash> #include <QtCore/QVector> + #include <unordered_map> -namespace QMatrixClient { - // Operations +namespace QMatrixClient +{ - /// Perform a server-side search. - /// - /// Performs a full text search across different categories. - class SearchJob : public BaseJob +// Operations + +/// Perform a server-side search. +/*! + * Performs a full text search across different categories. + */ +class SearchJob : public BaseJob +{ +public: + // Inner data structures + + /// Configures whether any context for the eventsreturned are included in + /// the response. + struct IncludeEventContext { - public: - // Inner data structures - - /// Configures whether any context for the events - /// returned are included in the response. - struct IncludeEventContext { - /// How many events before the result are - /// returned. By default, this is ``5``. - Omittable<int> beforeLimit; - /// How many events after the result are - /// returned. By default, this is ``5``. - Omittable<int> afterLimit; - /// Requests that the server returns the - /// historic profile information for the users - /// that sent the events that were returned. - /// By default, this is ``false``. - Omittable<bool> includeProfile; - }; - - /// Configuration for group. - struct Group { - /// Key that defines the group. - QString key; - }; - - /// Requests that the server partitions the result set - /// based on the provided list of keys. - struct Groupings { - /// List of groups to request. - QVector<Group> groupBy; - }; + /// How many events before the result arereturned. By default, this is + /// ``5``. + Omittable<int> beforeLimit; + /// How many events after the result arereturned. By default, this is + /// ``5``. + Omittable<int> afterLimit; + /// Requests that the server returns thehistoric profile information for + /// the usersthat sent the events that were returned.By default, this is + /// ``false``. + Omittable<bool> includeProfile; + }; + /// Configuration for group. + struct Group + { + /// Key that defines the group. + QString key; + }; + + /// Requests that the server partitions the result setbased on the provided + /// list of keys. + struct Groupings + { + /// List of groups to request. + QVector<Group> groupBy; + }; + + /// Mapping of category name to search criteria. + struct RoomEventsCriteria + { + /// The string to search events for + QString searchTerm; + /// The keys to search. Defaults to all. + QStringList keys; + /// This takes a `filter`_. + Omittable<RoomEventFilter> filter; + /// The order in which to search for results.By default, this is + /// ``"rank"``. + QString orderBy; + /// Configures whether any context for the eventsreturned are included + /// in the response. + Omittable<IncludeEventContext> eventContext; + /// Requests the server return the current state foreach room returned. + Omittable<bool> includeState; + /// Requests that the server partitions the result setbased on the + /// provided list of keys. + Omittable<Groupings> groupings; + }; + + /// Describes which categories to search in and their criteria. + struct Categories + { /// Mapping of category name to search criteria. - struct RoomEventsCriteria { - /// The string to search events for - QString searchTerm; - /// The keys to search. Defaults to all. - QStringList keys; - /// This takes a `filter`_. - Omittable<RoomEventFilter> filter; - /// The order in which to search for results. - /// By default, this is ``"rank"``. - QString orderBy; - /// Configures whether any context for the events - /// returned are included in the response. - Omittable<IncludeEventContext> eventContext; - /// Requests the server return the current state for - /// each room returned. - Omittable<bool> includeState; - /// Requests that the server partitions the result set - /// based on the provided list of keys. - Omittable<Groupings> groupings; - }; - - /// Describes which categories to search in and their criteria. - struct Categories { - /// Mapping of category name to search criteria. - Omittable<RoomEventsCriteria> roomEvents; - }; + Omittable<RoomEventsCriteria> roomEvents; + }; + /// Performs a full text search across different categories. + struct UserProfile + { + /// Performs a full text search across different categories. + QString displayname; /// Performs a full text search across different categories. - struct UserProfile { - /// Performs a full text search across different categories. - QString displayname; - /// Performs a full text search across different categories. - QString avatarUrl; - }; + QString avatarUrl; + }; + + /// Context for result, if requested. + struct EventContext + { + /// Pagination token for the start of the chunk + QString begin; + /// Pagination token for the end of the chunk + QString end; + /// The historic profile information of theusers that sent the events + /// returned.The ``string`` key is the user ID for whichthe profile + /// belongs to. + QHash<QString, UserProfile> profileInfo; + /// Events just before the result. + RoomEvents eventsBefore; + /// Events just after the result. + RoomEvents eventsAfter; + }; + /// The result object. + struct Result + { + /// A number that describes how closely this result matches the search. + /// Higher is closer. + Omittable<double> rank; + /// The event that matched. + RoomEventPtr result; /// Context for result, if requested. - struct EventContext { - /// Pagination token for the start of the chunk - QString begin; - /// Pagination token for the end of the chunk - QString end; - /// The historic profile information of the - /// users that sent the events returned. - /// - /// The ``string`` key is the user ID for which - /// the profile belongs to. - QHash<QString, UserProfile> profileInfo; - /// Events just before the result. - RoomEvents eventsBefore; - /// Events just after the result. - RoomEvents eventsAfter; - }; - - /// The result object. - struct Result { - /// A number that describes how closely this result matches the - /// search. Higher is closer. - Omittable<double> rank; - /// The event that matched. - RoomEventPtr result; - /// Context for result, if requested. - Omittable<EventContext> context; - }; - - /// The results for a particular group value. - struct GroupValue { - /// Token that can be used to get the next batch - /// of results in the group, by passing as the - /// `next_batch` parameter to the next call. If - /// this field is absent, there are no more - /// results in this group. - QString nextBatch; - /// Key that can be used to order different - /// groups. - Omittable<int> order; - /// Which results are in this group. - QStringList results; - }; + Omittable<EventContext> context; + }; + + /// The results for a particular group value. + struct GroupValue + { + /// Token that can be used to get the next batchof results in the group, + /// by passing as the`next_batch` parameter to the next call. Ifthis + /// field is absent, there are no moreresults in this group. + QString nextBatch; + /// Key that can be used to order differentgroups. + Omittable<int> order; + /// Which results are in this group. + QStringList results; + }; + /// Mapping of category name to search criteria. + struct ResultRoomEvents + { + /// An approximate count of the total number of results found. + Omittable<int> count; + /// List of words which should be highlighted, useful for stemming which + /// may change the query terms. + QStringList highlights; + /// List of results in the requested order. + std::vector<Result> results; + /// The current state for every room in the results.This is included if + /// the request had the``include_state`` key set with a value of + /// ``true``.The ``string`` key is the room ID for which the + /// ``StateEvent`` array belongs to. + std::unordered_map<QString, StateEvents> state; + /// Any groups that were requested.The outer ``string`` key is the group + /// key requested (eg: ``room_id``or ``sender``). The inner ``string`` + /// key is the grouped value (eg: a room's ID or a user's ID). + QHash<QString, QHash<QString, GroupValue>> groups; + /// Token that can be used to get the next batch ofresults, by passing + /// as the `next_batch` parameter tothe next call. If this field is + /// absent, there are nomore results. + QString nextBatch; + }; + + /// Describes which categories to search in and their criteria. + struct ResultCategories + { /// Mapping of category name to search criteria. - struct ResultRoomEvents { - /// An approximate count of the total number of results found. - Omittable<int> count; - /// List of words which should be highlighted, useful for stemming - /// which may change the query terms. - QStringList highlights; - /// List of results in the requested order. - std::vector<Result> results; - /// The current state for every room in the results. - /// This is included if the request had the - /// ``include_state`` key set with a value of ``true``. - /// - /// The ``string`` key is the room ID for which the ``State - /// Event`` array belongs to. - std::unordered_map<QString, StateEvents> state; - /// Any groups that were requested. - /// - /// The outer ``string`` key is the group key requested (eg: - /// ``room_id`` or ``sender``). The inner ``string`` key is the - /// grouped value (eg: a room's ID or a user's ID). - QHash<QString, QHash<QString, GroupValue>> groups; - /// Token that can be used to get the next batch of - /// results, by passing as the `next_batch` parameter to - /// the next call. If this field is absent, there are no - /// more results. - QString nextBatch; - }; - - /// Describes which categories to search in and their criteria. - struct ResultCategories { - /// Mapping of category name to search criteria. - Omittable<ResultRoomEvents> roomEvents; - }; - - // Construction/destruction - - /*! Perform a server-side search. - * \param searchCategories - * Describes which categories to search in and their criteria. - * \param nextBatch - * The point to return events from. If given, this should be a - * ``next_batch`` result from a previous call to this endpoint. - */ - explicit SearchJob(const Categories& searchCategories, - const QString& nextBatch = {}); - ~SearchJob() override; - - // Result properties - - /// Describes which categories to search in and their criteria. - const ResultCategories& searchCategories() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; + Omittable<ResultRoomEvents> roomEvents; }; + + // Construction/destruction + + /*! Perform a server-side search. + * \param searchCategories + * Describes which categories to search in and their criteria. + * \param nextBatch + * The point to return events from. If given, this should be a + * ``next_batch`` result from a previous call to this endpoint. + */ + explicit SearchJob(const Categories& searchCategories, + const QString& nextBatch = {}); + + ~SearchJob() override; + + // Result properties + + /// Describes which categories to search in and their criteria. + const ResultCategories& searchCategories() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + } // namespace QMatrixClient diff --git a/lib/csapi/sso_login_redirect.cpp b/lib/csapi/sso_login_redirect.cpp index 92084d52..b1dc3674 100644 --- a/lib/csapi/sso_login_redirect.cpp +++ b/lib/csapi/sso_login_redirect.cpp @@ -32,5 +32,4 @@ RedirectToSSOJob::RedirectToSSOJob(const QString& redirectUrl) : BaseJob(HttpVerb::Get, RedirectToSSOJobName, basePath % "/login/sso/redirect", queryToRedirectToSSO(redirectUrl), {}, false) -{ -} +{} diff --git a/lib/csapi/sso_login_redirect.h b/lib/csapi/sso_login_redirect.h index 2b0d3f65..af9e7780 100644 --- a/lib/csapi/sso_login_redirect.h +++ b/lib/csapi/sso_login_redirect.h @@ -6,31 +6,35 @@ #include "jobs/basejob.h" -namespace QMatrixClient { - // Operations +namespace QMatrixClient +{ - /// Redirect the user's browser to the SSO interface. - /// - /// A web-based Matrix client should instruct the user's browser to - /// navigate to this endpoint in order to log in via SSO. - /// - /// The server MUST respond with an HTTP redirect to the SSO interface. - class RedirectToSSOJob : public BaseJob - { - public: - /*! Redirect the user's browser to the SSO interface. - * \param redirectUrl - * URI to which the user will be redirected after the homeserver has - * authenticated the user with SSO. - */ - explicit RedirectToSSOJob(const QString& redirectUrl); +// Operations + +/// Redirect the user's browser to the SSO interface. +/*! + * A web-based Matrix client should instruct the user's browser to + * navigate to this endpoint in order to log in via SSO. + * + * The server MUST respond with an HTTP redirect to the SSO interface. + */ +class RedirectToSSOJob : public BaseJob +{ +public: + /*! Redirect the user's browser to the SSO interface. + * \param redirectUrl + * URI to which the user will be redirected after the homeserver has + * authenticated the user with SSO. + */ + explicit RedirectToSSOJob(const QString& redirectUrl); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * RedirectToSSOJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& redirectUrl); +}; - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * RedirectToSSOJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& redirectUrl); - }; } // namespace QMatrixClient diff --git a/lib/csapi/tags.cpp b/lib/csapi/tags.cpp index 9f591447..13c933e5 100644 --- a/lib/csapi/tags.cpp +++ b/lib/csapi/tags.cpp @@ -12,40 +12,43 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); -namespace QMatrixClient { - // Converters - - template <> struct JsonObjectConverter<GetRoomTagsJob::Tag> { - static void fillFrom(QJsonObject jo, GetRoomTagsJob::Tag& result) - { - fromJson(jo.take("order"_ls), result.order); - fromJson(jo, result.additionalProperties); - } - }; +// Converters +namespace QMatrixClient +{ + +template <> +struct JsonObjectConverter<GetRoomTagsJob::Tag> +{ + static void fillFrom(QJsonObject jo, GetRoomTagsJob::Tag& result) + { + fromJson(jo.take("order"_ls), result.order); + fromJson(jo, result.additionalProperties); + } +}; + } // namespace QMatrixClient class GetRoomTagsJob::Private { - public: +public: QHash<QString, Tag> tags; }; QUrl GetRoomTagsJob::makeRequestUrl(QUrl baseUrl, const QString& userId, const QString& roomId) { - return BaseJob::makeRequestUrl(std::move(baseUrl), - basePath % "/user/" % userId % "/rooms/" - % roomId % "/tags"); + return BaseJob::makeRequestUrl(std::move(baseUrl), basePath % "/user/" + % userId % "/rooms/" + % roomId % "/tags"); } static const auto GetRoomTagsJobName = QStringLiteral("GetRoomTagsJob"); GetRoomTagsJob::GetRoomTagsJob(const QString& userId, const QString& roomId) : BaseJob(HttpVerb::Get, GetRoomTagsJobName, - basePath % "/user/" % userId % "/rooms/" % roomId % "/tags"), - d(new Private) -{ -} + basePath % "/user/" % userId % "/rooms/" % roomId % "/tags") + , d(new Private) +{} GetRoomTagsJob::~GetRoomTagsJob() = default; @@ -58,6 +61,7 @@ BaseJob::Status GetRoomTagsJob::parseJson(const QJsonDocument& data) { auto json = data.object(); fromJson(json.value("tags"_ls), d->tags); + return Success; } @@ -66,8 +70,7 @@ static const auto SetRoomTagJobName = QStringLiteral("SetRoomTagJob"); SetRoomTagJob::SetRoomTagJob(const QString& userId, const QString& roomId, const QString& tag, Omittable<float> order) : BaseJob(HttpVerb::Put, SetRoomTagJobName, - basePath % "/user/" % userId % "/rooms/" % roomId % "/tags/" - % tag) + basePath % "/user/" % userId % "/rooms/" % roomId % "/tags/" % tag) { QJsonObject _data; addParam<IfNotEmpty>(_data, QStringLiteral("order"), order); @@ -79,7 +82,7 @@ QUrl DeleteRoomTagJob::makeRequestUrl(QUrl baseUrl, const QString& userId, { return BaseJob::makeRequestUrl(std::move(baseUrl), basePath % "/user/" % userId % "/rooms/" - % roomId % "/tags/" % tag); + % roomId % "/tags/" % tag); } static const auto DeleteRoomTagJobName = QStringLiteral("DeleteRoomTagJob"); @@ -87,7 +90,5 @@ static const auto DeleteRoomTagJobName = QStringLiteral("DeleteRoomTagJob"); DeleteRoomTagJob::DeleteRoomTagJob(const QString& userId, const QString& roomId, const QString& tag) : BaseJob(HttpVerb::Delete, DeleteRoomTagJobName, - basePath % "/user/" % userId % "/rooms/" % roomId % "/tags/" - % tag) -{ -} + basePath % "/user/" % userId % "/rooms/" % roomId % "/tags/" % tag) +{} diff --git a/lib/csapi/tags.h b/lib/csapi/tags.h index dc683ef7..dc20cd3d 100644 --- a/lib/csapi/tags.h +++ b/lib/csapi/tags.h @@ -4,115 +4,123 @@ #pragma once +#include "converters.h" + #include "jobs/basejob.h" -#include "converters.h" #include <QtCore/QHash> #include <QtCore/QVariant> -namespace QMatrixClient { - // Operations +namespace QMatrixClient +{ + +// Operations + +/// List the tags for a room. +/*! + * List the tags set by a user on a room. + */ +class GetRoomTagsJob : public BaseJob +{ +public: + // Inner data structures - /// List the tags for a room. - /// /// List the tags set by a user on a room. - class GetRoomTagsJob : public BaseJob + struct Tag { - public: - // Inner data structures + /// A number in a range ``[0,1]`` describing a relativeposition of the + /// room under the given tag. + Omittable<float> order; /// List the tags set by a user on a room. - struct Tag { - /// A number in a range ``[0,1]`` describing a relative - /// position of the room under the given tag. - Omittable<float> order; - /// List the tags set by a user on a room. - QVariantHash additionalProperties; - }; - - // Construction/destruction - - /*! List the tags for a room. - * \param userId - * The id of the user to get tags for. The access token must be - * authorized to make requests for this user ID. - * \param roomId - * The ID of the room to get tags for. - */ - explicit GetRoomTagsJob(const QString& userId, const QString& roomId); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetRoomTagsJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& userId, - const QString& roomId); - - ~GetRoomTagsJob() override; - - // Result properties + QVariantHash additionalProperties; + }; - /// List the tags set by a user on a room. - const QHash<QString, Tag>& tags() const; + // Construction/destruction - protected: - Status parseJson(const QJsonDocument& data) override; + /*! List the tags for a room. + * \param userId + * The id of the user to get tags for. The access token must be + * authorized to make requests for this user ID. + * \param roomId + * The ID of the room to get tags for. + */ + explicit GetRoomTagsJob(const QString& userId, const QString& roomId); - private: - class Private; - QScopedPointer<Private> d; - }; + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetRoomTagsJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& userId, + const QString& roomId); - /// Add a tag to a room. - /// - /// Add a tag to the room. - class SetRoomTagJob : public BaseJob - { - public: - /*! Add a tag to a room. - * \param userId - * The id of the user to add a tag for. The access token must be - * authorized to make requests for this user ID. - * \param roomId - * The ID of the room to add a tag to. - * \param tag - * The tag to add. - * \param order - * A number in a range ``[0,1]`` describing a relative - * position of the room under the given tag. - */ - explicit SetRoomTagJob(const QString& userId, const QString& roomId, - const QString& tag, - Omittable<float> order = none); - }; + ~GetRoomTagsJob() override; + + // Result properties + + /// List the tags set by a user on a room. + const QHash<QString, Tag>& tags() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Add a tag to a room. +/*! + * Add a tag to the room. + */ +class SetRoomTagJob : public BaseJob +{ +public: + /*! Add a tag to a room. + * \param userId + * The id of the user to add a tag for. The access token must be + * authorized to make requests for this user ID. + * \param roomId + * The ID of the room to add a tag to. + * \param tag + * The tag to add. + * \param order + * A number in a range ``[0,1]`` describing a relative + * position of the room under the given tag. + */ + explicit SetRoomTagJob(const QString& userId, const QString& roomId, + const QString& tag, Omittable<float> order = none); +}; + +/// Remove a tag from the room. +/*! + * Remove a tag from the room. + */ +class DeleteRoomTagJob : public BaseJob +{ +public: + /*! Remove a tag from the room. + * \param userId + * The id of the user to remove a tag for. The access token must be + * authorized to make requests for this user ID. + * \param roomId + * The ID of the room to remove a tag from. + * \param tag + * The tag to remove. + */ + explicit DeleteRoomTagJob(const QString& userId, const QString& roomId, + const QString& tag); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * DeleteRoomTagJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& userId, + const QString& roomId, const QString& tag); +}; - /// Remove a tag from the room. - /// - /// Remove a tag from the room. - class DeleteRoomTagJob : public BaseJob - { - public: - /*! Remove a tag from the room. - * \param userId - * The id of the user to remove a tag for. The access token must be - * authorized to make requests for this user ID. - * \param roomId - * The ID of the room to remove a tag from. - * \param tag - * The tag to remove. - */ - explicit DeleteRoomTagJob(const QString& userId, const QString& roomId, - const QString& tag); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * DeleteRoomTagJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& userId, - const QString& roomId, const QString& tag); - }; } // namespace QMatrixClient diff --git a/lib/csapi/third_party_lookup.cpp b/lib/csapi/third_party_lookup.cpp index 339a0d90..986ead01 100644 --- a/lib/csapi/third_party_lookup.cpp +++ b/lib/csapi/third_party_lookup.cpp @@ -14,7 +14,7 @@ static const auto basePath = QStringLiteral("/_matrix/client/r0"); class GetProtocolsJob::Private { - public: +public: QHash<QString, ThirdPartyProtocol> data; }; @@ -28,10 +28,9 @@ static const auto GetProtocolsJobName = QStringLiteral("GetProtocolsJob"); GetProtocolsJob::GetProtocolsJob() : BaseJob(HttpVerb::Get, GetProtocolsJobName, - basePath % "/thirdparty/protocols"), - d(new Private) -{ -} + basePath % "/thirdparty/protocols") + , d(new Private) +{} GetProtocolsJob::~GetProtocolsJob() = default; @@ -48,7 +47,7 @@ BaseJob::Status GetProtocolsJob::parseJson(const QJsonDocument& data) class GetProtocolMetadataJob::Private { - public: +public: ThirdPartyProtocol data; }; @@ -56,18 +55,17 @@ QUrl GetProtocolMetadataJob::makeRequestUrl(QUrl baseUrl, const QString& protocol) { return BaseJob::makeRequestUrl( - std::move(baseUrl), basePath % "/thirdparty/protocol/" % protocol); + std::move(baseUrl), basePath % "/thirdparty/protocol/" % protocol); } static const auto GetProtocolMetadataJobName = - QStringLiteral("GetProtocolMetadataJob"); + QStringLiteral("GetProtocolMetadataJob"); GetProtocolMetadataJob::GetProtocolMetadataJob(const QString& protocol) : BaseJob(HttpVerb::Get, GetProtocolMetadataJobName, - basePath % "/thirdparty/protocol/" % protocol), - d(new Private) -{ -} + basePath % "/thirdparty/protocol/" % protocol) + , d(new Private) +{} GetProtocolMetadataJob::~GetProtocolMetadataJob() = default; @@ -84,7 +82,7 @@ BaseJob::Status GetProtocolMetadataJob::parseJson(const QJsonDocument& data) class QueryLocationByProtocolJob::Private { - public: +public: QVector<ThirdPartyLocation> data; }; @@ -99,22 +97,21 @@ QUrl QueryLocationByProtocolJob::makeRequestUrl(QUrl baseUrl, const QString& protocol, const QString& searchFields) { - return BaseJob::makeRequestUrl( - std::move(baseUrl), basePath % "/thirdparty/location/" % protocol, - queryToQueryLocationByProtocol(searchFields)); + return BaseJob::makeRequestUrl(std::move(baseUrl), + basePath % "/thirdparty/location/" % protocol, + queryToQueryLocationByProtocol(searchFields)); } static const auto QueryLocationByProtocolJobName = - QStringLiteral("QueryLocationByProtocolJob"); + QStringLiteral("QueryLocationByProtocolJob"); QueryLocationByProtocolJob::QueryLocationByProtocolJob( - const QString& protocol, const QString& searchFields) + const QString& protocol, const QString& searchFields) : BaseJob(HttpVerb::Get, QueryLocationByProtocolJobName, basePath % "/thirdparty/location/" % protocol, - queryToQueryLocationByProtocol(searchFields)), - d(new Private) -{ -} + queryToQueryLocationByProtocol(searchFields)) + , d(new Private) +{} QueryLocationByProtocolJob::~QueryLocationByProtocolJob() = default; @@ -131,7 +128,7 @@ BaseJob::Status QueryLocationByProtocolJob::parseJson(const QJsonDocument& data) class QueryUserByProtocolJob::Private { - public: +public: QVector<ThirdPartyUser> data; }; @@ -152,16 +149,15 @@ QUrl QueryUserByProtocolJob::makeRequestUrl(QUrl baseUrl, } static const auto QueryUserByProtocolJobName = - QStringLiteral("QueryUserByProtocolJob"); + QStringLiteral("QueryUserByProtocolJob"); QueryUserByProtocolJob::QueryUserByProtocolJob(const QString& protocol, const QString& fields) : BaseJob(HttpVerb::Get, QueryUserByProtocolJobName, basePath % "/thirdparty/user/" % protocol, - queryToQueryUserByProtocol(fields)), - d(new Private) -{ -} + queryToQueryUserByProtocol(fields)) + , d(new Private) +{} QueryUserByProtocolJob::~QueryUserByProtocolJob() = default; @@ -178,7 +174,7 @@ BaseJob::Status QueryUserByProtocolJob::parseJson(const QJsonDocument& data) class QueryLocationByAliasJob::Private { - public: +public: QVector<ThirdPartyLocation> data; }; @@ -197,15 +193,14 @@ QUrl QueryLocationByAliasJob::makeRequestUrl(QUrl baseUrl, const QString& alias) } static const auto QueryLocationByAliasJobName = - QStringLiteral("QueryLocationByAliasJob"); + QStringLiteral("QueryLocationByAliasJob"); QueryLocationByAliasJob::QueryLocationByAliasJob(const QString& alias) : BaseJob(HttpVerb::Get, QueryLocationByAliasJobName, basePath % "/thirdparty/location", - queryToQueryLocationByAlias(alias)), - d(new Private) -{ -} + queryToQueryLocationByAlias(alias)) + , d(new Private) +{} QueryLocationByAliasJob::~QueryLocationByAliasJob() = default; @@ -222,7 +217,7 @@ BaseJob::Status QueryLocationByAliasJob::parseJson(const QJsonDocument& data) class QueryUserByIDJob::Private { - public: +public: QVector<ThirdPartyUser> data; }; @@ -244,10 +239,9 @@ static const auto QueryUserByIDJobName = QStringLiteral("QueryUserByIDJob"); QueryUserByIDJob::QueryUserByIDJob(const QString& userid) : BaseJob(HttpVerb::Get, QueryUserByIDJobName, - basePath % "/thirdparty/user", queryToQueryUserByID(userid)), - d(new Private) -{ -} + basePath % "/thirdparty/user", queryToQueryUserByID(userid)) + , d(new Private) +{} QueryUserByIDJob::~QueryUserByIDJob() = default; diff --git a/lib/csapi/third_party_lookup.h b/lib/csapi/third_party_lookup.h index 91bc79e5..d25c1cf3 100644 --- a/lib/csapi/third_party_lookup.h +++ b/lib/csapi/third_party_lookup.h @@ -4,244 +4,253 @@ #pragma once -#include "jobs/basejob.h" - #include "converters.h" + #include "csapi/../application-service/definitions/location.h" #include "csapi/../application-service/definitions/protocol.h" #include "csapi/../application-service/definitions/user.h" + +#include "jobs/basejob.h" + #include <QtCore/QHash> #include <QtCore/QVector> -namespace QMatrixClient { - // Operations - - /// Retrieve metadata about all protocols that a homeserver supports. - /// - /// Fetches the overall metadata about protocols supported by the - /// homeserver. Includes both the available protocols and all fields - /// required for queries against each protocol. - class GetProtocolsJob : public BaseJob - { - public: - explicit GetProtocolsJob(); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetProtocolsJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl); - - ~GetProtocolsJob() override; - - // Result properties - - /// The protocols supported by the homeserver. - const QHash<QString, ThirdPartyProtocol>& data() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; - - /// Retrieve metadata about a specific protocol that the homeserver - /// supports. - /// - /// Fetches the metadata from the homeserver about a particular third party - /// protocol. - class GetProtocolMetadataJob : public BaseJob - { - public: - /*! Retrieve metadata about a specific protocol that the homeserver supports. - * \param protocol - * The name of the protocol. - */ - explicit GetProtocolMetadataJob(const QString& protocol); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetProtocolMetadataJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& protocol); - - ~GetProtocolMetadataJob() override; - - // Result properties - - /// The protocol was found and metadata returned. - const ThirdPartyProtocol& data() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; - - /// Retrieve Matrix-side portals rooms leading to a third party location. - /// - /// Requesting this endpoint with a valid protocol name results in a list - /// of successful mapping results in a JSON array. Each result contains - /// objects to represent the Matrix room or rooms that represent a portal - /// to this third party network. Each has the Matrix room alias string, - /// an identifier for the particular third party network protocol, and an - /// object containing the network-specific fields that comprise this - /// identifier. It should attempt to canonicalise the identifier as much - /// as reasonably possible given the network type. - class QueryLocationByProtocolJob : public BaseJob - { - public: - /*! Retrieve Matrix-side portals rooms leading to a third party location. - * \param protocol - * The protocol used to communicate to the third party network. - * \param searchFields - * One or more custom fields to help identify the third party - * location. - */ - explicit QueryLocationByProtocolJob(const QString& protocol, - const QString& searchFields = {}); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * QueryLocationByProtocolJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& protocol, - const QString& searchFields = {}); - - ~QueryLocationByProtocolJob() override; - - // Result properties - - /// At least one portal room was found. - const QVector<ThirdPartyLocation>& data() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; - - /// Retrieve the Matrix User ID of a corresponding third party user. - /// - /// Retrieve a Matrix User ID linked to a user on the third party service, - /// given a set of user parameters. - class QueryUserByProtocolJob : public BaseJob - { - public: - /*! Retrieve the Matrix User ID of a corresponding third party user. - * \param protocol - * The name of the protocol. - * \param fields - * One or more custom fields that are passed to the AS to help - * identify the user. - */ - explicit QueryUserByProtocolJob(const QString& protocol, - const QString& fields = {}); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * QueryUserByProtocolJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& protocol, - const QString& fields = {}); - - ~QueryUserByProtocolJob() override; - - // Result properties - - /// The Matrix User IDs found with the given parameters. - const QVector<ThirdPartyUser>& data() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; - - /// Reverse-lookup third party locations given a Matrix room alias. - /// - /// Retrieve an array of third party network locations from a Matrix room - /// alias. - class QueryLocationByAliasJob : public BaseJob - { - public: - /*! Reverse-lookup third party locations given a Matrix room alias. - * \param alias - * The Matrix room alias to look up. - */ - explicit QueryLocationByAliasJob(const QString& alias); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * QueryLocationByAliasJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& alias); - - ~QueryLocationByAliasJob() override; - - // Result properties - - /// All found third party locations. - const QVector<ThirdPartyLocation>& data() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; - - /// Reverse-lookup third party users given a Matrix User ID. - /// - /// Retrieve an array of third party users from a Matrix User ID. - class QueryUserByIDJob : public BaseJob - { - public: - /*! Reverse-lookup third party users given a Matrix User ID. - * \param userid - * The Matrix User ID to look up. - */ - explicit QueryUserByIDJob(const QString& userid); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * QueryUserByIDJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& userid); - - ~QueryUserByIDJob() override; - - // Result properties - - /// An array of third party users. - const QVector<ThirdPartyUser>& data() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; +namespace QMatrixClient +{ + +// Operations + +/// Retrieve metadata about all protocols that a homeserver supports. +/*! + * Fetches the overall metadata about protocols supported by the + * homeserver. Includes both the available protocols and all fields + * required for queries against each protocol. + */ +class GetProtocolsJob : public BaseJob +{ +public: + explicit GetProtocolsJob(); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetProtocolsJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl); + + ~GetProtocolsJob() override; + + // Result properties + + /// The protocols supported by the homeserver. + const QHash<QString, ThirdPartyProtocol>& data() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Retrieve metadata about a specific protocol that the homeserver supports. +/*! + * Fetches the metadata from the homeserver about a particular third party + * protocol. + */ +class GetProtocolMetadataJob : public BaseJob +{ +public: + /*! Retrieve metadata about a specific protocol that the homeserver + * supports. \param protocol The name of the protocol. + */ + explicit GetProtocolMetadataJob(const QString& protocol); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetProtocolMetadataJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& protocol); + + ~GetProtocolMetadataJob() override; + + // Result properties + + /// The protocol was found and metadata returned. + const ThirdPartyProtocol& data() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Retrieve Matrix-side portals rooms leading to a third party location. +/*! + * Requesting this endpoint with a valid protocol name results in a list + * of successful mapping results in a JSON array. Each result contains + * objects to represent the Matrix room or rooms that represent a portal + * to this third party network. Each has the Matrix room alias string, + * an identifier for the particular third party network protocol, and an + * object containing the network-specific fields that comprise this + * identifier. It should attempt to canonicalise the identifier as much + * as reasonably possible given the network type. + */ +class QueryLocationByProtocolJob : public BaseJob +{ +public: + /*! Retrieve Matrix-side portals rooms leading to a third party location. + * \param protocol + * The protocol used to communicate to the third party network. + * \param searchFields + * One or more custom fields to help identify the third party + * location. + */ + explicit QueryLocationByProtocolJob(const QString& protocol, + const QString& searchFields = {}); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * QueryLocationByProtocolJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& protocol, + const QString& searchFields = {}); + + ~QueryLocationByProtocolJob() override; + + // Result properties + + /// At least one portal room was found. + const QVector<ThirdPartyLocation>& data() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Retrieve the Matrix User ID of a corresponding third party user. +/*! + * Retrieve a Matrix User ID linked to a user on the third party service, given + * a set of user parameters. + */ +class QueryUserByProtocolJob : public BaseJob +{ +public: + /*! Retrieve the Matrix User ID of a corresponding third party user. + * \param protocol + * The name of the protocol. + * \param fields + * One or more custom fields that are passed to the AS to help identify + * the user. + */ + explicit QueryUserByProtocolJob(const QString& protocol, + const QString& fields = {}); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * QueryUserByProtocolJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& protocol, + const QString& fields = {}); + + ~QueryUserByProtocolJob() override; + + // Result properties + + /// The Matrix User IDs found with the given parameters. + const QVector<ThirdPartyUser>& data() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Reverse-lookup third party locations given a Matrix room alias. +/*! + * Retrieve an array of third party network locations from a Matrix room + * alias. + */ +class QueryLocationByAliasJob : public BaseJob +{ +public: + /*! Reverse-lookup third party locations given a Matrix room alias. + * \param alias + * The Matrix room alias to look up. + */ + explicit QueryLocationByAliasJob(const QString& alias); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * QueryLocationByAliasJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& alias); + + ~QueryLocationByAliasJob() override; + + // Result properties + + /// All found third party locations. + const QVector<ThirdPartyLocation>& data() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + +/// Reverse-lookup third party users given a Matrix User ID. +/*! + * Retrieve an array of third party users from a Matrix User ID. + */ +class QueryUserByIDJob : public BaseJob +{ +public: + /*! Reverse-lookup third party users given a Matrix User ID. + * \param userid + * The Matrix User ID to look up. + */ + explicit QueryUserByIDJob(const QString& userid); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * QueryUserByIDJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& userid); + + ~QueryUserByIDJob() override; + + // Result properties + + /// An array of third party users. + const QVector<ThirdPartyUser>& data() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + } // namespace QMatrixClient diff --git a/lib/csapi/third_party_membership.h b/lib/csapi/third_party_membership.h index d1261567..36622c94 100644 --- a/lib/csapi/third_party_membership.h +++ b/lib/csapi/third_party_membership.h @@ -6,69 +6,72 @@ #include "jobs/basejob.h" -namespace QMatrixClient { - // Operations +namespace QMatrixClient +{ + +// Operations + +/// Invite a user to participate in a particular room. +/*! + * .. _invite-by-third-party-id-endpoint: + * + * *Note that there are two forms of this API, which are documented separately. + * This version of the API does not require that the inviter know the Matrix + * identifier of the invitee, and instead relies on third party identifiers. + * The homeserver uses an identity server to perform the mapping from + * third party identifier to a Matrix identifier. The other is documented in + * the* `joining rooms section`_. + * + * This API invites a user to participate in a particular room. + * They do not start participating in the room until they actually join the + * room. + * + * Only users currently in a particular room can invite other users to + * join that room. + * + * If the identity server did know the Matrix user identifier for the + * third party identifier, the homeserver will append a ``m.room.member`` + * event to the room. + * + * If the identity server does not know a Matrix user identifier for the + * passed third party identifier, the homeserver will issue an invitation + * which can be accepted upon providing proof of ownership of the third + * party identifier. This is achieved by the identity server generating a + * token, which it gives to the inviting homeserver. The homeserver will + * add an ``m.room.third_party_invite`` event into the graph for the room, + * containing that token. + * + * When the invitee binds the invited third party identifier to a Matrix + * user ID, the identity server will give the user a list of pending + * invitations, each containing: + * + * - The room ID to which they were invited + * + * - The token given to the homeserver + * + * - A signature of the token, signed with the identity server's private key + * + * - The matrix user ID who invited them to the room + * + * If a token is requested from the identity server, the homeserver will + * append a ``m.room.third_party_invite`` event to the room. + * + * .. _joining rooms section: `invite-by-user-id-endpoint`_ + */ +class InviteBy3PIDJob : public BaseJob +{ +public: + /*! Invite a user to participate in a particular room. + * \param roomId + * The room identifier (not alias) to which to invite the user. + * \param idServer + * The hostname+port of the identity server which should be used for third + * party identifier lookups. \param medium The kind of address being passed + * in the address field, for example ``email``. \param address The invitee's + * third party identifier. + */ + explicit InviteBy3PIDJob(const QString& roomId, const QString& idServer, + const QString& medium, const QString& address); +}; - /// Invite a user to participate in a particular room. - /// - /// .. _invite-by-third-party-id-endpoint: - /// - /// *Note that there are two forms of this API, which are documented - /// separately. This version of the API does not require that the inviter - /// know the Matrix identifier of the invitee, and instead relies on third - /// party identifiers. The homeserver uses an identity server to perform the - /// mapping from third party identifier to a Matrix identifier. The other is - /// documented in the* `joining rooms section`_. - /// - /// This API invites a user to participate in a particular room. - /// They do not start participating in the room until they actually join the - /// room. - /// - /// Only users currently in a particular room can invite other users to - /// join that room. - /// - /// If the identity server did know the Matrix user identifier for the - /// third party identifier, the homeserver will append a ``m.room.member`` - /// event to the room. - /// - /// If the identity server does not know a Matrix user identifier for the - /// passed third party identifier, the homeserver will issue an invitation - /// which can be accepted upon providing proof of ownership of the third - /// party identifier. This is achieved by the identity server generating a - /// token, which it gives to the inviting homeserver. The homeserver will - /// add an ``m.room.third_party_invite`` event into the graph for the room, - /// containing that token. - /// - /// When the invitee binds the invited third party identifier to a Matrix - /// user ID, the identity server will give the user a list of pending - /// invitations, each containing: - /// - /// - The room ID to which they were invited - /// - /// - The token given to the homeserver - /// - /// - A signature of the token, signed with the identity server's private - /// key - /// - /// - The matrix user ID who invited them to the room - /// - /// If a token is requested from the identity server, the homeserver will - /// append a ``m.room.third_party_invite`` event to the room. - /// - /// .. _joining rooms section: `invite-by-user-id-endpoint`_ - class InviteBy3PIDJob : public BaseJob - { - public: - /*! Invite a user to participate in a particular room. - * \param roomId - * The room identifier (not alias) to which to invite the user. - * \param idServer - * The hostname+port of the identity server which should be used for - * third party identifier lookups. \param medium The kind of address - * being passed in the address field, for example ``email``. \param - * address The invitee's third party identifier. - */ - explicit InviteBy3PIDJob(const QString& roomId, const QString& idServer, - const QString& medium, const QString& address); - }; } // namespace QMatrixClient diff --git a/lib/csapi/to_device.cpp b/lib/csapi/to_device.cpp index 241869f3..3fb17109 100644 --- a/lib/csapi/to_device.cpp +++ b/lib/csapi/to_device.cpp @@ -15,8 +15,8 @@ static const auto basePath = QStringLiteral("/_matrix/client/r0"); static const auto SendToDeviceJobName = QStringLiteral("SendToDeviceJob"); SendToDeviceJob::SendToDeviceJob( - const QString& eventType, const QString& txnId, - const QHash<QString, QHash<QString, QJsonObject>>& messages) + const QString& eventType, const QString& txnId, + const QHash<QString, QHash<QString, QJsonObject>>& messages) : BaseJob(HttpVerb::Put, SendToDeviceJobName, basePath % "/sendToDevice/" % eventType % "/" % txnId) { diff --git a/lib/csapi/to_device.h b/lib/csapi/to_device.h index 83df13b7..e0bbbe28 100644 --- a/lib/csapi/to_device.h +++ b/lib/csapi/to_device.h @@ -9,31 +9,34 @@ #include <QtCore/QHash> #include <QtCore/QJsonObject> -namespace QMatrixClient { - // Operations +namespace QMatrixClient +{ + +// Operations + +/// Send an event to a given set of devices. +/*! + * This endpoint is used to send send-to-device events to a set of + * client devices. + */ +class SendToDeviceJob : public BaseJob +{ +public: + /*! Send an event to a given set of devices. + * \param eventType + * The type of event to send. + * \param txnId + * The transaction ID for this event. Clients should generate an + * ID unique across requests with the same access token; it will be + * used by the server to ensure idempotency of requests. + * \param messages + * The messages to send. A map from user ID, to a map from + * device ID to message body. The device ID may also be `*`, + * meaning all known devices for the user. + */ + explicit SendToDeviceJob( + const QString& eventType, const QString& txnId, + const QHash<QString, QHash<QString, QJsonObject>>& messages = {}); +}; - /// Send an event to a given set of devices. - /// - /// This endpoint is used to send send-to-device events to a set of - /// client devices. - class SendToDeviceJob : public BaseJob - { - public: - /*! Send an event to a given set of devices. - * \param eventType - * The type of event to send. - * \param txnId - * The transaction ID for this event. Clients should generate an - * ID unique across requests with the same access token; it will be - * used by the server to ensure idempotency of requests. - * \param messages - * The messages to send. A map from user ID, to a map from - * device ID to message body. The device ID may also be `*`, - * meaning all known devices for the user. - */ - explicit SendToDeviceJob( - const QString& eventType, const QString& txnId, - const QHash<QString, QHash<QString, QJsonObject>>& - messages = {}); - }; } // namespace QMatrixClient diff --git a/lib/csapi/typing.h b/lib/csapi/typing.h index 1f32a8e5..0c3f75a8 100644 --- a/lib/csapi/typing.h +++ b/lib/csapi/typing.h @@ -4,34 +4,38 @@ #pragma once +#include "converters.h" + #include "jobs/basejob.h" -#include "converters.h" +namespace QMatrixClient +{ -namespace QMatrixClient { - // Operations +// Operations + +/// Informs the server that the user has started or stopped typing. +/*! + * This tells the server that the user is typing for the next N + * milliseconds where N is the value specified in the ``timeout`` key. + * Alternatively, if ``typing`` is ``false``, it tells the server that the + * user has stopped typing. + */ +class SetTypingJob : public BaseJob +{ +public: + /*! Informs the server that the user has started or stopped typing. + * \param userId + * The user who has started to type. + * \param roomId + * The room in which the user is typing. + * \param typing + * Whether the user is typing or not. If ``false``, the ``timeout`` + * key can be omitted. + * \param timeout + * The length of time in milliseconds to mark this user as typing. + */ + explicit SetTypingJob(const QString& userId, const QString& roomId, + bool typing, Omittable<int> timeout = none); +}; - /// Informs the server that the user has started or stopped typing. - /// - /// This tells the server that the user is typing for the next N - /// milliseconds where N is the value specified in the ``timeout`` key. - /// Alternatively, if ``typing`` is ``false``, it tells the server that the - /// user has stopped typing. - class SetTypingJob : public BaseJob - { - public: - /*! Informs the server that the user has started or stopped typing. - * \param userId - * The user who has started to type. - * \param roomId - * The room in which the user is typing. - * \param typing - * Whether the user is typing or not. If ``false``, the ``timeout`` - * key can be omitted. - * \param timeout - * The length of time in milliseconds to mark this user as typing. - */ - explicit SetTypingJob(const QString& userId, const QString& roomId, - bool typing, Omittable<int> timeout = none); - }; } // namespace QMatrixClient diff --git a/lib/csapi/users.cpp b/lib/csapi/users.cpp index 6d005915..39b05a77 100644 --- a/lib/csapi/users.cpp +++ b/lib/csapi/users.cpp @@ -12,35 +12,39 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); -namespace QMatrixClient { - // Converters - - template <> struct JsonObjectConverter<SearchUserDirectoryJob::User> { - static void fillFrom(const QJsonObject& jo, - SearchUserDirectoryJob::User& result) - { - fromJson(jo.value("user_id"_ls), result.userId); - fromJson(jo.value("display_name"_ls), result.displayName); - fromJson(jo.value("avatar_url"_ls), result.avatarUrl); - } - }; +// Converters +namespace QMatrixClient +{ + +template <> +struct JsonObjectConverter<SearchUserDirectoryJob::User> +{ + static void fillFrom(const QJsonObject& jo, + SearchUserDirectoryJob::User& result) + { + fromJson(jo.value("user_id"_ls), result.userId); + fromJson(jo.value("display_name"_ls), result.displayName); + fromJson(jo.value("avatar_url"_ls), result.avatarUrl); + } +}; + } // namespace QMatrixClient class SearchUserDirectoryJob::Private { - public: +public: QVector<User> results; bool limited; }; static const auto SearchUserDirectoryJobName = - QStringLiteral("SearchUserDirectoryJob"); + QStringLiteral("SearchUserDirectoryJob"); SearchUserDirectoryJob::SearchUserDirectoryJob(const QString& searchTerm, Omittable<int> limit) : BaseJob(HttpVerb::Post, SearchUserDirectoryJobName, - basePath % "/user_directory/search"), - d(new Private) + basePath % "/user_directory/search") + , d(new Private) { QJsonObject _data; addParam<>(_data, QStringLiteral("search_term"), searchTerm); @@ -50,8 +54,7 @@ SearchUserDirectoryJob::SearchUserDirectoryJob(const QString& searchTerm, SearchUserDirectoryJob::~SearchUserDirectoryJob() = default; -const QVector<SearchUserDirectoryJob::User>& -SearchUserDirectoryJob::results() const +const QVector<SearchUserDirectoryJob::User>& SearchUserDirectoryJob::results() const { return d->results; } @@ -62,12 +65,13 @@ BaseJob::Status SearchUserDirectoryJob::parseJson(const QJsonDocument& data) { auto json = data.object(); if (!json.contains("results"_ls)) - return { JsonParseError, + return { IncorrectResponse, "The key 'results' not found in the response" }; fromJson(json.value("results"_ls), d->results); if (!json.contains("limited"_ls)) - return { JsonParseError, + return { IncorrectResponse, "The key 'limited' not found in the response" }; fromJson(json.value("limited"_ls), d->limited); + return Success; } diff --git a/lib/csapi/users.h b/lib/csapi/users.h index 7754b82a..2e86c009 100644 --- a/lib/csapi/users.h +++ b/lib/csapi/users.h @@ -4,74 +4,80 @@ #pragma once +#include "converters.h" + #include "jobs/basejob.h" -#include "converters.h" #include <QtCore/QVector> -namespace QMatrixClient { - // Operations - - /// Searches the user directory. - /// - /// Performs a search for users on the homeserver. The homeserver may - /// determine which subset of users are searched, however the homeserver - /// MUST at a minimum consider the users the requesting user shares a - /// room with and those who reside in public rooms (known to the - /// homeserver). The search MUST consider local users to the homeserver, and - /// SHOULD query remote users as part of the search. - /// - /// The search is performed case-insensitively on user IDs and display - /// names preferably using a collation determined based upon the - /// ``Accept-Language`` header provided in the request, if present. - class SearchUserDirectoryJob : public BaseJob +namespace QMatrixClient +{ + +// Operations + +/// Searches the user directory. +/*! + * Performs a search for users on the homeserver. The homeserver may + * determine which subset of users are searched, however the homeserver + * MUST at a minimum consider the users the requesting user shares a + * room with and those who reside in public rooms (known to the homeserver). + * The search MUST consider local users to the homeserver, and SHOULD + * query remote users as part of the search. + * + * The search is performed case-insensitively on user IDs and display + * names preferably using a collation determined based upon the + * ``Accept-Language`` header provided in the request, if present. + */ +class SearchUserDirectoryJob : public BaseJob +{ +public: + // Inner data structures + + /// Performs a search for users on the homeserver. The homeserver + /// maydetermine which subset of users are searched, however the + /// homeserverMUST at a minimum consider the users the requesting user + /// shares aroom with and those who reside in public rooms (known to the + /// homeserver).The search MUST consider local users to the homeserver, and + /// SHOULDquery remote users as part of the search.The search is performed + /// case-insensitively on user IDs and displaynames preferably using a + /// collation determined based upon the ``Accept-Language`` header provided + /// in the request, if present. + struct User { - public: - // Inner data structures - - /// Performs a search for users on the homeserver. The homeserver may - /// determine which subset of users are searched, however the homeserver - /// MUST at a minimum consider the users the requesting user shares a - /// room with and those who reside in public rooms (known to the - /// homeserver). The search MUST consider local users to the homeserver, - /// and SHOULD query remote users as part of the search. - /// - /// The search is performed case-insensitively on user IDs and display - /// names preferably using a collation determined based upon the - /// ``Accept-Language`` header provided in the request, if present. - struct User { - /// The user's matrix user ID. - QString userId; - /// The display name of the user, if one exists. - QString displayName; - /// The avatar url, as an MXC, if one exists. - QString avatarUrl; - }; - - // Construction/destruction - - /*! Searches the user directory. - * \param searchTerm - * The term to search for - * \param limit - * The maximum number of results to return. Defaults to 10. - */ - explicit SearchUserDirectoryJob(const QString& searchTerm, - Omittable<int> limit = none); - ~SearchUserDirectoryJob() override; - - // Result properties - - /// Ordered by rank and then whether or not profile info is available. - const QVector<User>& results() const; - /// Indicates if the result list has been truncated by the limit. - bool limited() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; + /// The user's matrix user ID. + QString userId; + /// The display name of the user, if one exists. + QString displayName; + /// The avatar url, as an MXC, if one exists. + QString avatarUrl; }; + + // Construction/destruction + + /*! Searches the user directory. + * \param searchTerm + * The term to search for + * \param limit + * The maximum number of results to return. Defaults to 10. + */ + explicit SearchUserDirectoryJob(const QString& searchTerm, + Omittable<int> limit = none); + + ~SearchUserDirectoryJob() override; + + // Result properties + + /// Ordered by rank and then whether or not profile info is available. + const QVector<User>& results() const; + /// Indicates if the result list has been truncated by the limit. + bool limited() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + } // namespace QMatrixClient diff --git a/lib/csapi/versions.cpp b/lib/csapi/versions.cpp index 13e3be15..1d66b94f 100644 --- a/lib/csapi/versions.cpp +++ b/lib/csapi/versions.cpp @@ -14,7 +14,7 @@ static const auto basePath = QStringLiteral("/_matrix/client"); class GetVersionsJob::Private { - public: +public: QStringList versions; QHash<QString, bool> unstableFeatures; }; @@ -27,10 +27,9 @@ QUrl GetVersionsJob::makeRequestUrl(QUrl baseUrl) static const auto GetVersionsJobName = QStringLiteral("GetVersionsJob"); GetVersionsJob::GetVersionsJob() - : BaseJob(HttpVerb::Get, GetVersionsJobName, basePath % "/versions", false), - d(new Private) -{ -} + : BaseJob(HttpVerb::Get, GetVersionsJobName, basePath % "/versions", false) + , d(new Private) +{} GetVersionsJob::~GetVersionsJob() = default; @@ -45,9 +44,10 @@ BaseJob::Status GetVersionsJob::parseJson(const QJsonDocument& data) { auto json = data.object(); if (!json.contains("versions"_ls)) - return { JsonParseError, + return { IncorrectResponse, "The key 'versions' not found in the response" }; fromJson(json.value("versions"_ls), d->versions); fromJson(json.value("unstable_features"_ls), d->unstableFeatures); + return Success; } diff --git a/lib/csapi/versions.h b/lib/csapi/versions.h index d017708a..513e7f27 100644 --- a/lib/csapi/versions.h +++ b/lib/csapi/versions.h @@ -4,65 +4,70 @@ #pragma once +#include "converters.h" + #include "jobs/basejob.h" -#include "converters.h" #include <QtCore/QHash> -namespace QMatrixClient { - // Operations +namespace QMatrixClient +{ + +// Operations + +/// Gets the versions of the specification supported by the server. +/*! + * Gets the versions of the specification supported by the server. + * + * Values will take the form ``rX.Y.Z``. + * + * Only the latest ``Z`` value will be reported for each supported ``X.Y`` + * value. i.e. if the server implements ``r0.0.0``, ``r0.0.1``, and ``r1.2.0``, + * it will report ``r0.0.1`` and ``r1.2.0``. + * + * The server may additionally advertise experimental features it supports + * through ``unstable_features``. These features should be namespaced and + * may optionally include version information within their name if desired. + * Features listed here are not for optionally toggling parts of the Matrix + * specification and should only be used to advertise support for a feature + * which has not yet landed in the spec. For example, a feature currently + * undergoing the proposal process may appear here and eventually be taken + * off this list once the feature lands in the spec and the server deems it + * reasonable to do so. Servers may wish to keep advertising features here + * after they've been released into the spec to give clients a chance to + * upgrade appropriately. Additionally, clients should avoid using unstable + * features in their stable releases. + */ +class GetVersionsJob : public BaseJob +{ +public: + explicit GetVersionsJob(); - /// Gets the versions of the specification supported by the server. - /// - /// Gets the versions of the specification supported by the server. - /// - /// Values will take the form ``rX.Y.Z``. - /// - /// Only the latest ``Z`` value will be reported for each supported ``X.Y`` - /// value. i.e. if the server implements ``r0.0.0``, ``r0.0.1``, and - /// ``r1.2.0``, it will report ``r0.0.1`` and ``r1.2.0``. - /// - /// The server may additionally advertise experimental features it supports - /// through ``unstable_features``. These features should be namespaced and - /// may optionally include version information within their name if desired. - /// Features listed here are not for optionally toggling parts of the Matrix - /// specification and should only be used to advertise support for a feature - /// which has not yet landed in the spec. For example, a feature currently - /// undergoing the proposal process may appear here and eventually be taken - /// off this list once the feature lands in the spec and the server deems it - /// reasonable to do so. Servers may wish to keep advertising features here - /// after they've been released into the spec to give clients a chance to - /// upgrade appropriately. Additionally, clients should avoid using unstable - /// features in their stable releases. - class GetVersionsJob : public BaseJob - { - public: - explicit GetVersionsJob(); + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetVersionsJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl); - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetVersionsJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl); + ~GetVersionsJob() override; - ~GetVersionsJob() override; + // Result properties - // Result properties + /// The supported versions. + const QStringList& versions() const; + /// Experimental features the server supports. Features not listed here, + /// or the lack of this property all together, indicate that a feature is + /// not supported. + const QHash<QString, bool>& unstableFeatures() const; - /// The supported versions. - const QStringList& versions() const; - /// Experimental features the server supports. Features not listed here, - /// or the lack of this property all together, indicate that a feature - /// is not supported. - const QHash<QString, bool>& unstableFeatures() const; +protected: + Status parseJson(const QJsonDocument& data) override; - protected: - Status parseJson(const QJsonDocument& data) override; +private: + class Private; + QScopedPointer<Private> d; +}; - private: - class Private; - QScopedPointer<Private> d; - }; } // namespace QMatrixClient diff --git a/lib/csapi/voip.cpp b/lib/csapi/voip.cpp index ee511906..0e83c915 100644 --- a/lib/csapi/voip.cpp +++ b/lib/csapi/voip.cpp @@ -14,7 +14,7 @@ static const auto basePath = QStringLiteral("/_matrix/client/r0"); class GetTurnServerJob::Private { - public: +public: QJsonObject data; }; @@ -27,11 +27,9 @@ QUrl GetTurnServerJob::makeRequestUrl(QUrl baseUrl) static const auto GetTurnServerJobName = QStringLiteral("GetTurnServerJob"); GetTurnServerJob::GetTurnServerJob() - : BaseJob(HttpVerb::Get, GetTurnServerJobName, - basePath % "/voip/turnServer"), - d(new Private) -{ -} + : BaseJob(HttpVerb::Get, GetTurnServerJobName, basePath % "/voip/turnServer") + , d(new Private) +{} GetTurnServerJob::~GetTurnServerJob() = default; diff --git a/lib/csapi/voip.h b/lib/csapi/voip.h index 3b011651..ab34dcad 100644 --- a/lib/csapi/voip.h +++ b/lib/csapi/voip.h @@ -8,38 +8,42 @@ #include <QtCore/QJsonObject> -namespace QMatrixClient { - // Operations - - /// Obtain TURN server credentials. - /// - /// This API provides credentials for the client to use when initiating - /// calls. - class GetTurnServerJob : public BaseJob - { - public: - explicit GetTurnServerJob(); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetTurnServerJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl); - - ~GetTurnServerJob() override; - - // Result properties - - /// The TURN server credentials. - const QJsonObject& data() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; +namespace QMatrixClient +{ + +// Operations + +/// Obtain TURN server credentials. +/*! + * This API provides credentials for the client to use when initiating + * calls. + */ +class GetTurnServerJob : public BaseJob +{ +public: + explicit GetTurnServerJob(); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetTurnServerJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl); + + ~GetTurnServerJob() override; + + // Result properties + + /// The TURN server credentials. + const QJsonObject& data() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + } // namespace QMatrixClient diff --git a/lib/csapi/wellknown.cpp b/lib/csapi/wellknown.cpp index 8543c519..c2bd7822 100644 --- a/lib/csapi/wellknown.cpp +++ b/lib/csapi/wellknown.cpp @@ -14,7 +14,7 @@ static const auto basePath = QStringLiteral("/.well-known"); class GetWellknownJob::Private { - public: +public: DiscoveryInformation data; }; @@ -28,10 +28,9 @@ static const auto GetWellknownJobName = QStringLiteral("GetWellknownJob"); GetWellknownJob::GetWellknownJob() : BaseJob(HttpVerb::Get, GetWellknownJobName, basePath % "/matrix/client", - false), - d(new Private) -{ -} + false) + , d(new Private) +{} GetWellknownJob::~GetWellknownJob() = default; diff --git a/lib/csapi/wellknown.h b/lib/csapi/wellknown.h index 1df524ce..66917806 100644 --- a/lib/csapi/wellknown.h +++ b/lib/csapi/wellknown.h @@ -4,49 +4,54 @@ #pragma once -#include "jobs/basejob.h" - #include "converters.h" + #include "csapi/definitions/wellknown/full.h" -namespace QMatrixClient { - // Operations - - /// Gets Matrix server discovery information about the domain. - /// - /// Gets discovery information about the domain. The file may include - /// additional keys, which MUST follow the Java package naming convention, - /// e.g. ``com.example.myapp.property``. This ensures property names are - /// suitably namespaced for each application and reduces the risk of - /// clashes. - /// - /// Note that this endpoint is not necessarily handled by the homeserver, - /// but by another webserver, to be used for discovering the homeserver URL. - class GetWellknownJob : public BaseJob - { - public: - explicit GetWellknownJob(); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetWellknownJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl); - - ~GetWellknownJob() override; - - // Result properties - - /// Server discovery information. - const DiscoveryInformation& data() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; +#include "jobs/basejob.h" + +namespace QMatrixClient +{ + +// Operations + +/// Gets Matrix server discovery information about the domain. +/*! + * Gets discovery information about the domain. The file may include + * additional keys, which MUST follow the Java package naming convention, + * e.g. ``com.example.myapp.property``. This ensures property names are + * suitably namespaced for each application and reduces the risk of + * clashes. + * + * Note that this endpoint is not necessarily handled by the homeserver, + * but by another webserver, to be used for discovering the homeserver URL. + */ +class GetWellknownJob : public BaseJob +{ +public: + explicit GetWellknownJob(); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetWellknownJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl); + + ~GetWellknownJob() override; + + // Result properties + + /// Server discovery information. + const DiscoveryInformation& data() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + } // namespace QMatrixClient diff --git a/lib/csapi/whoami.cpp b/lib/csapi/whoami.cpp index f0a77aee..2ca9c435 100644 --- a/lib/csapi/whoami.cpp +++ b/lib/csapi/whoami.cpp @@ -14,7 +14,7 @@ static const auto basePath = QStringLiteral("/_matrix/client/r0"); class GetTokenOwnerJob::Private { - public: +public: QString userId; }; @@ -27,11 +27,9 @@ QUrl GetTokenOwnerJob::makeRequestUrl(QUrl baseUrl) static const auto GetTokenOwnerJobName = QStringLiteral("GetTokenOwnerJob"); GetTokenOwnerJob::GetTokenOwnerJob() - : BaseJob(HttpVerb::Get, GetTokenOwnerJobName, - basePath % "/account/whoami"), - d(new Private) -{ -} + : BaseJob(HttpVerb::Get, GetTokenOwnerJobName, basePath % "/account/whoami") + , d(new Private) +{} GetTokenOwnerJob::~GetTokenOwnerJob() = default; @@ -41,8 +39,9 @@ BaseJob::Status GetTokenOwnerJob::parseJson(const QJsonDocument& data) { auto json = data.object(); if (!json.contains("user_id"_ls)) - return { JsonParseError, + return { IncorrectResponse, "The key 'user_id' not found in the response" }; fromJson(json.value("user_id"_ls), d->userId); + return Success; } diff --git a/lib/csapi/whoami.h b/lib/csapi/whoami.h index 8f191351..e62b7dad 100644 --- a/lib/csapi/whoami.h +++ b/lib/csapi/whoami.h @@ -6,44 +6,48 @@ #include "jobs/basejob.h" -namespace QMatrixClient { - // Operations - - /// Gets information about the owner of an access token. - /// - /// Gets information about the owner of a given access token. - /// - /// Note that, as with the rest of the Client-Server API, - /// Application Services may masquerade as users within their - /// namespace by giving a ``user_id`` query parameter. In this - /// situation, the server should verify that the given ``user_id`` - /// is registered by the appservice, and return it in the response - /// body. - class GetTokenOwnerJob : public BaseJob - { - public: - explicit GetTokenOwnerJob(); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetTokenOwnerJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl); - - ~GetTokenOwnerJob() override; - - // Result properties - - /// The user id that owns the access token. - const QString& userId() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; +namespace QMatrixClient +{ + +// Operations + +/// Gets information about the owner of an access token. +/*! + * Gets information about the owner of a given access token. + * + * Note that, as with the rest of the Client-Server API, + * Application Services may masquerade as users within their + * namespace by giving a ``user_id`` query parameter. In this + * situation, the server should verify that the given ``user_id`` + * is registered by the appservice, and return it in the response + * body. + */ +class GetTokenOwnerJob : public BaseJob +{ +public: + explicit GetTokenOwnerJob(); + + /*! Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for + * GetTokenOwnerJob is necessary but the job + * itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl); + + ~GetTokenOwnerJob() override; + + // Result properties + + /// The user id that owns the access token. + const QString& userId() const; + +protected: + Status parseJson(const QJsonDocument& data) override; + +private: + class Private; + QScopedPointer<Private> d; +}; + } // namespace QMatrixClient diff --git a/lib/csapi/{{base}}.cpp.mustache b/lib/csapi/{{base}}.cpp.mustache index f9a63412..8ebac6ef 100644 --- a/lib/csapi/{{base}}.cpp.mustache +++ b/lib/csapi/{{base}}.cpp.mustache @@ -141,7 +141,7 @@ BaseJob::Status {{camelCaseOperationId}}Job::parseJson(const QJsonDocument& data }} auto json = data.object(); {{# properties}}{{#required? }} if (!json.contains("{{baseName}}"_ls)) - return { JsonParseError, + return { IncorrectResponse, "The key '{{baseName}}' not found in the response" }; {{/required? }} fromJson(json.value("{{baseName}}"_ls), d->{{paramName}}); |